xref: /petsc/src/snes/interface/snes.c (revision e4ed7901070ce1ca36eb7d68dd07557542e66e31)
19b94acceSBarry Smith 
2b45d2f2cSJed Brown #include <petsc-private/snesimpl.h>      /*I "petscsnes.h"  I*/
36cab3a1bSJed Brown #include <petscdmshell.h>          /*I "petscdmshell.h" I*/
49b94acceSBarry Smith 
5ace3abfcSBarry Smith PetscBool  SNESRegisterAllCalled = PETSC_FALSE;
68ba1e511SMatthew Knepley PetscFList SNESList              = PETSC_NULL;
78ba1e511SMatthew Knepley 
88ba1e511SMatthew Knepley /* Logging support */
97087cfbeSBarry Smith PetscClassId  SNES_CLASSID;
10f1c6b773SPeter Brune PetscLogEvent  SNES_Solve, SNES_FunctionEval, SNES_JacobianEval, SNES_GSEval;
11a09944afSBarry Smith 
12a09944afSBarry Smith #undef __FUNCT__
13cab2e9ccSBarry Smith #define __FUNCT__ "SNESDMComputeJacobian"
14cab2e9ccSBarry Smith /*
15cab2e9ccSBarry Smith     Translates from a SNES call to a DM call in computing a Jacobian
16caa4e7f2SJed Brown 
17caa4e7f2SJed Brown     This is a legacy calling sequence, should transition to dispatching through the SNESDM.
18cab2e9ccSBarry Smith */
19cab2e9ccSBarry Smith PetscErrorCode SNESDMComputeJacobian(SNES snes,Vec X,Mat *J,Mat *B,MatStructure *flag,void *ptr)
20cab2e9ccSBarry Smith {
21cab2e9ccSBarry Smith   PetscErrorCode ierr;
22cab2e9ccSBarry Smith   DM             dm;
23cab2e9ccSBarry Smith 
24cab2e9ccSBarry Smith   PetscFunctionBegin;
25cab2e9ccSBarry Smith   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
26cab2e9ccSBarry Smith   ierr = DMComputeJacobian(dm,X,*J,*B,flag);CHKERRQ(ierr);
27cab2e9ccSBarry Smith   PetscFunctionReturn(0);
28cab2e9ccSBarry Smith }
29cab2e9ccSBarry Smith 
30cab2e9ccSBarry Smith #undef __FUNCT__
31e113a28aSBarry Smith #define __FUNCT__ "SNESSetErrorIfNotConverged"
32e113a28aSBarry Smith /*@
33e113a28aSBarry Smith    SNESSetErrorIfNotConverged - Causes SNESSolve() to generate an error if the solver has not converged.
34e113a28aSBarry Smith 
353f9fe445SBarry Smith    Logically Collective on SNES
36e113a28aSBarry Smith 
37e113a28aSBarry Smith    Input Parameters:
38e113a28aSBarry Smith +  snes - iterative context obtained from SNESCreate()
39e113a28aSBarry Smith -  flg - PETSC_TRUE indicates you want the error generated
40e113a28aSBarry Smith 
41e113a28aSBarry Smith    Options database keys:
42e113a28aSBarry Smith .  -snes_error_if_not_converged : this takes an optional truth value (0/1/no/yes/true/false)
43e113a28aSBarry Smith 
44e113a28aSBarry Smith    Level: intermediate
45e113a28aSBarry Smith 
46e113a28aSBarry Smith    Notes:
47e113a28aSBarry Smith     Normally PETSc continues if a linear solver fails to converge, you can call SNESGetConvergedReason() after a SNESSolve()
48e113a28aSBarry Smith     to determine if it has converged.
49e113a28aSBarry Smith 
50e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero
51e113a28aSBarry Smith 
52e113a28aSBarry Smith .seealso: SNESGetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged()
53e113a28aSBarry Smith @*/
547087cfbeSBarry Smith PetscErrorCode  SNESSetErrorIfNotConverged(SNES snes,PetscBool  flg)
55e113a28aSBarry Smith {
56e113a28aSBarry Smith   PetscFunctionBegin;
57e113a28aSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
58acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flg,2);
59e113a28aSBarry Smith   snes->errorifnotconverged = flg;
60dd568438SSatish Balay 
61e113a28aSBarry Smith   PetscFunctionReturn(0);
62e113a28aSBarry Smith }
63e113a28aSBarry Smith 
64e113a28aSBarry Smith #undef __FUNCT__
65e113a28aSBarry Smith #define __FUNCT__ "SNESGetErrorIfNotConverged"
66e113a28aSBarry Smith /*@
67e113a28aSBarry Smith    SNESGetErrorIfNotConverged - Will SNESSolve() generate an error if the solver does not converge?
68e113a28aSBarry Smith 
69e113a28aSBarry Smith    Not Collective
70e113a28aSBarry Smith 
71e113a28aSBarry Smith    Input Parameter:
72e113a28aSBarry Smith .  snes - iterative context obtained from SNESCreate()
73e113a28aSBarry Smith 
74e113a28aSBarry Smith    Output Parameter:
75e113a28aSBarry Smith .  flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE
76e113a28aSBarry Smith 
77e113a28aSBarry Smith    Level: intermediate
78e113a28aSBarry Smith 
79e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero
80e113a28aSBarry Smith 
81e113a28aSBarry Smith .seealso:  SNESSetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged()
82e113a28aSBarry Smith @*/
837087cfbeSBarry Smith PetscErrorCode  SNESGetErrorIfNotConverged(SNES snes,PetscBool  *flag)
84e113a28aSBarry Smith {
85e113a28aSBarry Smith   PetscFunctionBegin;
86e113a28aSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
87e113a28aSBarry Smith   PetscValidPointer(flag,2);
88e113a28aSBarry Smith   *flag = snes->errorifnotconverged;
89e113a28aSBarry Smith   PetscFunctionReturn(0);
90e113a28aSBarry Smith }
91e113a28aSBarry Smith 
92e113a28aSBarry Smith #undef __FUNCT__
934936397dSBarry Smith #define __FUNCT__ "SNESSetFunctionDomainError"
94e725d27bSBarry Smith /*@
954936397dSBarry Smith    SNESSetFunctionDomainError - tells SNES that the input vector to your FormFunction is not
964936397dSBarry Smith      in the functions domain. For example, negative pressure.
974936397dSBarry Smith 
983f9fe445SBarry Smith    Logically Collective on SNES
994936397dSBarry Smith 
1004936397dSBarry Smith    Input Parameters:
1016a388c36SPeter Brune .  snes - the SNES context
1024936397dSBarry Smith 
10328529972SSatish Balay    Level: advanced
1044936397dSBarry Smith 
1054936397dSBarry Smith .keywords: SNES, view
1064936397dSBarry Smith 
1074936397dSBarry Smith .seealso: SNESCreate(), SNESSetFunction()
1084936397dSBarry Smith @*/
1097087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionDomainError(SNES snes)
1104936397dSBarry Smith {
1114936397dSBarry Smith   PetscFunctionBegin;
1120700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1134936397dSBarry Smith   snes->domainerror = PETSC_TRUE;
1144936397dSBarry Smith   PetscFunctionReturn(0);
1154936397dSBarry Smith }
1164936397dSBarry Smith 
1176a388c36SPeter Brune 
1186a388c36SPeter Brune #undef __FUNCT__
1196a388c36SPeter Brune #define __FUNCT__ "SNESGetFunctionDomainError"
1206a388c36SPeter Brune /*@
121c77b2880SPeter Brune    SNESGetFunctionDomainError - Gets the status of the domain error after a call to SNESComputeFunction;
1226a388c36SPeter Brune 
1236a388c36SPeter Brune    Logically Collective on SNES
1246a388c36SPeter Brune 
1256a388c36SPeter Brune    Input Parameters:
1266a388c36SPeter Brune .  snes - the SNES context
1276a388c36SPeter Brune 
1286a388c36SPeter Brune    Output Parameters:
1296a388c36SPeter Brune .  domainerror Set to PETSC_TRUE if there's a domain error; PETSC_FALSE otherwise.
1306a388c36SPeter Brune 
1316a388c36SPeter Brune    Level: advanced
1326a388c36SPeter Brune 
1336a388c36SPeter Brune .keywords: SNES, view
1346a388c36SPeter Brune 
1356a388c36SPeter Brune .seealso: SNESSetFunctionDomainError, SNESComputeFunction()
1366a388c36SPeter Brune @*/
1376a388c36SPeter Brune PetscErrorCode  SNESGetFunctionDomainError(SNES snes, PetscBool *domainerror)
1386a388c36SPeter Brune {
1396a388c36SPeter Brune   PetscFunctionBegin;
1406a388c36SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1416a388c36SPeter Brune   PetscValidPointer(domainerror, 2);
1426a388c36SPeter Brune   *domainerror = snes->domainerror;
1436a388c36SPeter Brune   PetscFunctionReturn(0);
1446a388c36SPeter Brune }
1456a388c36SPeter Brune 
1466a388c36SPeter Brune 
1474936397dSBarry Smith #undef __FUNCT__
1484a2ae208SSatish Balay #define __FUNCT__ "SNESView"
1497e2c5f70SBarry Smith /*@C
1509b94acceSBarry Smith    SNESView - Prints the SNES data structure.
1519b94acceSBarry Smith 
1524c49b128SBarry Smith    Collective on SNES
153fee21e36SBarry Smith 
154c7afd0dbSLois Curfman McInnes    Input Parameters:
155c7afd0dbSLois Curfman McInnes +  SNES - the SNES context
156c7afd0dbSLois Curfman McInnes -  viewer - visualization context
157c7afd0dbSLois Curfman McInnes 
1589b94acceSBarry Smith    Options Database Key:
159c8a8ba5cSLois Curfman McInnes .  -snes_view - Calls SNESView() at end of SNESSolve()
1609b94acceSBarry Smith 
1619b94acceSBarry Smith    Notes:
1629b94acceSBarry Smith    The available visualization contexts include
163b0a32e0cSBarry Smith +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
164b0a32e0cSBarry Smith -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
165c8a8ba5cSLois Curfman McInnes          output where only the first processor opens
166c8a8ba5cSLois Curfman McInnes          the file.  All other processors send their
167c8a8ba5cSLois Curfman McInnes          data to the first processor to print.
1689b94acceSBarry Smith 
1693e081fefSLois Curfman McInnes    The user can open an alternative visualization context with
170b0a32e0cSBarry Smith    PetscViewerASCIIOpen() - output to a specified file.
1719b94acceSBarry Smith 
17236851e7fSLois Curfman McInnes    Level: beginner
17336851e7fSLois Curfman McInnes 
1749b94acceSBarry Smith .keywords: SNES, view
1759b94acceSBarry Smith 
176b0a32e0cSBarry Smith .seealso: PetscViewerASCIIOpen()
1779b94acceSBarry Smith @*/
1787087cfbeSBarry Smith PetscErrorCode  SNESView(SNES snes,PetscViewer viewer)
1799b94acceSBarry Smith {
180fa9f3622SBarry Smith   SNESKSPEW           *kctx;
181dfbe8321SBarry Smith   PetscErrorCode      ierr;
18294b7f48cSBarry Smith   KSP                 ksp;
1837f1410a3SPeter Brune   SNESLineSearch      linesearch;
184ace3abfcSBarry Smith   PetscBool           iascii,isstring;
1859b94acceSBarry Smith 
1863a40ed3dSBarry Smith   PetscFunctionBegin;
1870700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1883050cee2SBarry Smith   if (!viewer) {
1897adad957SLisandro Dalcin     ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr);
1903050cee2SBarry Smith   }
1910700a824SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
192c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,viewer,2);
19374679c65SBarry Smith 
1942692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1952692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr);
19632077d6dSBarry Smith   if (iascii) {
197317d6ea6SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer,"SNES Object");CHKERRQ(ierr);
198e7788613SBarry Smith     if (snes->ops->view) {
199b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
200e7788613SBarry Smith       ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr);
201b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2020ef38995SBarry Smith     }
20377431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);CHKERRQ(ierr);
204a83599f4SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  tolerances: relative=%G, absolute=%G, solution=%G\n",
205c60f73f4SPeter Brune                  snes->rtol,snes->abstol,snes->stol);CHKERRQ(ierr);
20677431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr);
20777431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr);
2089b94acceSBarry Smith     if (snes->ksp_ewconv) {
209fa9f3622SBarry Smith       kctx = (SNESKSPEW *)snes->kspconvctx;
2109b94acceSBarry Smith       if (kctx) {
21177431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"  Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr);
212a83599f4SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    rtol_0=%G, rtol_max=%G, threshold=%G\n",kctx->rtol_0,kctx->rtol_max,kctx->threshold);CHKERRQ(ierr);
213a83599f4SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    gamma=%G, alpha=%G, alpha2=%G\n",kctx->gamma,kctx->alpha,kctx->alpha2);CHKERRQ(ierr);
2149b94acceSBarry Smith       }
2159b94acceSBarry Smith     }
216eb1f6c34SBarry Smith     if (snes->lagpreconditioner == -1) {
217eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is never rebuilt\n");CHKERRQ(ierr);
218eb1f6c34SBarry Smith     } else if (snes->lagpreconditioner > 1) {
219eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr);
220eb1f6c34SBarry Smith     }
221eb1f6c34SBarry Smith     if (snes->lagjacobian == -1) {
222eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is never rebuilt\n");CHKERRQ(ierr);
223eb1f6c34SBarry Smith     } else if (snes->lagjacobian > 1) {
22442f4f86dSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian);CHKERRQ(ierr);
225eb1f6c34SBarry Smith     }
2260f5bd95cSBarry Smith   } else if (isstring) {
227317d6ea6SBarry Smith     const char *type;
228454a90a3SBarry Smith     ierr = SNESGetType(snes,&type);CHKERRQ(ierr);
229b0a32e0cSBarry Smith     ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr);
23019bcc07fSBarry Smith   }
23142f4f86dSBarry Smith   if (snes->pc && snes->usespc) {
2324a0c5b0cSMatthew G Knepley     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
2334a0c5b0cSMatthew G Knepley     ierr = SNESView(snes->pc, viewer);CHKERRQ(ierr);
2344a0c5b0cSMatthew G Knepley     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2354a0c5b0cSMatthew G Knepley   }
2362c155ee1SBarry Smith   if (snes->usesksp) {
2372c155ee1SBarry Smith     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
238b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
23994b7f48cSBarry Smith     ierr = KSPView(ksp,viewer);CHKERRQ(ierr);
240b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2412c155ee1SBarry Smith   }
2427f1410a3SPeter Brune   if (snes->linesearch) {
2437f1410a3SPeter Brune     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
2447f1410a3SPeter Brune     ierr = SNESGetSNESLineSearch(snes, &linesearch);CHKERRQ(ierr);
2457f1410a3SPeter Brune     ierr = SNESLineSearchView(linesearch, viewer);CHKERRQ(ierr);
2467f1410a3SPeter Brune     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2477f1410a3SPeter Brune   }
2483a40ed3dSBarry Smith   PetscFunctionReturn(0);
2499b94acceSBarry Smith }
2509b94acceSBarry Smith 
25176b2cf59SMatthew Knepley /*
25276b2cf59SMatthew Knepley   We retain a list of functions that also take SNES command
25376b2cf59SMatthew Knepley   line options. These are called at the end SNESSetFromOptions()
25476b2cf59SMatthew Knepley */
25576b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5
256a7cc72afSBarry Smith static PetscInt numberofsetfromoptions;
2576849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES);
25876b2cf59SMatthew Knepley 
259e74ef692SMatthew Knepley #undef __FUNCT__
260e74ef692SMatthew Knepley #define __FUNCT__ "SNESAddOptionsChecker"
261ac226902SBarry Smith /*@C
26276b2cf59SMatthew Knepley   SNESAddOptionsChecker - Adds an additional function to check for SNES options.
26376b2cf59SMatthew Knepley 
26476b2cf59SMatthew Knepley   Not Collective
26576b2cf59SMatthew Knepley 
26676b2cf59SMatthew Knepley   Input Parameter:
26776b2cf59SMatthew Knepley . snescheck - function that checks for options
26876b2cf59SMatthew Knepley 
26976b2cf59SMatthew Knepley   Level: developer
27076b2cf59SMatthew Knepley 
27176b2cf59SMatthew Knepley .seealso: SNESSetFromOptions()
27276b2cf59SMatthew Knepley @*/
2737087cfbeSBarry Smith PetscErrorCode  SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES))
27476b2cf59SMatthew Knepley {
27576b2cf59SMatthew Knepley   PetscFunctionBegin;
27676b2cf59SMatthew Knepley   if (numberofsetfromoptions >= MAXSETFROMOPTIONS) {
277e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS);
27876b2cf59SMatthew Knepley   }
27976b2cf59SMatthew Knepley   othersetfromoptions[numberofsetfromoptions++] = snescheck;
28076b2cf59SMatthew Knepley   PetscFunctionReturn(0);
28176b2cf59SMatthew Knepley }
28276b2cf59SMatthew Knepley 
2837087cfbeSBarry Smith extern PetscErrorCode  SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*);
284aa3661deSLisandro Dalcin 
285aa3661deSLisandro Dalcin #undef __FUNCT__
286aa3661deSLisandro Dalcin #define __FUNCT__ "SNESSetUpMatrixFree_Private"
287ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool  hasOperator, PetscInt version)
288aa3661deSLisandro Dalcin {
289aa3661deSLisandro Dalcin   Mat            J;
290aa3661deSLisandro Dalcin   KSP            ksp;
291aa3661deSLisandro Dalcin   PC             pc;
292ace3abfcSBarry Smith   PetscBool      match;
293aa3661deSLisandro Dalcin   PetscErrorCode ierr;
294aa3661deSLisandro Dalcin 
295aa3661deSLisandro Dalcin   PetscFunctionBegin;
2960700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
297aa3661deSLisandro Dalcin 
29898613b67SLisandro Dalcin   if(!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) {
29998613b67SLisandro Dalcin     Mat A = snes->jacobian, B = snes->jacobian_pre;
30098613b67SLisandro Dalcin     ierr = MatGetVecs(A ? A : B, PETSC_NULL,&snes->vec_func);CHKERRQ(ierr);
30198613b67SLisandro Dalcin   }
30298613b67SLisandro Dalcin 
303aa3661deSLisandro Dalcin   if (version == 1) {
304aa3661deSLisandro Dalcin     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
30598613b67SLisandro Dalcin     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
3069c6ac3b3SBarry Smith     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
307aa3661deSLisandro Dalcin   } else if (version == 2) {
308e32f2f54SBarry Smith     if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first");
30982a7e548SBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
310aa3661deSLisandro Dalcin     ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr);
311aa3661deSLisandro Dalcin #else
312e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)");
313aa3661deSLisandro Dalcin #endif
314a8248277SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2");
315aa3661deSLisandro Dalcin 
316aa3661deSLisandro Dalcin   ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr);
317d3462f78SMatthew Knepley   if (hasOperator) {
318aa3661deSLisandro Dalcin     /* This version replaces the user provided Jacobian matrix with a
319aa3661deSLisandro Dalcin        matrix-free version but still employs the user-provided preconditioner matrix. */
320aa3661deSLisandro Dalcin     ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr);
321aa3661deSLisandro Dalcin   } else {
322aa3661deSLisandro Dalcin     /* This version replaces both the user-provided Jacobian and the user-
323aa3661deSLisandro Dalcin        provided preconditioner matrix with the default matrix free version. */
3246cab3a1bSJed Brown     void *functx;
3256cab3a1bSJed Brown     ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
3266cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr);
327aa3661deSLisandro Dalcin     /* Force no preconditioner */
328aa3661deSLisandro Dalcin     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
329aa3661deSLisandro Dalcin     ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr);
330aa3661deSLisandro Dalcin     ierr = PetscTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr);
331aa3661deSLisandro Dalcin     if (!match) {
332aa3661deSLisandro Dalcin       ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr);
333aa3661deSLisandro Dalcin       ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr);
334aa3661deSLisandro Dalcin     }
335aa3661deSLisandro Dalcin   }
3366bf464f9SBarry Smith   ierr = MatDestroy(&J);CHKERRQ(ierr);
337aa3661deSLisandro Dalcin   PetscFunctionReturn(0);
338aa3661deSLisandro Dalcin }
339aa3661deSLisandro Dalcin 
3404a2ae208SSatish Balay #undef __FUNCT__
341dfe15315SJed Brown #define __FUNCT__ "DMRestrictHook_SNESVecSol"
342dfe15315SJed Brown static PetscErrorCode DMRestrictHook_SNESVecSol(DM dmfine,Mat Restrict,Vec Rscale,Mat Inject,DM dmcoarse,void *ctx)
343dfe15315SJed Brown {
344dfe15315SJed Brown   SNES snes = (SNES)ctx;
345dfe15315SJed Brown   PetscErrorCode ierr;
346dfe15315SJed Brown   Vec Xfine,Xfine_named = PETSC_NULL,Xcoarse;
347dfe15315SJed Brown 
348dfe15315SJed Brown   PetscFunctionBegin;
349dfe15315SJed Brown   if (dmfine == snes->dm) Xfine = snes->vec_sol;
350dfe15315SJed Brown   else {
351dfe15315SJed Brown     ierr = DMGetNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);
352dfe15315SJed Brown     Xfine = Xfine_named;
353dfe15315SJed Brown   }
354dfe15315SJed Brown   ierr = DMGetNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr);
355dfe15315SJed Brown   ierr = MatRestrict(Restrict,Xfine,Xcoarse);CHKERRQ(ierr);
356dfe15315SJed Brown   ierr = VecPointwiseMult(Xcoarse,Xcoarse,Rscale);CHKERRQ(ierr);
357dfe15315SJed Brown   ierr = DMRestoreNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr);
358dfe15315SJed Brown   if (Xfine_named) {ierr = DMRestoreNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);}
359dfe15315SJed Brown   PetscFunctionReturn(0);
360dfe15315SJed Brown }
361dfe15315SJed Brown 
362dfe15315SJed Brown #undef __FUNCT__
363caa4e7f2SJed Brown #define __FUNCT__ "KSPComputeOperators_SNES"
364caa4e7f2SJed Brown static PetscErrorCode KSPComputeOperators_SNES(KSP ksp,Mat A,Mat B,MatStructure *mstruct,void *ctx)
365caa4e7f2SJed Brown {
366caa4e7f2SJed Brown   SNES snes = (SNES)ctx;
367caa4e7f2SJed Brown   PetscErrorCode ierr;
368caa4e7f2SJed Brown   Mat Asave = A,Bsave = B;
369dfe15315SJed Brown   Vec X,Xnamed = PETSC_NULL;
370dfe15315SJed Brown   DM dmsave;
371caa4e7f2SJed Brown 
372caa4e7f2SJed Brown   PetscFunctionBegin;
373dfe15315SJed Brown   dmsave = snes->dm;
374dfe15315SJed Brown   ierr = KSPGetDM(ksp,&snes->dm);CHKERRQ(ierr);
375dfe15315SJed Brown   if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */
376dfe15315SJed Brown   else {                                     /* We are on a coarser level, this vec was initialized using a DM restrict hook */
377dfe15315SJed Brown     ierr = DMGetNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr);
378dfe15315SJed Brown     X = Xnamed;
379dfe15315SJed Brown   }
380dfe15315SJed Brown   ierr = SNESComputeJacobian(snes,X,&A,&B,mstruct);CHKERRQ(ierr);
381caa4e7f2SJed Brown   if (A != Asave || B != Bsave) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_SUP,"No support for changing matrices at this time");
382dfe15315SJed Brown   if (Xnamed) {
383dfe15315SJed Brown     ierr = DMRestoreNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr);
384dfe15315SJed Brown   }
385dfe15315SJed Brown   snes->dm = dmsave;
386caa4e7f2SJed Brown   PetscFunctionReturn(0);
387caa4e7f2SJed Brown }
388caa4e7f2SJed Brown 
389caa4e7f2SJed Brown #undef __FUNCT__
3906cab3a1bSJed Brown #define __FUNCT__ "SNESSetUpMatrices"
3916cab3a1bSJed Brown /*@
3926cab3a1bSJed Brown    SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX()
3936cab3a1bSJed Brown 
3946cab3a1bSJed Brown    Collective
3956cab3a1bSJed Brown 
3966cab3a1bSJed Brown    Input Arguments:
3976cab3a1bSJed Brown .  snes - snes to configure
3986cab3a1bSJed Brown 
3996cab3a1bSJed Brown    Level: developer
4006cab3a1bSJed Brown 
4016cab3a1bSJed Brown .seealso: SNESSetUp()
4026cab3a1bSJed Brown @*/
4036cab3a1bSJed Brown PetscErrorCode SNESSetUpMatrices(SNES snes)
4046cab3a1bSJed Brown {
4056cab3a1bSJed Brown   PetscErrorCode ierr;
4066cab3a1bSJed Brown   DM             dm;
4076cab3a1bSJed Brown   SNESDM         sdm;
4086cab3a1bSJed Brown 
4096cab3a1bSJed Brown   PetscFunctionBegin;
4106cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
4116cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
412caa4e7f2SJed Brown   if (!sdm->computejacobian) {
4136cab3a1bSJed Brown     Mat J,B;
4146cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
4156cab3a1bSJed Brown     if (snes->mf_operator) {
4166cab3a1bSJed Brown       ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
4176cab3a1bSJed Brown       ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
4186cab3a1bSJed Brown       ierr = MatSetFromOptions(J);CHKERRQ(ierr);
4196cab3a1bSJed Brown     } else {
4206cab3a1bSJed Brown       J = B;
4216cab3a1bSJed Brown       ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
4226cab3a1bSJed Brown     }
4236cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,PETSC_NULL);CHKERRQ(ierr);
4246cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
4256cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
4266cab3a1bSJed Brown   } else if (!snes->jacobian && sdm->computejacobian == MatMFFDComputeJacobian) {
4276cab3a1bSJed Brown     Mat J;
4286cab3a1bSJed Brown     void *functx;
4296cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
4306cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
4316cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
4326cab3a1bSJed Brown     ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
4336cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr);
4346cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
435caa4e7f2SJed Brown   } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) {
4366cab3a1bSJed Brown     Mat J,B;
4376cab3a1bSJed Brown     void *functx;
4386cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
4396cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
4406cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
4416cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
4426cab3a1bSJed Brown     ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
4436cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,functx);CHKERRQ(ierr);
4446cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
4456cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
446caa4e7f2SJed Brown   } else if (!snes->jacobian_pre) {
4476cab3a1bSJed Brown     Mat J,B;
4486cab3a1bSJed Brown     J = snes->jacobian;
4496cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
4506cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J?J:B,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
4516cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
4526cab3a1bSJed Brown   }
453caa4e7f2SJed Brown   {
454caa4e7f2SJed Brown     PetscBool flg = PETSC_FALSE;
455caa4e7f2SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_kspcompute",&flg,PETSC_NULL);CHKERRQ(ierr);
456caa4e7f2SJed Brown     if (flg) {                  /* Plan to transition to this model */
457caa4e7f2SJed Brown       KSP ksp;
458caa4e7f2SJed Brown       ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
459caa4e7f2SJed Brown       ierr = KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes);CHKERRQ(ierr);
460dfe15315SJed Brown       ierr = DMCoarsenHookAdd(snes->dm,PETSC_NULL,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr);
461caa4e7f2SJed Brown     }
462caa4e7f2SJed Brown   }
4636cab3a1bSJed Brown   PetscFunctionReturn(0);
4646cab3a1bSJed Brown }
4656cab3a1bSJed Brown 
4666cab3a1bSJed Brown #undef __FUNCT__
4674a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions"
4689b94acceSBarry Smith /*@
46994b7f48cSBarry Smith    SNESSetFromOptions - Sets various SNES and KSP parameters from user options.
4709b94acceSBarry Smith 
471c7afd0dbSLois Curfman McInnes    Collective on SNES
472c7afd0dbSLois Curfman McInnes 
4739b94acceSBarry Smith    Input Parameter:
4749b94acceSBarry Smith .  snes - the SNES context
4759b94acceSBarry Smith 
47636851e7fSLois Curfman McInnes    Options Database Keys:
477ea630c6eSPeter Brune +  -snes_type <type> - ls, tr, ngmres, ncg, richardson, qn, vi, fas
47882738288SBarry Smith .  -snes_stol - convergence tolerance in terms of the norm
47982738288SBarry Smith                 of the change in the solution between steps
48070441072SBarry Smith .  -snes_atol <abstol> - absolute tolerance of residual norm
481b39c3a46SLois Curfman McInnes .  -snes_rtol <rtol> - relative decrease in tolerance norm from initial
482b39c3a46SLois Curfman McInnes .  -snes_max_it <max_it> - maximum number of iterations
483b39c3a46SLois Curfman McInnes .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
4844839bfe8SBarry Smith .  -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none
485ddf469c8SBarry Smith .  -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops
486a8054027SBarry Smith .  -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild)
487e35cf81dSBarry Smith .  -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild)
488b39c3a46SLois Curfman McInnes .  -snes_trtol <trtol> - trust region tolerance
4892492ecdbSBarry Smith .  -snes_no_convergence_test - skip convergence test in nonlinear
49082738288SBarry Smith                                solver; hence iterations will continue until max_it
4911fbbfb26SLois Curfman McInnes                                or some other criterion is reached. Saves expense
49282738288SBarry Smith                                of convergence test
493e8105e01SRichard Katz .  -snes_monitor <optional filename> - prints residual norm at each iteration. if no
494e8105e01SRichard Katz                                        filename given prints to stdout
495a6570f20SBarry Smith .  -snes_monitor_solution - plots solution at each iteration
496a6570f20SBarry Smith .  -snes_monitor_residual - plots residual (not its norm) at each iteration
497a6570f20SBarry Smith .  -snes_monitor_solution_update - plots update to solution at each iteration
498a6570f20SBarry Smith .  -snes_monitor_draw - plots residual norm at each iteration
499e24b481bSBarry Smith .  -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
5005968eb51SBarry Smith .  -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
501fee2055bSBarry Smith -  -snes_converged_reason - print the reason for convergence/divergence after each solve
50282738288SBarry Smith 
50382738288SBarry Smith     Options Database for Eisenstat-Walker method:
504fa9f3622SBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
5054b27c08aSLois Curfman McInnes .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
50636851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
50736851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
50836851e7fSLois Curfman McInnes .  -snes_ksp_ew_gamma <gamma> - Sets gamma
50936851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha <alpha> - Sets alpha
51036851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
51136851e7fSLois Curfman McInnes -  -snes_ksp_ew_threshold <threshold> - Sets threshold
51282738288SBarry Smith 
51311ca99fdSLois Curfman McInnes    Notes:
51411ca99fdSLois Curfman McInnes    To see all options, run your program with the -help option or consult
5150598bfebSBarry Smith    the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>.
51683e2fdc7SBarry Smith 
51736851e7fSLois Curfman McInnes    Level: beginner
51836851e7fSLois Curfman McInnes 
5199b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database
5209b94acceSBarry Smith 
52169ed319cSSatish Balay .seealso: SNESSetOptionsPrefix()
5229b94acceSBarry Smith @*/
5237087cfbeSBarry Smith PetscErrorCode  SNESSetFromOptions(SNES snes)
5249b94acceSBarry Smith {
525872b6db9SPeter Brune   PetscBool               flg,mf,mf_operator,pcset;
526efd51863SBarry Smith   PetscInt                i,indx,lag,mf_version,grids;
527aa3661deSLisandro Dalcin   MatStructure            matflag;
52885385478SLisandro Dalcin   const char              *deft = SNESLS;
52985385478SLisandro Dalcin   const char              *convtests[] = {"default","skip"};
53085385478SLisandro Dalcin   SNESKSPEW               *kctx = NULL;
531e8105e01SRichard Katz   char                    type[256], monfilename[PETSC_MAX_PATH_LEN];
53251e86f29SPeter Brune   const char              *optionsprefix;
533649052a6SBarry Smith   PetscViewer             monviewer;
53485385478SLisandro Dalcin   PetscErrorCode          ierr;
5359b94acceSBarry Smith 
5363a40ed3dSBarry Smith   PetscFunctionBegin;
5370700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
538ca161407SBarry Smith 
539186905e3SBarry Smith   if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
5403194b578SJed Brown   ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr);
5417adad957SLisandro Dalcin     if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; }
542b0a32e0cSBarry Smith     ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr);
543d64ed03dSBarry Smith     if (flg) {
544186905e3SBarry Smith       ierr = SNESSetType(snes,type);CHKERRQ(ierr);
5457adad957SLisandro Dalcin     } else if (!((PetscObject)snes)->type_name) {
546186905e3SBarry Smith       ierr = SNESSetType(snes,deft);CHKERRQ(ierr);
547d64ed03dSBarry Smith     }
54890d69ab7SBarry Smith     /* not used here, but called so will go into help messaage */
549909c8a9fSBarry Smith     ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr);
55093c39befSBarry Smith 
551c60f73f4SPeter Brune     ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,0);CHKERRQ(ierr);
55257034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr);
553186905e3SBarry Smith 
55457034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr);
555b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr);
556b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr);
55750ffb88aSMatthew Knepley     ierr = PetscOptionsInt("-snes_max_fail","Maximum failures","SNESSetTolerances",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr);
558ddf469c8SBarry Smith     ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr);
559acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);CHKERRQ(ierr);
56085385478SLisandro Dalcin 
561a8054027SBarry Smith     ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr);
562a8054027SBarry Smith     if (flg) {
563a8054027SBarry Smith       ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr);
564a8054027SBarry Smith     }
565e35cf81dSBarry Smith     ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr);
566e35cf81dSBarry Smith     if (flg) {
567e35cf81dSBarry Smith       ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr);
568e35cf81dSBarry Smith     }
569efd51863SBarry Smith     ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr);
570efd51863SBarry Smith     if (flg) {
571efd51863SBarry Smith       ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr);
572efd51863SBarry Smith     }
573a8054027SBarry Smith 
57485385478SLisandro Dalcin     ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr);
57585385478SLisandro Dalcin     if (flg) {
57685385478SLisandro Dalcin       switch (indx) {
5777f7931b9SBarry Smith       case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break;
5787f7931b9SBarry Smith       case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);    break;
57985385478SLisandro Dalcin       }
58085385478SLisandro Dalcin     }
58185385478SLisandro Dalcin 
582acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr);
583186905e3SBarry Smith 
58485385478SLisandro Dalcin     kctx = (SNESKSPEW *)snes->kspconvctx;
58585385478SLisandro Dalcin 
586acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr);
587186905e3SBarry Smith 
588fa9f3622SBarry Smith     ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr);
589fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr);
590fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr);
591fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr);
592fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr);
593fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr);
594fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr);
595186905e3SBarry Smith 
59690d69ab7SBarry Smith     flg  = PETSC_FALSE;
597acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
598a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);}
599eabae89aSBarry Smith 
600a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
601e8105e01SRichard Katz     if (flg) {
602649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
603649052a6SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
604e8105e01SRichard Katz     }
605eabae89aSBarry Smith 
606b271bb04SBarry Smith     ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
607b271bb04SBarry Smith     if (flg) {
608b271bb04SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr);
609b271bb04SBarry Smith     }
610b271bb04SBarry Smith 
611a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
612eabae89aSBarry Smith     if (flg) {
613649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
614f1bef1bcSMatthew Knepley       ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr);
615e8105e01SRichard Katz     }
616eabae89aSBarry Smith 
617a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
618eabae89aSBarry Smith     if (flg) {
619649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
620649052a6SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
621eabae89aSBarry Smith     }
622eabae89aSBarry Smith 
6235180491cSLisandro Dalcin     ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
6245180491cSLisandro Dalcin     if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);}
6255180491cSLisandro Dalcin 
62690d69ab7SBarry Smith     flg  = PETSC_FALSE;
627acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
628a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);}
62990d69ab7SBarry Smith     flg  = PETSC_FALSE;
630acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
631a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);}
63290d69ab7SBarry Smith     flg  = PETSC_FALSE;
633acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
634a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);}
63590d69ab7SBarry Smith     flg  = PETSC_FALSE;
636acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
637a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
63890d69ab7SBarry Smith     flg  = PETSC_FALSE;
639acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
640b271bb04SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
641e24b481bSBarry Smith 
64290d69ab7SBarry Smith     flg  = PETSC_FALSE;
643acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
6444b27c08aSLois Curfman McInnes     if (flg) {
6456cab3a1bSJed Brown       void *functx;
6466cab3a1bSJed Brown       ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
6476cab3a1bSJed Brown       ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,functx);CHKERRQ(ierr);
648ae15b995SBarry Smith       ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr);
6499b94acceSBarry Smith     }
650639f9d9dSBarry Smith 
651aa3661deSLisandro Dalcin     mf = mf_operator = PETSC_FALSE;
652aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
653acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr);
654a8248277SBarry Smith     if (flg && mf_operator) {
655a8248277SBarry Smith       snes->mf_operator = PETSC_TRUE;
656a8248277SBarry Smith       mf = PETSC_TRUE;
657a8248277SBarry Smith     }
658aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
659acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);CHKERRQ(ierr);
660aa3661deSLisandro Dalcin     if (!flg && mf_operator) mf = PETSC_TRUE;
661aa3661deSLisandro Dalcin     mf_version = 1;
662aa3661deSLisandro Dalcin     ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);CHKERRQ(ierr);
663aa3661deSLisandro Dalcin 
664d28543b3SPeter Brune 
66589b92e6fSPeter Brune     /* GS Options */
66689b92e6fSPeter Brune     ierr = PetscOptionsInt("-snes_gs_sweeps","Number of sweeps of GS to apply","SNESComputeGS",snes->gssweeps,&snes->gssweeps,PETSC_NULL);CHKERRQ(ierr);
66789b92e6fSPeter Brune 
66876b2cf59SMatthew Knepley     for(i = 0; i < numberofsetfromoptions; i++) {
66976b2cf59SMatthew Knepley       ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr);
67076b2cf59SMatthew Knepley     }
67176b2cf59SMatthew Knepley 
672e7788613SBarry Smith     if (snes->ops->setfromoptions) {
673e7788613SBarry Smith       ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr);
674639f9d9dSBarry Smith     }
6755d973c19SBarry Smith 
6765d973c19SBarry Smith     /* process any options handlers added with PetscObjectAddOptionsHandler() */
6775d973c19SBarry Smith     ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr);
678b0a32e0cSBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
6794bbc92c1SBarry Smith 
680aa3661deSLisandro Dalcin   if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); }
6811cee3971SBarry Smith 
6821cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
683aa3661deSLisandro Dalcin   ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag);
684aa3661deSLisandro Dalcin   ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr);
68585385478SLisandro Dalcin   ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr);
68693993e2dSLois Curfman McInnes 
6879e764e56SPeter Brune   if (!snes->linesearch) {
688f1c6b773SPeter Brune     ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);CHKERRQ(ierr);
6899e764e56SPeter Brune   }
690f1c6b773SPeter Brune   ierr = SNESLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr);
6919e764e56SPeter Brune 
69251e86f29SPeter Brune   /* if someone has set the SNES PC type, create it. */
69351e86f29SPeter Brune   ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
69451e86f29SPeter Brune   ierr = PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr);
69551e86f29SPeter Brune   if (pcset && (!snes->pc)) {
69651e86f29SPeter Brune     ierr = SNESGetPC(snes, &snes->pc);CHKERRQ(ierr);
69751e86f29SPeter Brune   }
6984a0c5b0cSMatthew G Knepley   if (snes->pc) {
699fde0ff24SPeter Brune     ierr = SNESSetOptionsPrefix(snes->pc, optionsprefix);CHKERRQ(ierr);
700fde0ff24SPeter Brune     ierr = SNESAppendOptionsPrefix(snes->pc, "npc_");CHKERRQ(ierr);
7014a0c5b0cSMatthew G Knepley     ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr);
70288976e71SPeter Brune     /* default to 1 iteration */
70388976e71SPeter Brune     ierr = SNESSetTolerances(snes->pc, snes->pc->abstol, snes->pc->rtol, snes->pc->stol, 1, snes->pc->max_funcs);CHKERRQ(ierr);
7044a0c5b0cSMatthew G Knepley     ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr);
7054a0c5b0cSMatthew G Knepley   }
7063a40ed3dSBarry Smith   PetscFunctionReturn(0);
7079b94acceSBarry Smith }
7089b94acceSBarry Smith 
709d25893d9SBarry Smith #undef __FUNCT__
710d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext"
711d25893d9SBarry Smith /*@
712d25893d9SBarry Smith    SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for
713d25893d9SBarry Smith    the nonlinear solvers.
714d25893d9SBarry Smith 
715d25893d9SBarry Smith    Logically Collective on SNES
716d25893d9SBarry Smith 
717d25893d9SBarry Smith    Input Parameters:
718d25893d9SBarry Smith +  snes - the SNES context
719d25893d9SBarry Smith .  compute - function to compute the context
720d25893d9SBarry Smith -  destroy - function to destroy the context
721d25893d9SBarry Smith 
722d25893d9SBarry Smith    Level: intermediate
723d25893d9SBarry Smith 
724d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context
725d25893d9SBarry Smith 
726d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext()
727d25893d9SBarry Smith @*/
728d25893d9SBarry Smith PetscErrorCode  SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**))
729d25893d9SBarry Smith {
730d25893d9SBarry Smith   PetscFunctionBegin;
731d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
732d25893d9SBarry Smith   snes->ops->usercompute = compute;
733d25893d9SBarry Smith   snes->ops->userdestroy = destroy;
734d25893d9SBarry Smith   PetscFunctionReturn(0);
735d25893d9SBarry Smith }
736a847f771SSatish Balay 
7374a2ae208SSatish Balay #undef __FUNCT__
7384a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext"
739b07ff414SBarry Smith /*@
7409b94acceSBarry Smith    SNESSetApplicationContext - Sets the optional user-defined context for
7419b94acceSBarry Smith    the nonlinear solvers.
7429b94acceSBarry Smith 
7433f9fe445SBarry Smith    Logically Collective on SNES
744fee21e36SBarry Smith 
745c7afd0dbSLois Curfman McInnes    Input Parameters:
746c7afd0dbSLois Curfman McInnes +  snes - the SNES context
747c7afd0dbSLois Curfman McInnes -  usrP - optional user context
748c7afd0dbSLois Curfman McInnes 
74936851e7fSLois Curfman McInnes    Level: intermediate
75036851e7fSLois Curfman McInnes 
7519b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context
7529b94acceSBarry Smith 
753d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetApplicationContext()
7549b94acceSBarry Smith @*/
7557087cfbeSBarry Smith PetscErrorCode  SNESSetApplicationContext(SNES snes,void *usrP)
7569b94acceSBarry Smith {
7571b2093e4SBarry Smith   PetscErrorCode ierr;
758b07ff414SBarry Smith   KSP            ksp;
7591b2093e4SBarry Smith 
7603a40ed3dSBarry Smith   PetscFunctionBegin;
7610700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
762b07ff414SBarry Smith   ierr       = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
763b07ff414SBarry Smith   ierr       = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr);
7649b94acceSBarry Smith   snes->user = usrP;
7653a40ed3dSBarry Smith   PetscFunctionReturn(0);
7669b94acceSBarry Smith }
76774679c65SBarry Smith 
7684a2ae208SSatish Balay #undef __FUNCT__
7694a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext"
770b07ff414SBarry Smith /*@
7719b94acceSBarry Smith    SNESGetApplicationContext - Gets the user-defined context for the
7729b94acceSBarry Smith    nonlinear solvers.
7739b94acceSBarry Smith 
774c7afd0dbSLois Curfman McInnes    Not Collective
775c7afd0dbSLois Curfman McInnes 
7769b94acceSBarry Smith    Input Parameter:
7779b94acceSBarry Smith .  snes - SNES context
7789b94acceSBarry Smith 
7799b94acceSBarry Smith    Output Parameter:
7809b94acceSBarry Smith .  usrP - user context
7819b94acceSBarry Smith 
78236851e7fSLois Curfman McInnes    Level: intermediate
78336851e7fSLois Curfman McInnes 
7849b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context
7859b94acceSBarry Smith 
7869b94acceSBarry Smith .seealso: SNESSetApplicationContext()
7879b94acceSBarry Smith @*/
788e71120c6SJed Brown PetscErrorCode  SNESGetApplicationContext(SNES snes,void *usrP)
7899b94acceSBarry Smith {
7903a40ed3dSBarry Smith   PetscFunctionBegin;
7910700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
792e71120c6SJed Brown   *(void**)usrP = snes->user;
7933a40ed3dSBarry Smith   PetscFunctionReturn(0);
7949b94acceSBarry Smith }
79574679c65SBarry Smith 
7964a2ae208SSatish Balay #undef __FUNCT__
7974a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber"
7989b94acceSBarry Smith /*@
799c8228a4eSBarry Smith    SNESGetIterationNumber - Gets the number of nonlinear iterations completed
800c8228a4eSBarry Smith    at this time.
8019b94acceSBarry Smith 
802c7afd0dbSLois Curfman McInnes    Not Collective
803c7afd0dbSLois Curfman McInnes 
8049b94acceSBarry Smith    Input Parameter:
8059b94acceSBarry Smith .  snes - SNES context
8069b94acceSBarry Smith 
8079b94acceSBarry Smith    Output Parameter:
8089b94acceSBarry Smith .  iter - iteration number
8099b94acceSBarry Smith 
810c8228a4eSBarry Smith    Notes:
811c8228a4eSBarry Smith    For example, during the computation of iteration 2 this would return 1.
812c8228a4eSBarry Smith 
813c8228a4eSBarry Smith    This is useful for using lagged Jacobians (where one does not recompute the
81408405cd6SLois Curfman McInnes    Jacobian at each SNES iteration). For example, the code
81508405cd6SLois Curfman McInnes .vb
81608405cd6SLois Curfman McInnes       ierr = SNESGetIterationNumber(snes,&it);
81708405cd6SLois Curfman McInnes       if (!(it % 2)) {
81808405cd6SLois Curfman McInnes         [compute Jacobian here]
81908405cd6SLois Curfman McInnes       }
82008405cd6SLois Curfman McInnes .ve
821c8228a4eSBarry Smith    can be used in your ComputeJacobian() function to cause the Jacobian to be
82208405cd6SLois Curfman McInnes    recomputed every second SNES iteration.
823c8228a4eSBarry Smith 
82436851e7fSLois Curfman McInnes    Level: intermediate
82536851e7fSLois Curfman McInnes 
8262b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number,
8272b668275SBarry Smith 
828b850b91aSLisandro Dalcin .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
8299b94acceSBarry Smith @*/
8307087cfbeSBarry Smith PetscErrorCode  SNESGetIterationNumber(SNES snes,PetscInt* iter)
8319b94acceSBarry Smith {
8323a40ed3dSBarry Smith   PetscFunctionBegin;
8330700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
8344482741eSBarry Smith   PetscValidIntPointer(iter,2);
8359b94acceSBarry Smith   *iter = snes->iter;
8363a40ed3dSBarry Smith   PetscFunctionReturn(0);
8379b94acceSBarry Smith }
83874679c65SBarry Smith 
8394a2ae208SSatish Balay #undef __FUNCT__
840360c497dSPeter Brune #define __FUNCT__ "SNESSetIterationNumber"
841360c497dSPeter Brune /*@
842360c497dSPeter Brune    SNESSetIterationNumber - Sets the current iteration number.
843360c497dSPeter Brune 
844360c497dSPeter Brune    Not Collective
845360c497dSPeter Brune 
846360c497dSPeter Brune    Input Parameter:
847360c497dSPeter Brune .  snes - SNES context
848360c497dSPeter Brune .  iter - iteration number
849360c497dSPeter Brune 
850360c497dSPeter Brune    Level: developer
851360c497dSPeter Brune 
852360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number,
853360c497dSPeter Brune 
854360c497dSPeter Brune .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
855360c497dSPeter Brune @*/
856360c497dSPeter Brune PetscErrorCode  SNESSetIterationNumber(SNES snes,PetscInt iter)
857360c497dSPeter Brune {
858360c497dSPeter Brune   PetscErrorCode ierr;
859360c497dSPeter Brune 
860360c497dSPeter Brune   PetscFunctionBegin;
861360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
862360c497dSPeter Brune   ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr);
863360c497dSPeter Brune   snes->iter = iter;
864360c497dSPeter Brune   ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr);
865360c497dSPeter Brune   PetscFunctionReturn(0);
866360c497dSPeter Brune }
867360c497dSPeter Brune 
868360c497dSPeter Brune #undef __FUNCT__
8694a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm"
8709b94acceSBarry Smith /*@
8719b94acceSBarry Smith    SNESGetFunctionNorm - Gets the norm of the current function that was set
8729b94acceSBarry Smith    with SNESSSetFunction().
8739b94acceSBarry Smith 
874c7afd0dbSLois Curfman McInnes    Collective on SNES
875c7afd0dbSLois Curfman McInnes 
8769b94acceSBarry Smith    Input Parameter:
8779b94acceSBarry Smith .  snes - SNES context
8789b94acceSBarry Smith 
8799b94acceSBarry Smith    Output Parameter:
8809b94acceSBarry Smith .  fnorm - 2-norm of function
8819b94acceSBarry Smith 
88236851e7fSLois Curfman McInnes    Level: intermediate
88336851e7fSLois Curfman McInnes 
8849b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm
885a86d99e1SLois Curfman McInnes 
886b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations()
8879b94acceSBarry Smith @*/
8887087cfbeSBarry Smith PetscErrorCode  SNESGetFunctionNorm(SNES snes,PetscReal *fnorm)
8899b94acceSBarry Smith {
8903a40ed3dSBarry Smith   PetscFunctionBegin;
8910700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
8924482741eSBarry Smith   PetscValidScalarPointer(fnorm,2);
8939b94acceSBarry Smith   *fnorm = snes->norm;
8943a40ed3dSBarry Smith   PetscFunctionReturn(0);
8959b94acceSBarry Smith }
89674679c65SBarry Smith 
897360c497dSPeter Brune 
898360c497dSPeter Brune #undef __FUNCT__
899360c497dSPeter Brune #define __FUNCT__ "SNESSetFunctionNorm"
900360c497dSPeter Brune /*@
901360c497dSPeter Brune    SNESSetFunctionNorm - Sets the 2-norm of the current function computed using VecNorm().
902360c497dSPeter Brune 
903360c497dSPeter Brune    Collective on SNES
904360c497dSPeter Brune 
905360c497dSPeter Brune    Input Parameter:
906360c497dSPeter Brune .  snes - SNES context
907360c497dSPeter Brune .  fnorm - 2-norm of function
908360c497dSPeter Brune 
909360c497dSPeter Brune    Level: developer
910360c497dSPeter Brune 
911360c497dSPeter Brune .keywords: SNES, nonlinear, set, function, norm
912360c497dSPeter Brune 
913360c497dSPeter Brune .seealso: SNESSetFunction(), SNESSetIterationNumber(), VecNorm().
914360c497dSPeter Brune @*/
915360c497dSPeter Brune PetscErrorCode  SNESSetFunctionNorm(SNES snes,PetscReal fnorm)
916360c497dSPeter Brune {
917360c497dSPeter Brune 
918360c497dSPeter Brune   PetscErrorCode ierr;
919360c497dSPeter Brune 
920360c497dSPeter Brune   PetscFunctionBegin;
921360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
922360c497dSPeter Brune   ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr);
923360c497dSPeter Brune   snes->norm = fnorm;
924360c497dSPeter Brune   ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr);
925360c497dSPeter Brune   PetscFunctionReturn(0);
926360c497dSPeter Brune }
927360c497dSPeter Brune 
9284a2ae208SSatish Balay #undef __FUNCT__
929b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures"
9309b94acceSBarry Smith /*@
931b850b91aSLisandro Dalcin    SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
9329b94acceSBarry Smith    attempted by the nonlinear solver.
9339b94acceSBarry Smith 
934c7afd0dbSLois Curfman McInnes    Not Collective
935c7afd0dbSLois Curfman McInnes 
9369b94acceSBarry Smith    Input Parameter:
9379b94acceSBarry Smith .  snes - SNES context
9389b94acceSBarry Smith 
9399b94acceSBarry Smith    Output Parameter:
9409b94acceSBarry Smith .  nfails - number of unsuccessful steps attempted
9419b94acceSBarry Smith 
942c96a6f78SLois Curfman McInnes    Notes:
943c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
944c96a6f78SLois Curfman McInnes 
94536851e7fSLois Curfman McInnes    Level: intermediate
94636851e7fSLois Curfman McInnes 
9479b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
94858ebbce7SBarry Smith 
949e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
95058ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures()
9519b94acceSBarry Smith @*/
9527087cfbeSBarry Smith PetscErrorCode  SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails)
9539b94acceSBarry Smith {
9543a40ed3dSBarry Smith   PetscFunctionBegin;
9550700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9564482741eSBarry Smith   PetscValidIntPointer(nfails,2);
95750ffb88aSMatthew Knepley   *nfails = snes->numFailures;
95850ffb88aSMatthew Knepley   PetscFunctionReturn(0);
95950ffb88aSMatthew Knepley }
96050ffb88aSMatthew Knepley 
96150ffb88aSMatthew Knepley #undef __FUNCT__
962b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures"
96350ffb88aSMatthew Knepley /*@
964b850b91aSLisandro Dalcin    SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
96550ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
96650ffb88aSMatthew Knepley 
96750ffb88aSMatthew Knepley    Not Collective
96850ffb88aSMatthew Knepley 
96950ffb88aSMatthew Knepley    Input Parameters:
97050ffb88aSMatthew Knepley +  snes     - SNES context
97150ffb88aSMatthew Knepley -  maxFails - maximum of unsuccessful steps
97250ffb88aSMatthew Knepley 
97350ffb88aSMatthew Knepley    Level: intermediate
97450ffb88aSMatthew Knepley 
97550ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
97658ebbce7SBarry Smith 
977e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
97858ebbce7SBarry Smith           SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
97950ffb88aSMatthew Knepley @*/
9807087cfbeSBarry Smith PetscErrorCode  SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
98150ffb88aSMatthew Knepley {
98250ffb88aSMatthew Knepley   PetscFunctionBegin;
9830700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
98450ffb88aSMatthew Knepley   snes->maxFailures = maxFails;
98550ffb88aSMatthew Knepley   PetscFunctionReturn(0);
98650ffb88aSMatthew Knepley }
98750ffb88aSMatthew Knepley 
98850ffb88aSMatthew Knepley #undef __FUNCT__
989b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures"
99050ffb88aSMatthew Knepley /*@
991b850b91aSLisandro Dalcin    SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
99250ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
99350ffb88aSMatthew Knepley 
99450ffb88aSMatthew Knepley    Not Collective
99550ffb88aSMatthew Knepley 
99650ffb88aSMatthew Knepley    Input Parameter:
99750ffb88aSMatthew Knepley .  snes     - SNES context
99850ffb88aSMatthew Knepley 
99950ffb88aSMatthew Knepley    Output Parameter:
100050ffb88aSMatthew Knepley .  maxFails - maximum of unsuccessful steps
100150ffb88aSMatthew Knepley 
100250ffb88aSMatthew Knepley    Level: intermediate
100350ffb88aSMatthew Knepley 
100450ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
100558ebbce7SBarry Smith 
1006e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
100758ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
100858ebbce7SBarry Smith 
100950ffb88aSMatthew Knepley @*/
10107087cfbeSBarry Smith PetscErrorCode  SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
101150ffb88aSMatthew Knepley {
101250ffb88aSMatthew Knepley   PetscFunctionBegin;
10130700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10144482741eSBarry Smith   PetscValidIntPointer(maxFails,2);
101550ffb88aSMatthew Knepley   *maxFails = snes->maxFailures;
10163a40ed3dSBarry Smith   PetscFunctionReturn(0);
10179b94acceSBarry Smith }
1018a847f771SSatish Balay 
10194a2ae208SSatish Balay #undef __FUNCT__
10202541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals"
10212541af92SBarry Smith /*@
10222541af92SBarry Smith    SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations
10232541af92SBarry Smith      done by SNES.
10242541af92SBarry Smith 
10252541af92SBarry Smith    Not Collective
10262541af92SBarry Smith 
10272541af92SBarry Smith    Input Parameter:
10282541af92SBarry Smith .  snes     - SNES context
10292541af92SBarry Smith 
10302541af92SBarry Smith    Output Parameter:
10312541af92SBarry Smith .  nfuncs - number of evaluations
10322541af92SBarry Smith 
10332541af92SBarry Smith    Level: intermediate
10342541af92SBarry Smith 
10352541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
103658ebbce7SBarry Smith 
1037e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures()
10382541af92SBarry Smith @*/
10397087cfbeSBarry Smith PetscErrorCode  SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs)
10402541af92SBarry Smith {
10412541af92SBarry Smith   PetscFunctionBegin;
10420700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10432541af92SBarry Smith   PetscValidIntPointer(nfuncs,2);
10442541af92SBarry Smith   *nfuncs = snes->nfuncs;
10452541af92SBarry Smith   PetscFunctionReturn(0);
10462541af92SBarry Smith }
10472541af92SBarry Smith 
10482541af92SBarry Smith #undef __FUNCT__
10493d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures"
10503d4c4710SBarry Smith /*@
10513d4c4710SBarry Smith    SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
10523d4c4710SBarry Smith    linear solvers.
10533d4c4710SBarry Smith 
10543d4c4710SBarry Smith    Not Collective
10553d4c4710SBarry Smith 
10563d4c4710SBarry Smith    Input Parameter:
10573d4c4710SBarry Smith .  snes - SNES context
10583d4c4710SBarry Smith 
10593d4c4710SBarry Smith    Output Parameter:
10603d4c4710SBarry Smith .  nfails - number of failed solves
10613d4c4710SBarry Smith 
10623d4c4710SBarry Smith    Notes:
10633d4c4710SBarry Smith    This counter is reset to zero for each successive call to SNESSolve().
10643d4c4710SBarry Smith 
10653d4c4710SBarry Smith    Level: intermediate
10663d4c4710SBarry Smith 
10673d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
106858ebbce7SBarry Smith 
1069e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures()
10703d4c4710SBarry Smith @*/
10717087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails)
10723d4c4710SBarry Smith {
10733d4c4710SBarry Smith   PetscFunctionBegin;
10740700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10753d4c4710SBarry Smith   PetscValidIntPointer(nfails,2);
10763d4c4710SBarry Smith   *nfails = snes->numLinearSolveFailures;
10773d4c4710SBarry Smith   PetscFunctionReturn(0);
10783d4c4710SBarry Smith }
10793d4c4710SBarry Smith 
10803d4c4710SBarry Smith #undef __FUNCT__
10813d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures"
10823d4c4710SBarry Smith /*@
10833d4c4710SBarry Smith    SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
10843d4c4710SBarry Smith    allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE
10853d4c4710SBarry Smith 
10863f9fe445SBarry Smith    Logically Collective on SNES
10873d4c4710SBarry Smith 
10883d4c4710SBarry Smith    Input Parameters:
10893d4c4710SBarry Smith +  snes     - SNES context
10903d4c4710SBarry Smith -  maxFails - maximum allowed linear solve failures
10913d4c4710SBarry Smith 
10923d4c4710SBarry Smith    Level: intermediate
10933d4c4710SBarry Smith 
1094a6796414SBarry Smith    Notes: By default this is 0; that is SNES returns on the first failed linear solve
10953d4c4710SBarry Smith 
10963d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
10973d4c4710SBarry Smith 
109858ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations()
10993d4c4710SBarry Smith @*/
11007087cfbeSBarry Smith PetscErrorCode  SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
11013d4c4710SBarry Smith {
11023d4c4710SBarry Smith   PetscFunctionBegin;
11030700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1104c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxFails,2);
11053d4c4710SBarry Smith   snes->maxLinearSolveFailures = maxFails;
11063d4c4710SBarry Smith   PetscFunctionReturn(0);
11073d4c4710SBarry Smith }
11083d4c4710SBarry Smith 
11093d4c4710SBarry Smith #undef __FUNCT__
11103d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures"
11113d4c4710SBarry Smith /*@
11123d4c4710SBarry Smith    SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
11133d4c4710SBarry Smith      are allowed before SNES terminates
11143d4c4710SBarry Smith 
11153d4c4710SBarry Smith    Not Collective
11163d4c4710SBarry Smith 
11173d4c4710SBarry Smith    Input Parameter:
11183d4c4710SBarry Smith .  snes     - SNES context
11193d4c4710SBarry Smith 
11203d4c4710SBarry Smith    Output Parameter:
11213d4c4710SBarry Smith .  maxFails - maximum of unsuccessful solves allowed
11223d4c4710SBarry Smith 
11233d4c4710SBarry Smith    Level: intermediate
11243d4c4710SBarry Smith 
11253d4c4710SBarry Smith    Notes: By default this is 1; that is SNES returns on the first failed linear solve
11263d4c4710SBarry Smith 
11273d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
11283d4c4710SBarry Smith 
1129e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(),
11303d4c4710SBarry Smith @*/
11317087cfbeSBarry Smith PetscErrorCode  SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
11323d4c4710SBarry Smith {
11333d4c4710SBarry Smith   PetscFunctionBegin;
11340700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11353d4c4710SBarry Smith   PetscValidIntPointer(maxFails,2);
11363d4c4710SBarry Smith   *maxFails = snes->maxLinearSolveFailures;
11373d4c4710SBarry Smith   PetscFunctionReturn(0);
11383d4c4710SBarry Smith }
11393d4c4710SBarry Smith 
11403d4c4710SBarry Smith #undef __FUNCT__
1141b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations"
1142c96a6f78SLois Curfman McInnes /*@
1143b850b91aSLisandro Dalcin    SNESGetLinearSolveIterations - Gets the total number of linear iterations
1144c96a6f78SLois Curfman McInnes    used by the nonlinear solver.
1145c96a6f78SLois Curfman McInnes 
1146c7afd0dbSLois Curfman McInnes    Not Collective
1147c7afd0dbSLois Curfman McInnes 
1148c96a6f78SLois Curfman McInnes    Input Parameter:
1149c96a6f78SLois Curfman McInnes .  snes - SNES context
1150c96a6f78SLois Curfman McInnes 
1151c96a6f78SLois Curfman McInnes    Output Parameter:
1152c96a6f78SLois Curfman McInnes .  lits - number of linear iterations
1153c96a6f78SLois Curfman McInnes 
1154c96a6f78SLois Curfman McInnes    Notes:
1155c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
1156c96a6f78SLois Curfman McInnes 
115736851e7fSLois Curfman McInnes    Level: intermediate
115836851e7fSLois Curfman McInnes 
1159c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations
11602b668275SBarry Smith 
11618c7482ecSBarry Smith .seealso:  SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures()
1162c96a6f78SLois Curfman McInnes @*/
11637087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveIterations(SNES snes,PetscInt* lits)
1164c96a6f78SLois Curfman McInnes {
11653a40ed3dSBarry Smith   PetscFunctionBegin;
11660700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11674482741eSBarry Smith   PetscValidIntPointer(lits,2);
1168c96a6f78SLois Curfman McInnes   *lits = snes->linear_its;
11693a40ed3dSBarry Smith   PetscFunctionReturn(0);
1170c96a6f78SLois Curfman McInnes }
1171c96a6f78SLois Curfman McInnes 
11724a2ae208SSatish Balay #undef __FUNCT__
117394b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP"
117452baeb72SSatish Balay /*@
117594b7f48cSBarry Smith    SNESGetKSP - Returns the KSP context for a SNES solver.
11769b94acceSBarry Smith 
117794b7f48cSBarry Smith    Not Collective, but if SNES object is parallel, then KSP object is parallel
1178c7afd0dbSLois Curfman McInnes 
11799b94acceSBarry Smith    Input Parameter:
11809b94acceSBarry Smith .  snes - the SNES context
11819b94acceSBarry Smith 
11829b94acceSBarry Smith    Output Parameter:
118394b7f48cSBarry Smith .  ksp - the KSP context
11849b94acceSBarry Smith 
11859b94acceSBarry Smith    Notes:
118694b7f48cSBarry Smith    The user can then directly manipulate the KSP context to set various
11879b94acceSBarry Smith    options, etc.  Likewise, the user can then extract and manipulate the
11882999313aSBarry Smith    PC contexts as well.
11899b94acceSBarry Smith 
119036851e7fSLois Curfman McInnes    Level: beginner
119136851e7fSLois Curfman McInnes 
119294b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
11939b94acceSBarry Smith 
11942999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
11959b94acceSBarry Smith @*/
11967087cfbeSBarry Smith PetscErrorCode  SNESGetKSP(SNES snes,KSP *ksp)
11979b94acceSBarry Smith {
11981cee3971SBarry Smith   PetscErrorCode ierr;
11991cee3971SBarry Smith 
12003a40ed3dSBarry Smith   PetscFunctionBegin;
12010700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
12024482741eSBarry Smith   PetscValidPointer(ksp,2);
12031cee3971SBarry Smith 
12041cee3971SBarry Smith   if (!snes->ksp) {
12051cee3971SBarry Smith     ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr);
12061cee3971SBarry Smith     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr);
12071cee3971SBarry Smith     ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr);
12081cee3971SBarry Smith   }
120994b7f48cSBarry Smith   *ksp = snes->ksp;
12103a40ed3dSBarry Smith   PetscFunctionReturn(0);
12119b94acceSBarry Smith }
121282bf6240SBarry Smith 
12134a2ae208SSatish Balay #undef __FUNCT__
12142999313aSBarry Smith #define __FUNCT__ "SNESSetKSP"
12152999313aSBarry Smith /*@
12162999313aSBarry Smith    SNESSetKSP - Sets a KSP context for the SNES object to use
12172999313aSBarry Smith 
12182999313aSBarry Smith    Not Collective, but the SNES and KSP objects must live on the same MPI_Comm
12192999313aSBarry Smith 
12202999313aSBarry Smith    Input Parameters:
12212999313aSBarry Smith +  snes - the SNES context
12222999313aSBarry Smith -  ksp - the KSP context
12232999313aSBarry Smith 
12242999313aSBarry Smith    Notes:
12252999313aSBarry Smith    The SNES object already has its KSP object, you can obtain with SNESGetKSP()
12262999313aSBarry Smith    so this routine is rarely needed.
12272999313aSBarry Smith 
12282999313aSBarry Smith    The KSP object that is already in the SNES object has its reference count
12292999313aSBarry Smith    decreased by one.
12302999313aSBarry Smith 
12312999313aSBarry Smith    Level: developer
12322999313aSBarry Smith 
12332999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
12342999313aSBarry Smith 
12352999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
12362999313aSBarry Smith @*/
12377087cfbeSBarry Smith PetscErrorCode  SNESSetKSP(SNES snes,KSP ksp)
12382999313aSBarry Smith {
12392999313aSBarry Smith   PetscErrorCode ierr;
12402999313aSBarry Smith 
12412999313aSBarry Smith   PetscFunctionBegin;
12420700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
12430700a824SBarry Smith   PetscValidHeaderSpecific(ksp,KSP_CLASSID,2);
12442999313aSBarry Smith   PetscCheckSameComm(snes,1,ksp,2);
12457dcf0eaaSdalcinl   ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr);
1246906ed7ccSBarry Smith   if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);}
12472999313aSBarry Smith   snes->ksp = ksp;
12482999313aSBarry Smith   PetscFunctionReturn(0);
12492999313aSBarry Smith }
12502999313aSBarry Smith 
12517adad957SLisandro Dalcin #if 0
12522999313aSBarry Smith #undef __FUNCT__
12534a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc"
12546849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj)
1255e24b481bSBarry Smith {
1256e24b481bSBarry Smith   PetscFunctionBegin;
1257e24b481bSBarry Smith   PetscFunctionReturn(0);
1258e24b481bSBarry Smith }
12597adad957SLisandro Dalcin #endif
1260e24b481bSBarry Smith 
12619b94acceSBarry Smith /* -----------------------------------------------------------*/
12624a2ae208SSatish Balay #undef __FUNCT__
12634a2ae208SSatish Balay #define __FUNCT__ "SNESCreate"
126452baeb72SSatish Balay /*@
12659b94acceSBarry Smith    SNESCreate - Creates a nonlinear solver context.
12669b94acceSBarry Smith 
1267c7afd0dbSLois Curfman McInnes    Collective on MPI_Comm
1268c7afd0dbSLois Curfman McInnes 
1269c7afd0dbSLois Curfman McInnes    Input Parameters:
1270906ed7ccSBarry Smith .  comm - MPI communicator
12719b94acceSBarry Smith 
12729b94acceSBarry Smith    Output Parameter:
12739b94acceSBarry Smith .  outsnes - the new SNES context
12749b94acceSBarry Smith 
1275c7afd0dbSLois Curfman McInnes    Options Database Keys:
1276c7afd0dbSLois Curfman McInnes +   -snes_mf - Activates default matrix-free Jacobian-vector products,
1277c7afd0dbSLois Curfman McInnes                and no preconditioning matrix
1278c7afd0dbSLois Curfman McInnes .   -snes_mf_operator - Activates default matrix-free Jacobian-vector
1279c7afd0dbSLois Curfman McInnes                products, and a user-provided preconditioning matrix
1280c7afd0dbSLois Curfman McInnes                as set by SNESSetJacobian()
1281c7afd0dbSLois Curfman McInnes -   -snes_fd - Uses (slow!) finite differences to compute Jacobian
1282c1f60f51SBarry Smith 
128336851e7fSLois Curfman McInnes    Level: beginner
128436851e7fSLois Curfman McInnes 
12859b94acceSBarry Smith .keywords: SNES, nonlinear, create, context
12869b94acceSBarry Smith 
1287a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner()
1288a8054027SBarry Smith 
12899b94acceSBarry Smith @*/
12907087cfbeSBarry Smith PetscErrorCode  SNESCreate(MPI_Comm comm,SNES *outsnes)
12919b94acceSBarry Smith {
1292dfbe8321SBarry Smith   PetscErrorCode      ierr;
12939b94acceSBarry Smith   SNES                snes;
1294fa9f3622SBarry Smith   SNESKSPEW           *kctx;
129537fcc0dbSBarry Smith 
12963a40ed3dSBarry Smith   PetscFunctionBegin;
1297ed1caa07SMatthew Knepley   PetscValidPointer(outsnes,2);
12988ba1e511SMatthew Knepley   *outsnes = PETSC_NULL;
12998ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES
13008ba1e511SMatthew Knepley   ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr);
13018ba1e511SMatthew Knepley #endif
13028ba1e511SMatthew Knepley 
13033194b578SJed Brown   ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr);
13047adad957SLisandro Dalcin 
130585385478SLisandro Dalcin   snes->ops->converged    = SNESDefaultConverged;
13062c155ee1SBarry Smith   snes->usesksp           = PETSC_TRUE;
130788976e71SPeter Brune   snes->tolerancesset     = PETSC_FALSE;
13089b94acceSBarry Smith   snes->max_its           = 50;
13099750a799SBarry Smith   snes->max_funcs	  = 10000;
13109b94acceSBarry Smith   snes->norm		  = 0.0;
1311b4874afaSBarry Smith   snes->rtol		  = 1.e-8;
1312b4874afaSBarry Smith   snes->ttol              = 0.0;
131370441072SBarry Smith   snes->abstol		  = 1.e-50;
1314c60f73f4SPeter Brune   snes->stol		  = 1.e-8;
13154b27c08aSLois Curfman McInnes   snes->deltatol	  = 1.e-12;
13169b94acceSBarry Smith   snes->nfuncs            = 0;
131750ffb88aSMatthew Knepley   snes->numFailures       = 0;
131850ffb88aSMatthew Knepley   snes->maxFailures       = 1;
13197a00f4a9SLois Curfman McInnes   snes->linear_its        = 0;
1320e35cf81dSBarry Smith   snes->lagjacobian       = 1;
1321a8054027SBarry Smith   snes->lagpreconditioner = 1;
1322639f9d9dSBarry Smith   snes->numbermonitors    = 0;
13239b94acceSBarry Smith   snes->data              = 0;
13244dc4c822SBarry Smith   snes->setupcalled       = PETSC_FALSE;
1325186905e3SBarry Smith   snes->ksp_ewconv        = PETSC_FALSE;
13266f24a144SLois Curfman McInnes   snes->nwork             = 0;
132758c9b817SLisandro Dalcin   snes->work              = 0;
132858c9b817SLisandro Dalcin   snes->nvwork            = 0;
132958c9b817SLisandro Dalcin   snes->vwork             = 0;
1330758f92a0SBarry Smith   snes->conv_hist_len     = 0;
1331758f92a0SBarry Smith   snes->conv_hist_max     = 0;
1332758f92a0SBarry Smith   snes->conv_hist         = PETSC_NULL;
1333758f92a0SBarry Smith   snes->conv_hist_its     = PETSC_NULL;
1334758f92a0SBarry Smith   snes->conv_hist_reset   = PETSC_TRUE;
1335*e4ed7901SPeter Brune   snes->vec_func_init_set = PETSC_FALSE;
1336*e4ed7901SPeter Brune   snes->norm_init         = 0.;
1337*e4ed7901SPeter Brune   snes->norm_init_set     = PETSC_FALSE;
1338184914b5SBarry Smith   snes->reason            = SNES_CONVERGED_ITERATING;
133989b92e6fSPeter Brune   snes->gssweeps          = 1;
13409b94acceSBarry Smith 
13413d4c4710SBarry Smith   snes->numLinearSolveFailures = 0;
13423d4c4710SBarry Smith   snes->maxLinearSolveFailures = 1;
13433d4c4710SBarry Smith 
13449b94acceSBarry Smith   /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
134538f2d2fdSLisandro Dalcin   ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr);
13469b94acceSBarry Smith   snes->kspconvctx  = (void*)kctx;
13479b94acceSBarry Smith   kctx->version     = 2;
13489b94acceSBarry Smith   kctx->rtol_0      = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
13499b94acceSBarry Smith                              this was too large for some test cases */
135075567043SBarry Smith   kctx->rtol_last   = 0.0;
13519b94acceSBarry Smith   kctx->rtol_max    = .9;
13529b94acceSBarry Smith   kctx->gamma       = 1.0;
135362d1f40fSBarry Smith   kctx->alpha       = .5*(1.0 + PetscSqrtReal(5.0));
135471f87433Sdalcinl   kctx->alpha2      = kctx->alpha;
13559b94acceSBarry Smith   kctx->threshold   = .1;
135675567043SBarry Smith   kctx->lresid_last = 0.0;
135775567043SBarry Smith   kctx->norm_last   = 0.0;
13589b94acceSBarry Smith 
13599b94acceSBarry Smith   *outsnes = snes;
13603a40ed3dSBarry Smith   PetscFunctionReturn(0);
13619b94acceSBarry Smith }
13629b94acceSBarry Smith 
13634a2ae208SSatish Balay #undef __FUNCT__
13644a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction"
13659b94acceSBarry Smith /*@C
13669b94acceSBarry Smith    SNESSetFunction - Sets the function evaluation routine and function
13679b94acceSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
13689b94acceSBarry Smith    equations.
13699b94acceSBarry Smith 
13703f9fe445SBarry Smith    Logically Collective on SNES
1371fee21e36SBarry Smith 
1372c7afd0dbSLois Curfman McInnes    Input Parameters:
1373c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1374c7afd0dbSLois Curfman McInnes .  r - vector to store function value
1375de044059SHong Zhang .  func - function evaluation routine
1376c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
1377c7afd0dbSLois Curfman McInnes          function evaluation routine (may be PETSC_NULL)
13789b94acceSBarry Smith 
1379c7afd0dbSLois Curfman McInnes    Calling sequence of func:
13808d76a1e5SLois Curfman McInnes $    func (SNES snes,Vec x,Vec f,void *ctx);
1381c7afd0dbSLois Curfman McInnes 
1382c586c404SJed Brown +  snes - the SNES context
1383c586c404SJed Brown .  x - state at which to evaluate residual
1384c586c404SJed Brown .  f - vector to put residual
1385c7afd0dbSLois Curfman McInnes -  ctx - optional user-defined function context
13869b94acceSBarry Smith 
13879b94acceSBarry Smith    Notes:
13889b94acceSBarry Smith    The Newton-like methods typically solve linear systems of the form
13899b94acceSBarry Smith $      f'(x) x = -f(x),
1390c7afd0dbSLois Curfman McInnes    where f'(x) denotes the Jacobian matrix and f(x) is the function.
13919b94acceSBarry Smith 
139236851e7fSLois Curfman McInnes    Level: beginner
139336851e7fSLois Curfman McInnes 
13949b94acceSBarry Smith .keywords: SNES, nonlinear, set, function
13959b94acceSBarry Smith 
13968b0a5094SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard()
13979b94acceSBarry Smith @*/
13987087cfbeSBarry Smith PetscErrorCode  SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx)
13999b94acceSBarry Smith {
140085385478SLisandro Dalcin   PetscErrorCode ierr;
14016cab3a1bSJed Brown   DM             dm;
14026cab3a1bSJed Brown 
14033a40ed3dSBarry Smith   PetscFunctionBegin;
14040700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1405d2a683ecSLisandro Dalcin   if (r) {
1406d2a683ecSLisandro Dalcin     PetscValidHeaderSpecific(r,VEC_CLASSID,2);
1407d2a683ecSLisandro Dalcin     PetscCheckSameComm(snes,1,r,2);
140885385478SLisandro Dalcin     ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr);
14096bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
141085385478SLisandro Dalcin     snes->vec_func = r;
1411d2a683ecSLisandro Dalcin   }
14126cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
14136cab3a1bSJed Brown   ierr = DMSNESSetFunction(dm,func,ctx);CHKERRQ(ierr);
14143a40ed3dSBarry Smith   PetscFunctionReturn(0);
14159b94acceSBarry Smith }
14169b94acceSBarry Smith 
1417646217ecSPeter Brune 
1418646217ecSPeter Brune #undef __FUNCT__
1419*e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunction"
1420*e4ed7901SPeter Brune /*@C
1421*e4ed7901SPeter Brune    SNESSetInitialFunction - Sets the function vector to be used as the
1422*e4ed7901SPeter Brune    function norm at the initialization of the method.  In some
1423*e4ed7901SPeter Brune    instances, the user has precomputed the function before calling
1424*e4ed7901SPeter Brune    SNESSolve.  This function allows one to avoid a redundant call
1425*e4ed7901SPeter Brune    to SNESComputeFunction in that case.
1426*e4ed7901SPeter Brune 
1427*e4ed7901SPeter Brune    Logically Collective on SNES
1428*e4ed7901SPeter Brune 
1429*e4ed7901SPeter Brune    Input Parameters:
1430*e4ed7901SPeter Brune +  snes - the SNES context
1431*e4ed7901SPeter Brune -  f - vector to store function value
1432*e4ed7901SPeter Brune 
1433*e4ed7901SPeter Brune    Notes:
1434*e4ed7901SPeter Brune    This should not be modified during the solution procedure.
1435*e4ed7901SPeter Brune 
1436*e4ed7901SPeter Brune    This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning.
1437*e4ed7901SPeter Brune 
1438*e4ed7901SPeter Brune    Level: developer
1439*e4ed7901SPeter Brune 
1440*e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function
1441*e4ed7901SPeter Brune 
1442*e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunctionNorm()
1443*e4ed7901SPeter Brune @*/
1444*e4ed7901SPeter Brune PetscErrorCode  SNESSetInitialFunction(SNES snes, Vec f)
1445*e4ed7901SPeter Brune {
1446*e4ed7901SPeter Brune   PetscErrorCode ierr;
1447*e4ed7901SPeter Brune   Vec            vec_func;
1448*e4ed7901SPeter Brune 
1449*e4ed7901SPeter Brune   PetscFunctionBegin;
1450*e4ed7901SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1451*e4ed7901SPeter Brune   PetscValidHeaderSpecific(f,VEC_CLASSID,2);
1452*e4ed7901SPeter Brune   PetscCheckSameComm(snes,1,f,2);
1453*e4ed7901SPeter Brune   ierr = PetscObjectReference((PetscObject)f);CHKERRQ(ierr);
1454*e4ed7901SPeter Brune   ierr = SNESGetFunction(snes,&vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
1455*e4ed7901SPeter Brune   ierr = VecCopy(f, vec_func);CHKERRQ(ierr);
1456*e4ed7901SPeter Brune   PetscFunctionReturn(0);
1457*e4ed7901SPeter Brune }
1458*e4ed7901SPeter Brune 
1459*e4ed7901SPeter Brune 
1460*e4ed7901SPeter Brune #undef __FUNCT__
1461*e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunctionNorm"
1462*e4ed7901SPeter Brune /*@C
1463*e4ed7901SPeter Brune    SNESSetInitialFunctionNorm - Sets the function norm to be used as the function norm
1464*e4ed7901SPeter Brune    at the initialization of the  method.  In some instances, the user has precomputed
1465*e4ed7901SPeter Brune    the function and its norm before calling SNESSolve.  This function allows one to
1466*e4ed7901SPeter Brune    avoid a redundant call to SNESComputeFunction() and VecNorm() in that case.
1467*e4ed7901SPeter Brune 
1468*e4ed7901SPeter Brune    Logically Collective on SNES
1469*e4ed7901SPeter Brune 
1470*e4ed7901SPeter Brune    Input Parameters:
1471*e4ed7901SPeter Brune +  snes - the SNES context
1472*e4ed7901SPeter Brune -  fnorm - the norm of F as set by SNESSetInitialFunction()
1473*e4ed7901SPeter Brune 
1474*e4ed7901SPeter Brune    This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning.
1475*e4ed7901SPeter Brune 
1476*e4ed7901SPeter Brune    Level: developer
1477*e4ed7901SPeter Brune 
1478*e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function, norm
1479*e4ed7901SPeter Brune 
1480*e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunction()
1481*e4ed7901SPeter Brune @*/
1482*e4ed7901SPeter Brune PetscErrorCode  SNESSetInitialFunctionNorm(SNES snes, PetscReal fnorm)
1483*e4ed7901SPeter Brune {
1484*e4ed7901SPeter Brune   PetscFunctionBegin;
1485*e4ed7901SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1486*e4ed7901SPeter Brune   snes->norm_init = fnorm;
1487*e4ed7901SPeter Brune   snes->norm_init_set = PETSC_TRUE;
1488*e4ed7901SPeter Brune   PetscFunctionReturn(0);
1489*e4ed7901SPeter Brune }
1490*e4ed7901SPeter Brune 
1491*e4ed7901SPeter Brune #undef __FUNCT__
1492646217ecSPeter Brune #define __FUNCT__ "SNESSetGS"
1493c79ef259SPeter Brune /*@C
1494c79ef259SPeter Brune    SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for
1495c79ef259SPeter Brune    use with composed nonlinear solvers.
1496c79ef259SPeter Brune 
1497c79ef259SPeter Brune    Input Parameters:
1498c79ef259SPeter Brune +  snes   - the SNES context
1499c79ef259SPeter Brune .  gsfunc - function evaluation routine
1500c79ef259SPeter Brune -  ctx    - [optional] user-defined context for private data for the
1501c79ef259SPeter Brune             smoother evaluation routine (may be PETSC_NULL)
1502c79ef259SPeter Brune 
1503c79ef259SPeter Brune    Calling sequence of func:
1504c79ef259SPeter Brune $    func (SNES snes,Vec x,Vec b,void *ctx);
1505c79ef259SPeter Brune 
1506c79ef259SPeter Brune +  X   - solution vector
1507c79ef259SPeter Brune .  B   - RHS vector
1508d28543b3SPeter Brune -  ctx - optional user-defined Gauss-Seidel context
1509c79ef259SPeter Brune 
1510c79ef259SPeter Brune    Notes:
1511c79ef259SPeter Brune    The GS routines are used by the composed nonlinear solver to generate
1512c79ef259SPeter Brune     a problem appropriate update to the solution, particularly FAS.
1513c79ef259SPeter Brune 
1514d28543b3SPeter Brune    Level: intermediate
1515c79ef259SPeter Brune 
1516d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel
1517c79ef259SPeter Brune 
1518c79ef259SPeter Brune .seealso: SNESGetFunction(), SNESComputeGS()
1519c79ef259SPeter Brune @*/
15206cab3a1bSJed Brown PetscErrorCode SNESSetGS(SNES snes,PetscErrorCode (*gsfunc)(SNES,Vec,Vec,void*),void *ctx)
15216cab3a1bSJed Brown {
15226cab3a1bSJed Brown   PetscErrorCode ierr;
15236cab3a1bSJed Brown   DM dm;
15246cab3a1bSJed Brown 
1525646217ecSPeter Brune   PetscFunctionBegin;
15266cab3a1bSJed Brown   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
15276cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
15286cab3a1bSJed Brown   ierr = DMSNESSetGS(dm,gsfunc,ctx);CHKERRQ(ierr);
1529646217ecSPeter Brune   PetscFunctionReturn(0);
1530646217ecSPeter Brune }
1531646217ecSPeter Brune 
1532d25893d9SBarry Smith #undef __FUNCT__
153389b92e6fSPeter Brune #define __FUNCT__ "SNESSetGSSweeps"
153489b92e6fSPeter Brune /*@
153589b92e6fSPeter Brune    SNESSetGSSweeps - Sets the number of sweeps of GS to use.
153689b92e6fSPeter Brune 
153789b92e6fSPeter Brune    Input Parameters:
153889b92e6fSPeter Brune +  snes   - the SNES context
153989b92e6fSPeter Brune -  sweeps  - the number of sweeps of GS to perform.
154089b92e6fSPeter Brune 
154189b92e6fSPeter Brune    Level: intermediate
154289b92e6fSPeter Brune 
154389b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel
154489b92e6fSPeter Brune 
154589b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGetGSSweeps()
154689b92e6fSPeter Brune @*/
154789b92e6fSPeter Brune 
154889b92e6fSPeter Brune PetscErrorCode SNESSetGSSweeps(SNES snes, PetscInt sweeps) {
154989b92e6fSPeter Brune   PetscFunctionBegin;
155089b92e6fSPeter Brune   snes->gssweeps = sweeps;
155189b92e6fSPeter Brune   PetscFunctionReturn(0);
155289b92e6fSPeter Brune }
155389b92e6fSPeter Brune 
155489b92e6fSPeter Brune 
155589b92e6fSPeter Brune #undef __FUNCT__
155689b92e6fSPeter Brune #define __FUNCT__ "SNESGetGSSweeps"
155789b92e6fSPeter Brune /*@
155889b92e6fSPeter Brune    SNESGetGSSweeps - Gets the number of sweeps GS will use.
155989b92e6fSPeter Brune 
156089b92e6fSPeter Brune    Input Parameters:
156189b92e6fSPeter Brune .  snes   - the SNES context
156289b92e6fSPeter Brune 
156389b92e6fSPeter Brune    Output Parameters:
156489b92e6fSPeter Brune .  sweeps  - the number of sweeps of GS to perform.
156589b92e6fSPeter Brune 
156689b92e6fSPeter Brune    Level: intermediate
156789b92e6fSPeter Brune 
156889b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel
156989b92e6fSPeter Brune 
157089b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESSetGSSweeps()
157189b92e6fSPeter Brune @*/
157289b92e6fSPeter Brune PetscErrorCode SNESGetGSSweeps(SNES snes, PetscInt * sweeps) {
157389b92e6fSPeter Brune   PetscFunctionBegin;
157489b92e6fSPeter Brune   *sweeps = snes->gssweeps;
157589b92e6fSPeter Brune   PetscFunctionReturn(0);
157689b92e6fSPeter Brune }
157789b92e6fSPeter Brune 
157889b92e6fSPeter Brune #undef __FUNCT__
15798b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction"
15808b0a5094SBarry Smith PetscErrorCode  SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx)
15818b0a5094SBarry Smith {
15828b0a5094SBarry Smith   PetscErrorCode ierr;
15836cab3a1bSJed Brown   void *functx,*jacctx;
15846cab3a1bSJed Brown 
15858b0a5094SBarry Smith   PetscFunctionBegin;
15866cab3a1bSJed Brown   ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
15876cab3a1bSJed Brown   ierr = SNESGetJacobian(snes,PETSC_NULL,PETSC_NULL,PETSC_NULL,&jacctx);CHKERRQ(ierr);
15888b0a5094SBarry Smith   /*  A(x)*x - b(x) */
15896cab3a1bSJed Brown   ierr = (*snes->ops->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,jacctx);CHKERRQ(ierr);
15906cab3a1bSJed Brown   ierr = (*snes->ops->computepfunction)(snes,x,f,functx);CHKERRQ(ierr);
15918b0a5094SBarry Smith   ierr = VecView(x,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr);
15928b0a5094SBarry Smith   ierr = VecView(f,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr);
15938b0a5094SBarry Smith   ierr = VecScale(f,-1.0);CHKERRQ(ierr);
15948b0a5094SBarry Smith   ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr);
15958b0a5094SBarry Smith   PetscFunctionReturn(0);
15968b0a5094SBarry Smith }
15978b0a5094SBarry Smith 
15988b0a5094SBarry Smith #undef __FUNCT__
15998b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian"
16008b0a5094SBarry Smith PetscErrorCode  SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx)
16018b0a5094SBarry Smith {
16028b0a5094SBarry Smith   PetscFunctionBegin;
16038b0a5094SBarry Smith   *flag = snes->matstruct;
16048b0a5094SBarry Smith   PetscFunctionReturn(0);
16058b0a5094SBarry Smith }
16068b0a5094SBarry Smith 
16078b0a5094SBarry Smith #undef __FUNCT__
16088b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard"
16098b0a5094SBarry Smith /*@C
16100d04baf8SBarry Smith    SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization)
16118b0a5094SBarry Smith 
16128b0a5094SBarry Smith    Logically Collective on SNES
16138b0a5094SBarry Smith 
16148b0a5094SBarry Smith    Input Parameters:
16158b0a5094SBarry Smith +  snes - the SNES context
16168b0a5094SBarry Smith .  r - vector to store function value
16178b0a5094SBarry Smith .  func - function evaluation routine
16188b0a5094SBarry 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)
16198b0a5094SBarry Smith .  mat - matrix to store A
16208b0a5094SBarry Smith .  mfunc  - function to compute matrix value
16218b0a5094SBarry Smith -  ctx - [optional] user-defined context for private data for the
16228b0a5094SBarry Smith          function evaluation routine (may be PETSC_NULL)
16238b0a5094SBarry Smith 
16248b0a5094SBarry Smith    Calling sequence of func:
16258b0a5094SBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
16268b0a5094SBarry Smith 
16278b0a5094SBarry Smith +  f - function vector
16288b0a5094SBarry Smith -  ctx - optional user-defined function context
16298b0a5094SBarry Smith 
16308b0a5094SBarry Smith    Calling sequence of mfunc:
16318b0a5094SBarry Smith $     mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx);
16328b0a5094SBarry Smith 
16338b0a5094SBarry Smith +  x - input vector
16348b0a5094SBarry 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(),
16358b0a5094SBarry Smith           normally just pass mat in this location
16368b0a5094SBarry Smith .  mat - form A(x) matrix
16378b0a5094SBarry Smith .  flag - flag indicating information about the preconditioner matrix
16388b0a5094SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
16398b0a5094SBarry Smith -  ctx - [optional] user-defined Jacobian context
16408b0a5094SBarry Smith 
16418b0a5094SBarry Smith    Notes:
16428b0a5094SBarry Smith     One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both
16438b0a5094SBarry Smith 
16448b0a5094SBarry 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}
16458b0a5094SBarry 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.
16468b0a5094SBarry Smith 
16478b0a5094SBarry Smith      Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner.
16488b0a5094SBarry Smith 
16490d04baf8SBarry Smith    We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then
16500d04baf8SBarry Smith    the direct Picard iteration A(x^n) x^{n+1} = b(x^n)
16518b0a5094SBarry Smith 
16528b0a5094SBarry 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
16538b0a5094SBarry 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
16548b0a5094SBarry Smith    different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-).
16558b0a5094SBarry Smith 
16568b0a5094SBarry Smith    Level: beginner
16578b0a5094SBarry Smith 
16588b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function
16598b0a5094SBarry Smith 
16600d04baf8SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard()
16618b0a5094SBarry Smith @*/
16628b0a5094SBarry 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)
16638b0a5094SBarry Smith {
16648b0a5094SBarry Smith   PetscErrorCode ierr;
16658b0a5094SBarry Smith   PetscFunctionBegin;
16668b0a5094SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
16678b0a5094SBarry Smith   snes->ops->computepfunction = func;
16688b0a5094SBarry Smith   snes->ops->computepjacobian = mfunc;
16698b0a5094SBarry Smith   ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr);
16708b0a5094SBarry Smith   ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr);
16718b0a5094SBarry Smith   PetscFunctionReturn(0);
16728b0a5094SBarry Smith }
16738b0a5094SBarry Smith 
16748b0a5094SBarry Smith #undef __FUNCT__
1675d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess"
1676d25893d9SBarry Smith /*@C
1677d25893d9SBarry Smith    SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem
1678d25893d9SBarry Smith 
1679d25893d9SBarry Smith    Logically Collective on SNES
1680d25893d9SBarry Smith 
1681d25893d9SBarry Smith    Input Parameters:
1682d25893d9SBarry Smith +  snes - the SNES context
1683d25893d9SBarry Smith .  func - function evaluation routine
1684d25893d9SBarry Smith -  ctx - [optional] user-defined context for private data for the
1685d25893d9SBarry Smith          function evaluation routine (may be PETSC_NULL)
1686d25893d9SBarry Smith 
1687d25893d9SBarry Smith    Calling sequence of func:
1688d25893d9SBarry Smith $    func (SNES snes,Vec x,void *ctx);
1689d25893d9SBarry Smith 
1690d25893d9SBarry Smith .  f - function vector
1691d25893d9SBarry Smith -  ctx - optional user-defined function context
1692d25893d9SBarry Smith 
1693d25893d9SBarry Smith    Level: intermediate
1694d25893d9SBarry Smith 
1695d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function
1696d25893d9SBarry Smith 
1697d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
1698d25893d9SBarry Smith @*/
1699d25893d9SBarry Smith PetscErrorCode  SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx)
1700d25893d9SBarry Smith {
1701d25893d9SBarry Smith   PetscFunctionBegin;
1702d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1703d25893d9SBarry Smith   if (func) snes->ops->computeinitialguess = func;
1704d25893d9SBarry Smith   if (ctx)  snes->initialguessP            = ctx;
1705d25893d9SBarry Smith   PetscFunctionReturn(0);
1706d25893d9SBarry Smith }
1707d25893d9SBarry Smith 
17083ab0aad5SBarry Smith /* --------------------------------------------------------------- */
17093ab0aad5SBarry Smith #undef __FUNCT__
17101096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs"
17111096aae1SMatthew Knepley /*@C
17121096aae1SMatthew Knepley    SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
17131096aae1SMatthew Knepley    it assumes a zero right hand side.
17141096aae1SMatthew Knepley 
17153f9fe445SBarry Smith    Logically Collective on SNES
17161096aae1SMatthew Knepley 
17171096aae1SMatthew Knepley    Input Parameter:
17181096aae1SMatthew Knepley .  snes - the SNES context
17191096aae1SMatthew Knepley 
17201096aae1SMatthew Knepley    Output Parameter:
1721bc08b0f1SBarry Smith .  rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null
17221096aae1SMatthew Knepley 
17231096aae1SMatthew Knepley    Level: intermediate
17241096aae1SMatthew Knepley 
17251096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side
17261096aae1SMatthew Knepley 
172785385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
17281096aae1SMatthew Knepley @*/
17297087cfbeSBarry Smith PetscErrorCode  SNESGetRhs(SNES snes,Vec *rhs)
17301096aae1SMatthew Knepley {
17311096aae1SMatthew Knepley   PetscFunctionBegin;
17320700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
17331096aae1SMatthew Knepley   PetscValidPointer(rhs,2);
173485385478SLisandro Dalcin   *rhs = snes->vec_rhs;
17351096aae1SMatthew Knepley   PetscFunctionReturn(0);
17361096aae1SMatthew Knepley }
17371096aae1SMatthew Knepley 
17381096aae1SMatthew Knepley #undef __FUNCT__
17394a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction"
17409b94acceSBarry Smith /*@
174136851e7fSLois Curfman McInnes    SNESComputeFunction - Calls the function that has been set with
17429b94acceSBarry Smith                          SNESSetFunction().
17439b94acceSBarry Smith 
1744c7afd0dbSLois Curfman McInnes    Collective on SNES
1745c7afd0dbSLois Curfman McInnes 
17469b94acceSBarry Smith    Input Parameters:
1747c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1748c7afd0dbSLois Curfman McInnes -  x - input vector
17499b94acceSBarry Smith 
17509b94acceSBarry Smith    Output Parameter:
17513638b69dSLois Curfman McInnes .  y - function vector, as set by SNESSetFunction()
17529b94acceSBarry Smith 
17531bffabb2SLois Curfman McInnes    Notes:
175436851e7fSLois Curfman McInnes    SNESComputeFunction() is typically used within nonlinear solvers
175536851e7fSLois Curfman McInnes    implementations, so most users would not generally call this routine
175636851e7fSLois Curfman McInnes    themselves.
175736851e7fSLois Curfman McInnes 
175836851e7fSLois Curfman McInnes    Level: developer
175936851e7fSLois Curfman McInnes 
17609b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function
17619b94acceSBarry Smith 
1762a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction()
17639b94acceSBarry Smith @*/
17647087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction(SNES snes,Vec x,Vec y)
17659b94acceSBarry Smith {
1766dfbe8321SBarry Smith   PetscErrorCode ierr;
17676cab3a1bSJed Brown   DM             dm;
17686cab3a1bSJed Brown   SNESDM         sdm;
17699b94acceSBarry Smith 
17703a40ed3dSBarry Smith   PetscFunctionBegin;
17710700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
17720700a824SBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
17730700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
1774c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,x,2);
1775c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,3);
17764ec14c9cSBarry Smith   VecValidValues(x,2,PETSC_TRUE);
1777184914b5SBarry Smith 
17786cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
17796cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
1780d5ba7fb7SMatthew Knepley   ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
17816cab3a1bSJed Brown   if (sdm->computefunction) {
1782d64ed03dSBarry Smith     PetscStackPush("SNES user function");
17836cab3a1bSJed Brown     ierr = (*sdm->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr);
1784d64ed03dSBarry Smith     PetscStackPop;
178573250ac0SBarry Smith   } else if (snes->dm) {
1786644e2e5bSBarry Smith     ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr);
1787c90fad12SPeter Brune   } else if (snes->vec_rhs) {
1788c90fad12SPeter Brune     ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr);
1789644e2e5bSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve().");
179085385478SLisandro Dalcin   if (snes->vec_rhs) {
179185385478SLisandro Dalcin     ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr);
17923ab0aad5SBarry Smith   }
1793ae3c334cSLois Curfman McInnes   snes->nfuncs++;
1794d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
17954ec14c9cSBarry Smith   VecValidValues(y,3,PETSC_FALSE);
17963a40ed3dSBarry Smith   PetscFunctionReturn(0);
17979b94acceSBarry Smith }
17989b94acceSBarry Smith 
17994a2ae208SSatish Balay #undef __FUNCT__
1800646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS"
1801c79ef259SPeter Brune /*@
1802c79ef259SPeter Brune    SNESComputeGS - Calls the Gauss-Seidel function that has been set with
1803c79ef259SPeter Brune                    SNESSetGS().
1804c79ef259SPeter Brune 
1805c79ef259SPeter Brune    Collective on SNES
1806c79ef259SPeter Brune 
1807c79ef259SPeter Brune    Input Parameters:
1808c79ef259SPeter Brune +  snes - the SNES context
1809c79ef259SPeter Brune .  x - input vector
1810c79ef259SPeter Brune -  b - rhs vector
1811c79ef259SPeter Brune 
1812c79ef259SPeter Brune    Output Parameter:
1813c79ef259SPeter Brune .  x - new solution vector
1814c79ef259SPeter Brune 
1815c79ef259SPeter Brune    Notes:
1816c79ef259SPeter Brune    SNESComputeGS() is typically used within composed nonlinear solver
1817c79ef259SPeter Brune    implementations, so most users would not generally call this routine
1818c79ef259SPeter Brune    themselves.
1819c79ef259SPeter Brune 
1820c79ef259SPeter Brune    Level: developer
1821c79ef259SPeter Brune 
1822c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function
1823c79ef259SPeter Brune 
1824c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction()
1825c79ef259SPeter Brune @*/
1826646217ecSPeter Brune PetscErrorCode  SNESComputeGS(SNES snes,Vec b,Vec x)
1827646217ecSPeter Brune {
1828646217ecSPeter Brune   PetscErrorCode ierr;
182989b92e6fSPeter Brune   PetscInt i;
18306cab3a1bSJed Brown   DM dm;
18316cab3a1bSJed Brown   SNESDM sdm;
1832646217ecSPeter Brune 
1833646217ecSPeter Brune   PetscFunctionBegin;
1834646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1835646217ecSPeter Brune   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
1836646217ecSPeter Brune   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3);
1837646217ecSPeter Brune   PetscCheckSameComm(snes,1,x,2);
1838646217ecSPeter Brune   if(b) PetscCheckSameComm(snes,1,b,3);
18394ec14c9cSBarry Smith   if (b) VecValidValues(b,2,PETSC_TRUE);
1840701cf23dSPeter Brune   ierr = PetscLogEventBegin(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr);
18416cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
18426cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
18436cab3a1bSJed Brown   if (sdm->computegs) {
184489b92e6fSPeter Brune     for (i = 0; i < snes->gssweeps; i++) {
1845646217ecSPeter Brune       PetscStackPush("SNES user GS");
18466cab3a1bSJed Brown       ierr = (*sdm->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr);
1847646217ecSPeter Brune       PetscStackPop;
184889b92e6fSPeter Brune     }
1849646217ecSPeter Brune   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve().");
1850701cf23dSPeter Brune   ierr = PetscLogEventEnd(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr);
18514ec14c9cSBarry Smith   VecValidValues(x,3,PETSC_FALSE);
1852646217ecSPeter Brune   PetscFunctionReturn(0);
1853646217ecSPeter Brune }
1854646217ecSPeter Brune 
1855646217ecSPeter Brune 
1856646217ecSPeter Brune #undef __FUNCT__
18574a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian"
185862fef451SLois Curfman McInnes /*@
185962fef451SLois Curfman McInnes    SNESComputeJacobian - Computes the Jacobian matrix that has been
186062fef451SLois Curfman McInnes    set with SNESSetJacobian().
186162fef451SLois Curfman McInnes 
1862c7afd0dbSLois Curfman McInnes    Collective on SNES and Mat
1863c7afd0dbSLois Curfman McInnes 
186462fef451SLois Curfman McInnes    Input Parameters:
1865c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1866c7afd0dbSLois Curfman McInnes -  x - input vector
186762fef451SLois Curfman McInnes 
186862fef451SLois Curfman McInnes    Output Parameters:
1869c7afd0dbSLois Curfman McInnes +  A - Jacobian matrix
187062fef451SLois Curfman McInnes .  B - optional preconditioning matrix
18712b668275SBarry Smith -  flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER)
1872fee21e36SBarry Smith 
1873e35cf81dSBarry Smith   Options Database Keys:
1874e35cf81dSBarry Smith +    -snes_lag_preconditioner <lag>
1875693365a8SJed Brown .    -snes_lag_jacobian <lag>
1876693365a8SJed Brown .    -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences
1877693365a8SJed Brown .    -snes_compare_explicit_draw  - Compare the computed Jacobian to the finite difference Jacobian and draw the result
1878693365a8SJed Brown .    -snes_compare_explicit_contour  - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result
18794c30e9fbSJed Brown .    -snes_compare_operator  - Make the comparison options above use the operator instead of the preconditioning matrix
1880c01495d3SJed Brown .    -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference
1881c01495d3SJed Brown .    -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences
1882c01495d3SJed Brown .    -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold
1883c01495d3SJed Brown .    -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
1884c01495d3SJed Brown .    -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
18854c30e9fbSJed Brown .    -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences
1886c01495d3SJed Brown -    -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences
1887c01495d3SJed Brown 
1888e35cf81dSBarry Smith 
188962fef451SLois Curfman McInnes    Notes:
189062fef451SLois Curfman McInnes    Most users should not need to explicitly call this routine, as it
189162fef451SLois Curfman McInnes    is used internally within the nonlinear solvers.
189262fef451SLois Curfman McInnes 
189394b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the
1894dc5a77f8SLois Curfman McInnes    flag parameter.
189562fef451SLois Curfman McInnes 
189636851e7fSLois Curfman McInnes    Level: developer
189736851e7fSLois Curfman McInnes 
189862fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix
189962fef451SLois Curfman McInnes 
1900e35cf81dSBarry Smith .seealso:  SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian()
190162fef451SLois Curfman McInnes @*/
19027087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg)
19039b94acceSBarry Smith {
1904dfbe8321SBarry Smith   PetscErrorCode ierr;
1905ace3abfcSBarry Smith   PetscBool      flag;
19066cab3a1bSJed Brown   DM             dm;
19076cab3a1bSJed Brown   SNESDM         sdm;
19083a40ed3dSBarry Smith 
19093a40ed3dSBarry Smith   PetscFunctionBegin;
19100700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
19110700a824SBarry Smith   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
19124482741eSBarry Smith   PetscValidPointer(flg,5);
1913c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,X,2);
19144ec14c9cSBarry Smith   VecValidValues(X,2,PETSC_TRUE);
19156cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
19166cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
19176cab3a1bSJed Brown   if (!sdm->computejacobian) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc");
1918ebd3b9afSBarry Smith 
1919ebd3b9afSBarry Smith   /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */
1920ebd3b9afSBarry Smith 
1921fe3ffe1eSBarry Smith   if (snes->lagjacobian == -2) {
1922fe3ffe1eSBarry Smith     snes->lagjacobian = -1;
1923fe3ffe1eSBarry Smith     ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr);
1924fe3ffe1eSBarry Smith   } else if (snes->lagjacobian == -1) {
1925e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
1926e35cf81dSBarry Smith     ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr);
1927ebd3b9afSBarry Smith     ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
1928ebd3b9afSBarry Smith     if (flag) {
1929ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1930ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1931ebd3b9afSBarry Smith     }
1932e35cf81dSBarry Smith     PetscFunctionReturn(0);
1933e35cf81dSBarry Smith   } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) {
1934e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
1935e35cf81dSBarry Smith     ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr);
1936ebd3b9afSBarry Smith     ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
1937ebd3b9afSBarry Smith     if (flag) {
1938ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1939ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1940ebd3b9afSBarry Smith     }
1941e35cf81dSBarry Smith     PetscFunctionReturn(0);
1942e35cf81dSBarry Smith   }
1943e35cf81dSBarry Smith 
1944c4fc05e7SBarry Smith   *flg = DIFFERENT_NONZERO_PATTERN;
1945e35cf81dSBarry Smith   ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
1946d64ed03dSBarry Smith   PetscStackPush("SNES user Jacobian function");
19476cab3a1bSJed Brown   ierr = (*sdm->computejacobian)(snes,X,A,B,flg,sdm->jacobianctx);CHKERRQ(ierr);
1948d64ed03dSBarry Smith   PetscStackPop;
1949d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
1950a8054027SBarry Smith 
19513b4f5425SBarry Smith   if (snes->lagpreconditioner == -2) {
19523b4f5425SBarry Smith     ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr);
19533b4f5425SBarry Smith     snes->lagpreconditioner = -1;
19543b4f5425SBarry Smith   } else if (snes->lagpreconditioner == -1) {
1955a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
1956a8054027SBarry Smith     ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr);
1957a8054027SBarry Smith   } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) {
1958a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
1959a8054027SBarry Smith     ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr);
1960a8054027SBarry Smith   }
1961a8054027SBarry Smith 
19626d84be18SBarry Smith   /* make sure user returned a correct Jacobian and preconditioner */
19630700a824SBarry Smith   /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3);
19640700a824SBarry Smith     PetscValidHeaderSpecific(*B,MAT_CLASSID,4);   */
1965693365a8SJed Brown   {
1966693365a8SJed Brown     PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE;
1967693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr);
1968693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr);
1969693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr);
1970693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr);
1971693365a8SJed Brown     if (flag || flag_draw || flag_contour) {
1972693365a8SJed Brown       Mat Bexp_mine = PETSC_NULL,Bexp,FDexp;
1973693365a8SJed Brown       MatStructure mstruct;
1974693365a8SJed Brown       PetscViewer vdraw,vstdout;
19756b3a5b13SJed Brown       PetscBool flg;
1976693365a8SJed Brown       if (flag_operator) {
1977693365a8SJed Brown         ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr);
1978693365a8SJed Brown         Bexp = Bexp_mine;
1979693365a8SJed Brown       } else {
1980693365a8SJed Brown         /* See if the preconditioning matrix can be viewed and added directly */
1981693365a8SJed Brown         ierr = PetscTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr);
1982693365a8SJed Brown         if (flg) Bexp = *B;
1983693365a8SJed Brown         else {
1984693365a8SJed Brown           /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */
1985693365a8SJed Brown           ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr);
1986693365a8SJed Brown           Bexp = Bexp_mine;
1987693365a8SJed Brown         }
1988693365a8SJed Brown       }
1989693365a8SJed Brown       ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr);
1990693365a8SJed Brown       ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr);
1991693365a8SJed Brown       ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr);
1992693365a8SJed Brown       if (flag_draw || flag_contour) {
1993693365a8SJed Brown         ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
1994693365a8SJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
1995693365a8SJed Brown       } else vdraw = PETSC_NULL;
1996693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr);
1997693365a8SJed Brown       if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);}
1998693365a8SJed Brown       if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);}
1999693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr);
2000693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
2001693365a8SJed Brown       if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);}
2002693365a8SJed Brown       ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2003693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr);
2004693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
2005693365a8SJed Brown       if (vdraw) {              /* Always use contour for the difference */
2006693365a8SJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
2007693365a8SJed Brown         ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);
2008693365a8SJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
2009693365a8SJed Brown       }
2010693365a8SJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
2011693365a8SJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
2012693365a8SJed Brown       ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr);
2013693365a8SJed Brown       ierr = MatDestroy(&FDexp);CHKERRQ(ierr);
2014693365a8SJed Brown     }
2015693365a8SJed Brown   }
20164c30e9fbSJed Brown   {
20176719d8e4SJed Brown     PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE;
20186719d8e4SJed Brown     PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON;
20194c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr);
20206719d8e4SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr);
20214c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr);
20224c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr);
20236719d8e4SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr);
20246719d8e4SJed Brown     ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr);
20256719d8e4SJed Brown     ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr);
20266719d8e4SJed Brown     if (flag || flag_display || flag_draw || flag_contour || flag_threshold) {
20274c30e9fbSJed Brown       Mat Bfd;
20284c30e9fbSJed Brown       MatStructure mstruct;
20294c30e9fbSJed Brown       PetscViewer vdraw,vstdout;
20304c30e9fbSJed Brown       ISColoring iscoloring;
20314c30e9fbSJed Brown       MatFDColoring matfdcoloring;
20324c30e9fbSJed Brown       PetscErrorCode (*func)(SNES,Vec,Vec,void*);
20334c30e9fbSJed Brown       void *funcctx;
20346719d8e4SJed Brown       PetscReal norm1,norm2,normmax;
20354c30e9fbSJed Brown 
20364c30e9fbSJed Brown       ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr);
20374c30e9fbSJed Brown       ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr);
20384c30e9fbSJed Brown       ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr);
20394c30e9fbSJed Brown       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
20404c30e9fbSJed Brown 
20414c30e9fbSJed Brown       /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */
20424c30e9fbSJed Brown       ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr);
20434c30e9fbSJed Brown       ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr);
20444c30e9fbSJed Brown       ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr);
20454c30e9fbSJed Brown       ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr);
20464c30e9fbSJed Brown       ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr);
20474c30e9fbSJed Brown       ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr);
20484c30e9fbSJed Brown       ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr);
20494c30e9fbSJed Brown 
20504c30e9fbSJed Brown       ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr);
20514c30e9fbSJed Brown       if (flag_draw || flag_contour) {
20524c30e9fbSJed Brown         ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
20534c30e9fbSJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
20544c30e9fbSJed Brown       } else vdraw = PETSC_NULL;
20554c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr);
20566719d8e4SJed Brown       if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);}
20574c30e9fbSJed Brown       if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);}
20584c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr);
20596719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
20604c30e9fbSJed Brown       if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);}
20614c30e9fbSJed Brown       ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
20624c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr);
20636719d8e4SJed Brown       ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr);
20644c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr);
20656719d8e4SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr);
20666719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
20674c30e9fbSJed Brown       if (vdraw) {              /* Always use contour for the difference */
20684c30e9fbSJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
20694c30e9fbSJed Brown         ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);
20704c30e9fbSJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
20714c30e9fbSJed Brown       }
20724c30e9fbSJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
20736719d8e4SJed Brown 
20746719d8e4SJed Brown       if (flag_threshold) {
20756719d8e4SJed Brown         PetscInt bs,rstart,rend,i;
20766719d8e4SJed Brown         ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr);
20776719d8e4SJed Brown         ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr);
20786719d8e4SJed Brown         for (i=rstart; i<rend; i++) {
20796719d8e4SJed Brown           const PetscScalar *ba,*ca;
20806719d8e4SJed Brown           const PetscInt *bj,*cj;
20816719d8e4SJed Brown           PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1;
20826719d8e4SJed Brown           PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0;
20836719d8e4SJed Brown           ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr);
20846719d8e4SJed Brown           ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
20856719d8e4SJed Brown           if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold");
20866719d8e4SJed Brown           for (j=0; j<bn; j++) {
20876719d8e4SJed Brown             PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
20886719d8e4SJed Brown             if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) {
20896719d8e4SJed Brown               maxentrycol = bj[j];
20906719d8e4SJed Brown               maxentry = PetscRealPart(ba[j]);
20916719d8e4SJed Brown             }
20926719d8e4SJed Brown             if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) {
20936719d8e4SJed Brown               maxdiffcol = bj[j];
20946719d8e4SJed Brown               maxdiff = PetscRealPart(ca[j]);
20956719d8e4SJed Brown             }
20966719d8e4SJed Brown             if (rdiff > maxrdiff) {
20976719d8e4SJed Brown               maxrdiffcol = bj[j];
20986719d8e4SJed Brown               maxrdiff = rdiff;
20996719d8e4SJed Brown             }
21006719d8e4SJed Brown           }
21016719d8e4SJed Brown           if (maxrdiff > 1) {
21026719d8e4SJed 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);
21036719d8e4SJed Brown             for (j=0; j<bn; j++) {
21046719d8e4SJed Brown               PetscReal rdiff;
21056719d8e4SJed Brown               rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
21066719d8e4SJed Brown               if (rdiff > 1) {
21076719d8e4SJed Brown                 ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr);
21086719d8e4SJed Brown               }
21096719d8e4SJed Brown             }
21106719d8e4SJed Brown             ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr);
21116719d8e4SJed Brown           }
21126719d8e4SJed Brown           ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr);
21136719d8e4SJed Brown           ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
21146719d8e4SJed Brown         }
21156719d8e4SJed Brown       }
21164c30e9fbSJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
21174c30e9fbSJed Brown       ierr = MatDestroy(&Bfd);CHKERRQ(ierr);
21184c30e9fbSJed Brown     }
21194c30e9fbSJed Brown   }
21203a40ed3dSBarry Smith   PetscFunctionReturn(0);
21219b94acceSBarry Smith }
21229b94acceSBarry Smith 
21234a2ae208SSatish Balay #undef __FUNCT__
21244a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian"
21259b94acceSBarry Smith /*@C
21269b94acceSBarry Smith    SNESSetJacobian - Sets the function to compute Jacobian as well as the
2127044dda88SLois Curfman McInnes    location to store the matrix.
21289b94acceSBarry Smith 
21293f9fe445SBarry Smith    Logically Collective on SNES and Mat
2130c7afd0dbSLois Curfman McInnes 
21319b94acceSBarry Smith    Input Parameters:
2132c7afd0dbSLois Curfman McInnes +  snes - the SNES context
21339b94acceSBarry Smith .  A - Jacobian matrix
21349b94acceSBarry Smith .  B - preconditioner matrix (usually same as the Jacobian)
2135efd51863SBarry Smith .  func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value)
2136c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
2137efd51863SBarry Smith          Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value)
21389b94acceSBarry Smith 
21399b94acceSBarry Smith    Calling sequence of func:
21408d76a1e5SLois Curfman McInnes $     func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx);
21419b94acceSBarry Smith 
2142c7afd0dbSLois Curfman McInnes +  x - input vector
21439b94acceSBarry Smith .  A - Jacobian matrix
21449b94acceSBarry Smith .  B - preconditioner matrix, usually the same as A
2145ac21db08SLois Curfman McInnes .  flag - flag indicating information about the preconditioner matrix
21462b668275SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
2147c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined Jacobian context
21489b94acceSBarry Smith 
21499b94acceSBarry Smith    Notes:
215094b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the flag
21512cd2dfdcSLois Curfman McInnes    output parameter in the routine func().  Be sure to read this information!
2152ac21db08SLois Curfman McInnes 
2153ac21db08SLois Curfman McInnes    The routine func() takes Mat * as the matrix arguments rather than Mat.
21549b94acceSBarry Smith    This allows the Jacobian evaluation routine to replace A and/or B with a
21559b94acceSBarry Smith    completely new new matrix structure (not just different matrix elements)
21569b94acceSBarry Smith    when appropriate, for instance, if the nonzero structure is changing
21579b94acceSBarry Smith    throughout the global iterations.
21589b94acceSBarry Smith 
215916913363SBarry Smith    If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on
216016913363SBarry Smith    each matrix.
216116913363SBarry Smith 
2162a8a26c1eSJed Brown    If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument
2163a8a26c1eSJed Brown    must be a MatFDColoring.
2164a8a26c1eSJed Brown 
2165c3cc8fd1SJed Brown    Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian.  One common
2166c3cc8fd1SJed Brown    example is to use the "Picard linearization" which only differentiates through the highest order parts of each term.
2167c3cc8fd1SJed Brown 
216836851e7fSLois Curfman McInnes    Level: beginner
216936851e7fSLois Curfman McInnes 
21709b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix
21719b94acceSBarry Smith 
21723ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure
21739b94acceSBarry Smith @*/
21747087cfbeSBarry Smith PetscErrorCode  SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
21759b94acceSBarry Smith {
2176dfbe8321SBarry Smith   PetscErrorCode ierr;
21776cab3a1bSJed Brown   DM             dm;
21783a7fca6bSBarry Smith 
21793a40ed3dSBarry Smith   PetscFunctionBegin;
21800700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
21810700a824SBarry Smith   if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2);
21820700a824SBarry Smith   if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3);
2183c9780b6fSBarry Smith   if (A) PetscCheckSameComm(snes,1,A,2);
218406975374SJed Brown   if (B) PetscCheckSameComm(snes,1,B,3);
21856cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
21866cab3a1bSJed Brown   ierr = DMSNESSetJacobian(dm,func,ctx);CHKERRQ(ierr);
21873a7fca6bSBarry Smith   if (A) {
21887dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
21896bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
21909b94acceSBarry Smith     snes->jacobian = A;
21913a7fca6bSBarry Smith   }
21923a7fca6bSBarry Smith   if (B) {
21937dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr);
21946bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
21959b94acceSBarry Smith     snes->jacobian_pre = B;
21963a7fca6bSBarry Smith   }
21973a40ed3dSBarry Smith   PetscFunctionReturn(0);
21989b94acceSBarry Smith }
219962fef451SLois Curfman McInnes 
22004a2ae208SSatish Balay #undef __FUNCT__
22014a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian"
2202c2aafc4cSSatish Balay /*@C
2203b4fd4287SBarry Smith    SNESGetJacobian - Returns the Jacobian matrix and optionally the user
2204b4fd4287SBarry Smith    provided context for evaluating the Jacobian.
2205b4fd4287SBarry Smith 
2206c7afd0dbSLois Curfman McInnes    Not Collective, but Mat object will be parallel if SNES object is
2207c7afd0dbSLois Curfman McInnes 
2208b4fd4287SBarry Smith    Input Parameter:
2209b4fd4287SBarry Smith .  snes - the nonlinear solver context
2210b4fd4287SBarry Smith 
2211b4fd4287SBarry Smith    Output Parameters:
2212c7afd0dbSLois Curfman McInnes +  A - location to stash Jacobian matrix (or PETSC_NULL)
2213b4fd4287SBarry Smith .  B - location to stash preconditioner matrix (or PETSC_NULL)
221470e92668SMatthew Knepley .  func - location to put Jacobian function (or PETSC_NULL)
221570e92668SMatthew Knepley -  ctx - location to stash Jacobian ctx (or PETSC_NULL)
2216fee21e36SBarry Smith 
221736851e7fSLois Curfman McInnes    Level: advanced
221836851e7fSLois Curfman McInnes 
2219b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian()
2220b4fd4287SBarry Smith @*/
22217087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
2222b4fd4287SBarry Smith {
22236cab3a1bSJed Brown   PetscErrorCode ierr;
22246cab3a1bSJed Brown   DM             dm;
22256cab3a1bSJed Brown   SNESDM         sdm;
22266cab3a1bSJed Brown 
22273a40ed3dSBarry Smith   PetscFunctionBegin;
22280700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2229b4fd4287SBarry Smith   if (A)    *A    = snes->jacobian;
2230b4fd4287SBarry Smith   if (B)    *B    = snes->jacobian_pre;
22316cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
22326cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
22336cab3a1bSJed Brown   if (func) *func = sdm->computejacobian;
22346cab3a1bSJed Brown   if (ctx)  *ctx  = sdm->jacobianctx;
22353a40ed3dSBarry Smith   PetscFunctionReturn(0);
2236b4fd4287SBarry Smith }
2237b4fd4287SBarry Smith 
22389b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */
22399b94acceSBarry Smith 
22404a2ae208SSatish Balay #undef __FUNCT__
22414a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp"
22429b94acceSBarry Smith /*@
22439b94acceSBarry Smith    SNESSetUp - Sets up the internal data structures for the later use
2244272ac6f2SLois Curfman McInnes    of a nonlinear solver.
22459b94acceSBarry Smith 
2246fee21e36SBarry Smith    Collective on SNES
2247fee21e36SBarry Smith 
2248c7afd0dbSLois Curfman McInnes    Input Parameters:
224970e92668SMatthew Knepley .  snes - the SNES context
2250c7afd0dbSLois Curfman McInnes 
2251272ac6f2SLois Curfman McInnes    Notes:
2252272ac6f2SLois Curfman McInnes    For basic use of the SNES solvers the user need not explicitly call
2253272ac6f2SLois Curfman McInnes    SNESSetUp(), since these actions will automatically occur during
2254272ac6f2SLois Curfman McInnes    the call to SNESSolve().  However, if one wishes to control this
2255272ac6f2SLois Curfman McInnes    phase separately, SNESSetUp() should be called after SNESCreate()
2256272ac6f2SLois Curfman McInnes    and optional routines of the form SNESSetXXX(), but before SNESSolve().
2257272ac6f2SLois Curfman McInnes 
225836851e7fSLois Curfman McInnes    Level: advanced
225936851e7fSLois Curfman McInnes 
22609b94acceSBarry Smith .keywords: SNES, nonlinear, setup
22619b94acceSBarry Smith 
22629b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
22639b94acceSBarry Smith @*/
22647087cfbeSBarry Smith PetscErrorCode  SNESSetUp(SNES snes)
22659b94acceSBarry Smith {
2266dfbe8321SBarry Smith   PetscErrorCode ierr;
22676cab3a1bSJed Brown   DM             dm;
22686cab3a1bSJed Brown   SNESDM         sdm;
22693a40ed3dSBarry Smith 
22703a40ed3dSBarry Smith   PetscFunctionBegin;
22710700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
22724dc4c822SBarry Smith   if (snes->setupcalled) PetscFunctionReturn(0);
22739b94acceSBarry Smith 
22747adad957SLisandro Dalcin   if (!((PetscObject)snes)->type_name) {
227585385478SLisandro Dalcin     ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr);
227685385478SLisandro Dalcin   }
227785385478SLisandro Dalcin 
2278a63bb30eSJed Brown   ierr = SNESGetFunction(snes,&snes->vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
227917186662SBarry Smith   if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
228058c9b817SLisandro Dalcin   if (snes->vec_rhs  == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector");
228158c9b817SLisandro Dalcin 
228258c9b817SLisandro Dalcin   if (!snes->vec_sol_update /* && snes->vec_sol */) {
228358c9b817SLisandro Dalcin     ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr);
228458c9b817SLisandro Dalcin     ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr);
228558c9b817SLisandro Dalcin   }
228658c9b817SLisandro Dalcin 
22876cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
22886cab3a1bSJed Brown   ierr = DMSNESSetUpLegacy(dm);CHKERRQ(ierr); /* To be removed when function routines are taken out of the DM package */
22896cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
22906cab3a1bSJed Brown   if (!sdm->computefunction) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction(), DMSNESSetFunction(), DMDASNESSetFunctionLocal(), etc");
22916cab3a1bSJed Brown   if (!snes->vec_func) {
22926cab3a1bSJed Brown     ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr);
2293214df951SJed Brown   }
2294efd51863SBarry Smith 
2295b710008aSBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);}
2296b710008aSBarry Smith 
2297f1c6b773SPeter Brune   if (!snes->linesearch) {ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);}
22989e764e56SPeter Brune 
2299d25893d9SBarry Smith   if (snes->ops->usercompute && !snes->user) {
2300d25893d9SBarry Smith     ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr);
2301d25893d9SBarry Smith   }
2302d25893d9SBarry Smith 
2303410397dcSLisandro Dalcin   if (snes->ops->setup) {
2304410397dcSLisandro Dalcin     ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr);
2305410397dcSLisandro Dalcin   }
230658c9b817SLisandro Dalcin 
23077aaed0d8SBarry Smith   snes->setupcalled = PETSC_TRUE;
23083a40ed3dSBarry Smith   PetscFunctionReturn(0);
23099b94acceSBarry Smith }
23109b94acceSBarry Smith 
23114a2ae208SSatish Balay #undef __FUNCT__
231237596af1SLisandro Dalcin #define __FUNCT__ "SNESReset"
231337596af1SLisandro Dalcin /*@
231437596af1SLisandro Dalcin    SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats
231537596af1SLisandro Dalcin 
231637596af1SLisandro Dalcin    Collective on SNES
231737596af1SLisandro Dalcin 
231837596af1SLisandro Dalcin    Input Parameter:
231937596af1SLisandro Dalcin .  snes - iterative context obtained from SNESCreate()
232037596af1SLisandro Dalcin 
2321d25893d9SBarry Smith    Level: intermediate
2322d25893d9SBarry Smith 
2323d25893d9SBarry Smith    Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext()
232437596af1SLisandro Dalcin 
232537596af1SLisandro Dalcin .keywords: SNES, destroy
232637596af1SLisandro Dalcin 
232737596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve()
232837596af1SLisandro Dalcin @*/
232937596af1SLisandro Dalcin PetscErrorCode  SNESReset(SNES snes)
233037596af1SLisandro Dalcin {
233137596af1SLisandro Dalcin   PetscErrorCode ierr;
233237596af1SLisandro Dalcin 
233337596af1SLisandro Dalcin   PetscFunctionBegin;
233437596af1SLisandro Dalcin   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2335d25893d9SBarry Smith   if (snes->ops->userdestroy && snes->user) {
2336d25893d9SBarry Smith     ierr       = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr);
2337d25893d9SBarry Smith     snes->user = PETSC_NULL;
2338d25893d9SBarry Smith   }
23398a23116dSBarry Smith   if (snes->pc) {
23408a23116dSBarry Smith     ierr = SNESReset(snes->pc);CHKERRQ(ierr);
23418a23116dSBarry Smith   }
23428a23116dSBarry Smith 
234337596af1SLisandro Dalcin   if (snes->ops->reset) {
234437596af1SLisandro Dalcin     ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr);
234537596af1SLisandro Dalcin   }
23469e764e56SPeter Brune   if (snes->ksp) {
23479e764e56SPeter Brune     ierr = KSPReset(snes->ksp);CHKERRQ(ierr);
23489e764e56SPeter Brune   }
23499e764e56SPeter Brune 
23509e764e56SPeter Brune   if (snes->linesearch) {
2351f1c6b773SPeter Brune     ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr);
23529e764e56SPeter Brune   }
23539e764e56SPeter Brune 
23546bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
23556bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
23566bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr);
23576bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
23586bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
23596bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
2360c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);
2361c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);
236237596af1SLisandro Dalcin   snes->nwork = snes->nvwork = 0;
236337596af1SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
236437596af1SLisandro Dalcin   PetscFunctionReturn(0);
236537596af1SLisandro Dalcin }
236637596af1SLisandro Dalcin 
236737596af1SLisandro Dalcin #undef __FUNCT__
23684a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy"
236952baeb72SSatish Balay /*@
23709b94acceSBarry Smith    SNESDestroy - Destroys the nonlinear solver context that was created
23719b94acceSBarry Smith    with SNESCreate().
23729b94acceSBarry Smith 
2373c7afd0dbSLois Curfman McInnes    Collective on SNES
2374c7afd0dbSLois Curfman McInnes 
23759b94acceSBarry Smith    Input Parameter:
23769b94acceSBarry Smith .  snes - the SNES context
23779b94acceSBarry Smith 
237836851e7fSLois Curfman McInnes    Level: beginner
237936851e7fSLois Curfman McInnes 
23809b94acceSBarry Smith .keywords: SNES, nonlinear, destroy
23819b94acceSBarry Smith 
238263a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve()
23839b94acceSBarry Smith @*/
23846bf464f9SBarry Smith PetscErrorCode  SNESDestroy(SNES *snes)
23859b94acceSBarry Smith {
23866849ba73SBarry Smith   PetscErrorCode ierr;
23873a40ed3dSBarry Smith 
23883a40ed3dSBarry Smith   PetscFunctionBegin;
23896bf464f9SBarry Smith   if (!*snes) PetscFunctionReturn(0);
23906bf464f9SBarry Smith   PetscValidHeaderSpecific((*snes),SNES_CLASSID,1);
23916bf464f9SBarry Smith   if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);}
2392d4bb536fSBarry Smith 
23936bf464f9SBarry Smith   ierr = SNESReset((*snes));CHKERRQ(ierr);
23948a23116dSBarry Smith   ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr);
23956b8b9a38SLisandro Dalcin 
2396be0abb6dSBarry Smith   /* if memory was published with AMS then destroy it */
23976bf464f9SBarry Smith   ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr);
23986bf464f9SBarry Smith   if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);}
23996d4c513bSLisandro Dalcin 
24006bf464f9SBarry Smith   ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr);
24016bf464f9SBarry Smith   ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr);
2402f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr);
24036b8b9a38SLisandro Dalcin 
24046bf464f9SBarry Smith   ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr);
24056bf464f9SBarry Smith   if ((*snes)->ops->convergeddestroy) {
24066bf464f9SBarry Smith     ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr);
24076b8b9a38SLisandro Dalcin   }
24086bf464f9SBarry Smith   if ((*snes)->conv_malloc) {
24096bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr);
24106bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr);
241158c9b817SLisandro Dalcin   }
24126bf464f9SBarry Smith   ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr);
2413a79aaaedSSatish Balay   ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr);
24143a40ed3dSBarry Smith  PetscFunctionReturn(0);
24159b94acceSBarry Smith }
24169b94acceSBarry Smith 
24179b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */
24189b94acceSBarry Smith 
24194a2ae208SSatish Balay #undef __FUNCT__
2420a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner"
2421a8054027SBarry Smith /*@
2422a8054027SBarry Smith    SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.
2423a8054027SBarry Smith 
24243f9fe445SBarry Smith    Logically Collective on SNES
2425a8054027SBarry Smith 
2426a8054027SBarry Smith    Input Parameters:
2427a8054027SBarry Smith +  snes - the SNES context
2428a8054027SBarry 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
24293b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2430a8054027SBarry Smith 
2431a8054027SBarry Smith    Options Database Keys:
2432a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2433a8054027SBarry Smith 
2434a8054027SBarry Smith    Notes:
2435a8054027SBarry Smith    The default is 1
2436a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2437a8054027SBarry Smith    If  -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use
2438a8054027SBarry Smith 
2439a8054027SBarry Smith    Level: intermediate
2440a8054027SBarry Smith 
2441a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2442a8054027SBarry Smith 
2443e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2444a8054027SBarry Smith 
2445a8054027SBarry Smith @*/
24467087cfbeSBarry Smith PetscErrorCode  SNESSetLagPreconditioner(SNES snes,PetscInt lag)
2447a8054027SBarry Smith {
2448a8054027SBarry Smith   PetscFunctionBegin;
24490700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2450e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2451e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2452c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2453a8054027SBarry Smith   snes->lagpreconditioner = lag;
2454a8054027SBarry Smith   PetscFunctionReturn(0);
2455a8054027SBarry Smith }
2456a8054027SBarry Smith 
2457a8054027SBarry Smith #undef __FUNCT__
2458efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence"
2459efd51863SBarry Smith /*@
2460efd51863SBarry Smith    SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does
2461efd51863SBarry Smith 
2462efd51863SBarry Smith    Logically Collective on SNES
2463efd51863SBarry Smith 
2464efd51863SBarry Smith    Input Parameters:
2465efd51863SBarry Smith +  snes - the SNES context
2466efd51863SBarry Smith -  steps - the number of refinements to do, defaults to 0
2467efd51863SBarry Smith 
2468efd51863SBarry Smith    Options Database Keys:
2469efd51863SBarry Smith .    -snes_grid_sequence <steps>
2470efd51863SBarry Smith 
2471efd51863SBarry Smith    Level: intermediate
2472efd51863SBarry Smith 
2473c0df2a02SJed Brown    Notes:
2474c0df2a02SJed Brown    Use SNESGetSolution() to extract the fine grid solution after grid sequencing.
2475c0df2a02SJed Brown 
2476efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2477efd51863SBarry Smith 
2478efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2479efd51863SBarry Smith 
2480efd51863SBarry Smith @*/
2481efd51863SBarry Smith PetscErrorCode  SNESSetGridSequence(SNES snes,PetscInt steps)
2482efd51863SBarry Smith {
2483efd51863SBarry Smith   PetscFunctionBegin;
2484efd51863SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2485efd51863SBarry Smith   PetscValidLogicalCollectiveInt(snes,steps,2);
2486efd51863SBarry Smith   snes->gridsequence = steps;
2487efd51863SBarry Smith   PetscFunctionReturn(0);
2488efd51863SBarry Smith }
2489efd51863SBarry Smith 
2490efd51863SBarry Smith #undef __FUNCT__
2491a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner"
2492a8054027SBarry Smith /*@
2493a8054027SBarry Smith    SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt
2494a8054027SBarry Smith 
24953f9fe445SBarry Smith    Not Collective
2496a8054027SBarry Smith 
2497a8054027SBarry Smith    Input Parameter:
2498a8054027SBarry Smith .  snes - the SNES context
2499a8054027SBarry Smith 
2500a8054027SBarry Smith    Output Parameter:
2501a8054027SBarry 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
25023b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2503a8054027SBarry Smith 
2504a8054027SBarry Smith    Options Database Keys:
2505a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2506a8054027SBarry Smith 
2507a8054027SBarry Smith    Notes:
2508a8054027SBarry Smith    The default is 1
2509a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2510a8054027SBarry Smith 
2511a8054027SBarry Smith    Level: intermediate
2512a8054027SBarry Smith 
2513a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2514a8054027SBarry Smith 
2515a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner()
2516a8054027SBarry Smith 
2517a8054027SBarry Smith @*/
25187087cfbeSBarry Smith PetscErrorCode  SNESGetLagPreconditioner(SNES snes,PetscInt *lag)
2519a8054027SBarry Smith {
2520a8054027SBarry Smith   PetscFunctionBegin;
25210700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2522a8054027SBarry Smith   *lag = snes->lagpreconditioner;
2523a8054027SBarry Smith   PetscFunctionReturn(0);
2524a8054027SBarry Smith }
2525a8054027SBarry Smith 
2526a8054027SBarry Smith #undef __FUNCT__
2527e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian"
2528e35cf81dSBarry Smith /*@
2529e35cf81dSBarry Smith    SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how
2530e35cf81dSBarry Smith      often the preconditioner is rebuilt.
2531e35cf81dSBarry Smith 
25323f9fe445SBarry Smith    Logically Collective on SNES
2533e35cf81dSBarry Smith 
2534e35cf81dSBarry Smith    Input Parameters:
2535e35cf81dSBarry Smith +  snes - the SNES context
2536e35cf81dSBarry 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
2537fe3ffe1eSBarry Smith          the Jacobian is built etc. -2 means rebuild at next chance but then never again
2538e35cf81dSBarry Smith 
2539e35cf81dSBarry Smith    Options Database Keys:
2540e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2541e35cf81dSBarry Smith 
2542e35cf81dSBarry Smith    Notes:
2543e35cf81dSBarry Smith    The default is 1
2544e35cf81dSBarry Smith    The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2545fe3ffe1eSBarry 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
2546fe3ffe1eSBarry Smith    at the next Newton step but never again (unless it is reset to another value)
2547e35cf81dSBarry Smith 
2548e35cf81dSBarry Smith    Level: intermediate
2549e35cf81dSBarry Smith 
2550e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2551e35cf81dSBarry Smith 
2552e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian()
2553e35cf81dSBarry Smith 
2554e35cf81dSBarry Smith @*/
25557087cfbeSBarry Smith PetscErrorCode  SNESSetLagJacobian(SNES snes,PetscInt lag)
2556e35cf81dSBarry Smith {
2557e35cf81dSBarry Smith   PetscFunctionBegin;
25580700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2559e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2560e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2561c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2562e35cf81dSBarry Smith   snes->lagjacobian = lag;
2563e35cf81dSBarry Smith   PetscFunctionReturn(0);
2564e35cf81dSBarry Smith }
2565e35cf81dSBarry Smith 
2566e35cf81dSBarry Smith #undef __FUNCT__
2567e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian"
2568e35cf81dSBarry Smith /*@
2569e35cf81dSBarry Smith    SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt
2570e35cf81dSBarry Smith 
25713f9fe445SBarry Smith    Not Collective
2572e35cf81dSBarry Smith 
2573e35cf81dSBarry Smith    Input Parameter:
2574e35cf81dSBarry Smith .  snes - the SNES context
2575e35cf81dSBarry Smith 
2576e35cf81dSBarry Smith    Output Parameter:
2577e35cf81dSBarry 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
2578e35cf81dSBarry Smith          the Jacobian is built etc.
2579e35cf81dSBarry Smith 
2580e35cf81dSBarry Smith    Options Database Keys:
2581e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2582e35cf81dSBarry Smith 
2583e35cf81dSBarry Smith    Notes:
2584e35cf81dSBarry Smith    The default is 1
2585e35cf81dSBarry Smith    The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2586e35cf81dSBarry Smith 
2587e35cf81dSBarry Smith    Level: intermediate
2588e35cf81dSBarry Smith 
2589e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2590e35cf81dSBarry Smith 
2591e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner()
2592e35cf81dSBarry Smith 
2593e35cf81dSBarry Smith @*/
25947087cfbeSBarry Smith PetscErrorCode  SNESGetLagJacobian(SNES snes,PetscInt *lag)
2595e35cf81dSBarry Smith {
2596e35cf81dSBarry Smith   PetscFunctionBegin;
25970700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2598e35cf81dSBarry Smith   *lag = snes->lagjacobian;
2599e35cf81dSBarry Smith   PetscFunctionReturn(0);
2600e35cf81dSBarry Smith }
2601e35cf81dSBarry Smith 
2602e35cf81dSBarry Smith #undef __FUNCT__
26034a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances"
26049b94acceSBarry Smith /*@
2605d7a720efSLois Curfman McInnes    SNESSetTolerances - Sets various parameters used in convergence tests.
26069b94acceSBarry Smith 
26073f9fe445SBarry Smith    Logically Collective on SNES
2608c7afd0dbSLois Curfman McInnes 
26099b94acceSBarry Smith    Input Parameters:
2610c7afd0dbSLois Curfman McInnes +  snes - the SNES context
261170441072SBarry Smith .  abstol - absolute convergence tolerance
261233174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
261333174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
261433174efeSLois Curfman McInnes            of the change in the solution between steps
261533174efeSLois Curfman McInnes .  maxit - maximum number of iterations
2616c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
2617fee21e36SBarry Smith 
261833174efeSLois Curfman McInnes    Options Database Keys:
261970441072SBarry Smith +    -snes_atol <abstol> - Sets abstol
2620c7afd0dbSLois Curfman McInnes .    -snes_rtol <rtol> - Sets rtol
2621c7afd0dbSLois Curfman McInnes .    -snes_stol <stol> - Sets stol
2622c7afd0dbSLois Curfman McInnes .    -snes_max_it <maxit> - Sets maxit
2623c7afd0dbSLois Curfman McInnes -    -snes_max_funcs <maxf> - Sets maxf
26249b94acceSBarry Smith 
2625d7a720efSLois Curfman McInnes    Notes:
26269b94acceSBarry Smith    The default maximum number of iterations is 50.
26279b94acceSBarry Smith    The default maximum number of function evaluations is 1000.
26289b94acceSBarry Smith 
262936851e7fSLois Curfman McInnes    Level: intermediate
263036851e7fSLois Curfman McInnes 
263133174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances
26329b94acceSBarry Smith 
26332492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance()
26349b94acceSBarry Smith @*/
26357087cfbeSBarry Smith PetscErrorCode  SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
26369b94acceSBarry Smith {
26373a40ed3dSBarry Smith   PetscFunctionBegin;
26380700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2639c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,abstol,2);
2640c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol,3);
2641c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,stol,4);
2642c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxit,5);
2643c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxf,6);
2644c5eb9154SBarry Smith 
2645ab54825eSJed Brown   if (abstol != PETSC_DEFAULT) {
2646ab54825eSJed Brown     if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol);
2647ab54825eSJed Brown     snes->abstol = abstol;
2648ab54825eSJed Brown   }
2649ab54825eSJed Brown   if (rtol != PETSC_DEFAULT) {
2650ab54825eSJed 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);
2651ab54825eSJed Brown     snes->rtol = rtol;
2652ab54825eSJed Brown   }
2653ab54825eSJed Brown   if (stol != PETSC_DEFAULT) {
2654ab54825eSJed Brown     if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol);
2655c60f73f4SPeter Brune     snes->stol = stol;
2656ab54825eSJed Brown   }
2657ab54825eSJed Brown   if (maxit != PETSC_DEFAULT) {
2658ab54825eSJed Brown     if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit);
2659ab54825eSJed Brown     snes->max_its = maxit;
2660ab54825eSJed Brown   }
2661ab54825eSJed Brown   if (maxf != PETSC_DEFAULT) {
2662ab54825eSJed Brown     if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf);
2663ab54825eSJed Brown     snes->max_funcs = maxf;
2664ab54825eSJed Brown   }
266588976e71SPeter Brune   snes->tolerancesset = PETSC_TRUE;
26663a40ed3dSBarry Smith   PetscFunctionReturn(0);
26679b94acceSBarry Smith }
26689b94acceSBarry Smith 
26694a2ae208SSatish Balay #undef __FUNCT__
26704a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances"
26719b94acceSBarry Smith /*@
267233174efeSLois Curfman McInnes    SNESGetTolerances - Gets various parameters used in convergence tests.
267333174efeSLois Curfman McInnes 
2674c7afd0dbSLois Curfman McInnes    Not Collective
2675c7afd0dbSLois Curfman McInnes 
267633174efeSLois Curfman McInnes    Input Parameters:
2677c7afd0dbSLois Curfman McInnes +  snes - the SNES context
267885385478SLisandro Dalcin .  atol - absolute convergence tolerance
267933174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
268033174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
268133174efeSLois Curfman McInnes            of the change in the solution between steps
268233174efeSLois Curfman McInnes .  maxit - maximum number of iterations
2683c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
2684fee21e36SBarry Smith 
268533174efeSLois Curfman McInnes    Notes:
268633174efeSLois Curfman McInnes    The user can specify PETSC_NULL for any parameter that is not needed.
268733174efeSLois Curfman McInnes 
268836851e7fSLois Curfman McInnes    Level: intermediate
268936851e7fSLois Curfman McInnes 
269033174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances
269133174efeSLois Curfman McInnes 
269233174efeSLois Curfman McInnes .seealso: SNESSetTolerances()
269333174efeSLois Curfman McInnes @*/
26947087cfbeSBarry Smith PetscErrorCode  SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
269533174efeSLois Curfman McInnes {
26963a40ed3dSBarry Smith   PetscFunctionBegin;
26970700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
269885385478SLisandro Dalcin   if (atol)  *atol  = snes->abstol;
269933174efeSLois Curfman McInnes   if (rtol)  *rtol  = snes->rtol;
2700c60f73f4SPeter Brune   if (stol)  *stol  = snes->stol;
270133174efeSLois Curfman McInnes   if (maxit) *maxit = snes->max_its;
270233174efeSLois Curfman McInnes   if (maxf)  *maxf  = snes->max_funcs;
27033a40ed3dSBarry Smith   PetscFunctionReturn(0);
270433174efeSLois Curfman McInnes }
270533174efeSLois Curfman McInnes 
27064a2ae208SSatish Balay #undef __FUNCT__
27074a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance"
270833174efeSLois Curfman McInnes /*@
27099b94acceSBarry Smith    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
27109b94acceSBarry Smith 
27113f9fe445SBarry Smith    Logically Collective on SNES
2712fee21e36SBarry Smith 
2713c7afd0dbSLois Curfman McInnes    Input Parameters:
2714c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2715c7afd0dbSLois Curfman McInnes -  tol - tolerance
2716c7afd0dbSLois Curfman McInnes 
27179b94acceSBarry Smith    Options Database Key:
2718c7afd0dbSLois Curfman McInnes .  -snes_trtol <tol> - Sets tol
27199b94acceSBarry Smith 
272036851e7fSLois Curfman McInnes    Level: intermediate
272136851e7fSLois Curfman McInnes 
27229b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance
27239b94acceSBarry Smith 
27242492ecdbSBarry Smith .seealso: SNESSetTolerances()
27259b94acceSBarry Smith @*/
27267087cfbeSBarry Smith PetscErrorCode  SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
27279b94acceSBarry Smith {
27283a40ed3dSBarry Smith   PetscFunctionBegin;
27290700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2730c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,tol,2);
27319b94acceSBarry Smith   snes->deltatol = tol;
27323a40ed3dSBarry Smith   PetscFunctionReturn(0);
27339b94acceSBarry Smith }
27349b94acceSBarry Smith 
2735df9fa365SBarry Smith /*
2736df9fa365SBarry Smith    Duplicate the lg monitors for SNES from KSP; for some reason with
2737df9fa365SBarry Smith    dynamic libraries things don't work under Sun4 if we just use
2738df9fa365SBarry Smith    macros instead of functions
2739df9fa365SBarry Smith */
27404a2ae208SSatish Balay #undef __FUNCT__
2741a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG"
27427087cfbeSBarry Smith PetscErrorCode  SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx)
2743ce1608b8SBarry Smith {
2744dfbe8321SBarry Smith   PetscErrorCode ierr;
2745ce1608b8SBarry Smith 
2746ce1608b8SBarry Smith   PetscFunctionBegin;
27470700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2748a6570f20SBarry Smith   ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr);
2749ce1608b8SBarry Smith   PetscFunctionReturn(0);
2750ce1608b8SBarry Smith }
2751ce1608b8SBarry Smith 
27524a2ae208SSatish Balay #undef __FUNCT__
2753a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate"
27547087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2755df9fa365SBarry Smith {
2756dfbe8321SBarry Smith   PetscErrorCode ierr;
2757df9fa365SBarry Smith 
2758df9fa365SBarry Smith   PetscFunctionBegin;
2759a6570f20SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2760df9fa365SBarry Smith   PetscFunctionReturn(0);
2761df9fa365SBarry Smith }
2762df9fa365SBarry Smith 
27634a2ae208SSatish Balay #undef __FUNCT__
2764a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy"
27656bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGDestroy(PetscDrawLG *draw)
2766df9fa365SBarry Smith {
2767dfbe8321SBarry Smith   PetscErrorCode ierr;
2768df9fa365SBarry Smith 
2769df9fa365SBarry Smith   PetscFunctionBegin;
2770a6570f20SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2771df9fa365SBarry Smith   PetscFunctionReturn(0);
2772df9fa365SBarry Smith }
2773df9fa365SBarry Smith 
27747087cfbeSBarry Smith extern PetscErrorCode  SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
2775b271bb04SBarry Smith #undef __FUNCT__
2776b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange"
27777087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx)
2778b271bb04SBarry Smith {
2779b271bb04SBarry Smith   PetscDrawLG      lg;
2780b271bb04SBarry Smith   PetscErrorCode   ierr;
2781b271bb04SBarry Smith   PetscReal        x,y,per;
2782b271bb04SBarry Smith   PetscViewer      v = (PetscViewer)monctx;
2783b271bb04SBarry Smith   static PetscReal prev; /* should be in the context */
2784b271bb04SBarry Smith   PetscDraw        draw;
2785b271bb04SBarry Smith   PetscFunctionBegin;
2786b271bb04SBarry Smith   if (!monctx) {
2787b271bb04SBarry Smith     MPI_Comm    comm;
2788b271bb04SBarry Smith 
2789b271bb04SBarry Smith     ierr   = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
2790b271bb04SBarry Smith     v      = PETSC_VIEWER_DRAW_(comm);
2791b271bb04SBarry Smith   }
2792b271bb04SBarry Smith   ierr   = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr);
2793b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2794b271bb04SBarry Smith   ierr   = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2795b271bb04SBarry Smith   ierr   = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr);
2796b271bb04SBarry Smith   x = (PetscReal) n;
2797b271bb04SBarry Smith   if (rnorm > 0.0) y = log10(rnorm); else y = -15.0;
2798b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2799b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2800b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2801b271bb04SBarry Smith   }
2802b271bb04SBarry Smith 
2803b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr);
2804b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2805b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2806b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr);
2807b271bb04SBarry Smith   ierr =  SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr);
2808b271bb04SBarry Smith   x = (PetscReal) n;
2809b271bb04SBarry Smith   y = 100.0*per;
2810b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2811b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2812b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2813b271bb04SBarry Smith   }
2814b271bb04SBarry Smith 
2815b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr);
2816b271bb04SBarry Smith   if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2817b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2818b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr);
2819b271bb04SBarry Smith   x = (PetscReal) n;
2820b271bb04SBarry Smith   y = (prev - rnorm)/prev;
2821b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2822b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2823b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2824b271bb04SBarry Smith   }
2825b271bb04SBarry Smith 
2826b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr);
2827b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2828b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2829b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr);
2830b271bb04SBarry Smith   x = (PetscReal) n;
2831b271bb04SBarry Smith   y = (prev - rnorm)/(prev*per);
2832b271bb04SBarry Smith   if (n > 2) { /*skip initial crazy value */
2833b271bb04SBarry Smith     ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2834b271bb04SBarry Smith   }
2835b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2836b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2837b271bb04SBarry Smith   }
2838b271bb04SBarry Smith   prev = rnorm;
2839b271bb04SBarry Smith   PetscFunctionReturn(0);
2840b271bb04SBarry Smith }
2841b271bb04SBarry Smith 
2842b271bb04SBarry Smith #undef __FUNCT__
2843b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate"
28447087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2845b271bb04SBarry Smith {
2846b271bb04SBarry Smith   PetscErrorCode ierr;
2847b271bb04SBarry Smith 
2848b271bb04SBarry Smith   PetscFunctionBegin;
2849b271bb04SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2850b271bb04SBarry Smith   PetscFunctionReturn(0);
2851b271bb04SBarry Smith }
2852b271bb04SBarry Smith 
2853b271bb04SBarry Smith #undef __FUNCT__
2854b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy"
28556bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGRangeDestroy(PetscDrawLG *draw)
2856b271bb04SBarry Smith {
2857b271bb04SBarry Smith   PetscErrorCode ierr;
2858b271bb04SBarry Smith 
2859b271bb04SBarry Smith   PetscFunctionBegin;
2860b271bb04SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2861b271bb04SBarry Smith   PetscFunctionReturn(0);
2862b271bb04SBarry Smith }
2863b271bb04SBarry Smith 
28647a03ce2fSLisandro Dalcin #undef __FUNCT__
28657a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor"
2866228d79bcSJed Brown /*@
2867228d79bcSJed Brown    SNESMonitor - runs the user provided monitor routines, if they exist
2868228d79bcSJed Brown 
2869228d79bcSJed Brown    Collective on SNES
2870228d79bcSJed Brown 
2871228d79bcSJed Brown    Input Parameters:
2872228d79bcSJed Brown +  snes - nonlinear solver context obtained from SNESCreate()
2873228d79bcSJed Brown .  iter - iteration number
2874228d79bcSJed Brown -  rnorm - relative norm of the residual
2875228d79bcSJed Brown 
2876228d79bcSJed Brown    Notes:
2877228d79bcSJed Brown    This routine is called by the SNES implementations.
2878228d79bcSJed Brown    It does not typically need to be called by the user.
2879228d79bcSJed Brown 
2880228d79bcSJed Brown    Level: developer
2881228d79bcSJed Brown 
2882228d79bcSJed Brown .seealso: SNESMonitorSet()
2883228d79bcSJed Brown @*/
28847a03ce2fSLisandro Dalcin PetscErrorCode  SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm)
28857a03ce2fSLisandro Dalcin {
28867a03ce2fSLisandro Dalcin   PetscErrorCode ierr;
28877a03ce2fSLisandro Dalcin   PetscInt       i,n = snes->numbermonitors;
28887a03ce2fSLisandro Dalcin 
28897a03ce2fSLisandro Dalcin   PetscFunctionBegin;
28907a03ce2fSLisandro Dalcin   for (i=0; i<n; i++) {
28917a03ce2fSLisandro Dalcin     ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr);
28927a03ce2fSLisandro Dalcin   }
28937a03ce2fSLisandro Dalcin   PetscFunctionReturn(0);
28947a03ce2fSLisandro Dalcin }
28957a03ce2fSLisandro Dalcin 
28969b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */
28979b94acceSBarry Smith 
28984a2ae208SSatish Balay #undef __FUNCT__
2899a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet"
29009b94acceSBarry Smith /*@C
2901a6570f20SBarry Smith    SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
29029b94acceSBarry Smith    iteration of the nonlinear solver to display the iteration's
29039b94acceSBarry Smith    progress.
29049b94acceSBarry Smith 
29053f9fe445SBarry Smith    Logically Collective on SNES
2906fee21e36SBarry Smith 
2907c7afd0dbSLois Curfman McInnes    Input Parameters:
2908c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2909c7afd0dbSLois Curfman McInnes .  func - monitoring routine
2910b8a78c4aSBarry Smith .  mctx - [optional] user-defined context for private data for the
2911e8105e01SRichard Katz           monitor routine (use PETSC_NULL if no context is desired)
2912b3006f0bSLois Curfman McInnes -  monitordestroy - [optional] routine that frees monitor context
2913b3006f0bSLois Curfman McInnes           (may be PETSC_NULL)
29149b94acceSBarry Smith 
2915c7afd0dbSLois Curfman McInnes    Calling sequence of func:
2916a7cc72afSBarry Smith $     int func(SNES snes,PetscInt its, PetscReal norm,void *mctx)
2917c7afd0dbSLois Curfman McInnes 
2918c7afd0dbSLois Curfman McInnes +    snes - the SNES context
2919c7afd0dbSLois Curfman McInnes .    its - iteration number
2920c7afd0dbSLois Curfman McInnes .    norm - 2-norm function value (may be estimated)
292140a0c1c6SLois Curfman McInnes -    mctx - [optional] monitoring context
29229b94acceSBarry Smith 
29239665c990SLois Curfman McInnes    Options Database Keys:
2924a6570f20SBarry Smith +    -snes_monitor        - sets SNESMonitorDefault()
2925a6570f20SBarry Smith .    -snes_monitor_draw    - sets line graph monitor,
2926a6570f20SBarry Smith                             uses SNESMonitorLGCreate()
2927cca6129bSJed Brown -    -snes_monitor_cancel - cancels all monitors that have
2928c7afd0dbSLois Curfman McInnes                             been hardwired into a code by
2929a6570f20SBarry Smith                             calls to SNESMonitorSet(), but
2930c7afd0dbSLois Curfman McInnes                             does not cancel those set via
2931c7afd0dbSLois Curfman McInnes                             the options database.
29329665c990SLois Curfman McInnes 
2933639f9d9dSBarry Smith    Notes:
29346bc08f3fSLois Curfman McInnes    Several different monitoring routines may be set by calling
2935a6570f20SBarry Smith    SNESMonitorSet() multiple times; all will be called in the
29366bc08f3fSLois Curfman McInnes    order in which they were set.
2937639f9d9dSBarry Smith 
2938025f1a04SBarry Smith    Fortran notes: Only a single monitor function can be set for each SNES object
2939025f1a04SBarry Smith 
294036851e7fSLois Curfman McInnes    Level: intermediate
294136851e7fSLois Curfman McInnes 
29429b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor
29439b94acceSBarry Smith 
2944a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel()
29459b94acceSBarry Smith @*/
2946c2efdce3SBarry Smith PetscErrorCode  SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
29479b94acceSBarry Smith {
2948b90d0a6eSBarry Smith   PetscInt       i;
2949649052a6SBarry Smith   PetscErrorCode ierr;
2950b90d0a6eSBarry Smith 
29513a40ed3dSBarry Smith   PetscFunctionBegin;
29520700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
295317186662SBarry Smith   if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
2954b90d0a6eSBarry Smith   for (i=0; i<snes->numbermonitors;i++) {
2955649052a6SBarry Smith     if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) {
2956649052a6SBarry Smith       if (monitordestroy) {
2957c2efdce3SBarry Smith         ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr);
2958649052a6SBarry Smith       }
2959b90d0a6eSBarry Smith       PetscFunctionReturn(0);
2960b90d0a6eSBarry Smith     }
2961b90d0a6eSBarry Smith   }
2962b90d0a6eSBarry Smith   snes->monitor[snes->numbermonitors]           = monitor;
2963b8a78c4aSBarry Smith   snes->monitordestroy[snes->numbermonitors]    = monitordestroy;
2964639f9d9dSBarry Smith   snes->monitorcontext[snes->numbermonitors++]  = (void*)mctx;
29653a40ed3dSBarry Smith   PetscFunctionReturn(0);
29669b94acceSBarry Smith }
29679b94acceSBarry Smith 
29684a2ae208SSatish Balay #undef __FUNCT__
2969a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel"
29705cd90555SBarry Smith /*@C
2971a6570f20SBarry Smith    SNESMonitorCancel - Clears all the monitor functions for a SNES object.
29725cd90555SBarry Smith 
29733f9fe445SBarry Smith    Logically Collective on SNES
2974c7afd0dbSLois Curfman McInnes 
29755cd90555SBarry Smith    Input Parameters:
29765cd90555SBarry Smith .  snes - the SNES context
29775cd90555SBarry Smith 
29781a480d89SAdministrator    Options Database Key:
2979a6570f20SBarry Smith .  -snes_monitor_cancel - cancels all monitors that have been hardwired
2980a6570f20SBarry Smith     into a code by calls to SNESMonitorSet(), but does not cancel those
2981c7afd0dbSLois Curfman McInnes     set via the options database
29825cd90555SBarry Smith 
29835cd90555SBarry Smith    Notes:
29845cd90555SBarry Smith    There is no way to clear one specific monitor from a SNES object.
29855cd90555SBarry Smith 
298636851e7fSLois Curfman McInnes    Level: intermediate
298736851e7fSLois Curfman McInnes 
29885cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor
29895cd90555SBarry Smith 
2990a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet()
29915cd90555SBarry Smith @*/
29927087cfbeSBarry Smith PetscErrorCode  SNESMonitorCancel(SNES snes)
29935cd90555SBarry Smith {
2994d952e501SBarry Smith   PetscErrorCode ierr;
2995d952e501SBarry Smith   PetscInt       i;
2996d952e501SBarry Smith 
29975cd90555SBarry Smith   PetscFunctionBegin;
29980700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2999d952e501SBarry Smith   for (i=0; i<snes->numbermonitors; i++) {
3000d952e501SBarry Smith     if (snes->monitordestroy[i]) {
30013c4aec1bSBarry Smith       ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr);
3002d952e501SBarry Smith     }
3003d952e501SBarry Smith   }
30045cd90555SBarry Smith   snes->numbermonitors = 0;
30055cd90555SBarry Smith   PetscFunctionReturn(0);
30065cd90555SBarry Smith }
30075cd90555SBarry Smith 
30084a2ae208SSatish Balay #undef __FUNCT__
30094a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest"
30109b94acceSBarry Smith /*@C
30119b94acceSBarry Smith    SNESSetConvergenceTest - Sets the function that is to be used
30129b94acceSBarry Smith    to test for convergence of the nonlinear iterative solution.
30139b94acceSBarry Smith 
30143f9fe445SBarry Smith    Logically Collective on SNES
3015fee21e36SBarry Smith 
3016c7afd0dbSLois Curfman McInnes    Input Parameters:
3017c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3018c7afd0dbSLois Curfman McInnes .  func - routine to test for convergence
30197f7931b9SBarry Smith .  cctx - [optional] context for private data for the convergence routine  (may be PETSC_NULL)
30207f7931b9SBarry Smith -  destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran)
30219b94acceSBarry Smith 
3022c7afd0dbSLois Curfman McInnes    Calling sequence of func:
302306ee9f85SBarry Smith $     PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
3024c7afd0dbSLois Curfman McInnes 
3025c7afd0dbSLois Curfman McInnes +    snes - the SNES context
302606ee9f85SBarry Smith .    it - current iteration (0 is the first and is before any Newton step)
3027c7afd0dbSLois Curfman McInnes .    cctx - [optional] convergence context
3028184914b5SBarry Smith .    reason - reason for convergence/divergence
3029c7afd0dbSLois Curfman McInnes .    xnorm - 2-norm of current iterate
30304b27c08aSLois Curfman McInnes .    gnorm - 2-norm of current step
30314b27c08aSLois Curfman McInnes -    f - 2-norm of function
30329b94acceSBarry Smith 
303336851e7fSLois Curfman McInnes    Level: advanced
303436851e7fSLois Curfman McInnes 
30359b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test
30369b94acceSBarry Smith 
303785385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged()
30389b94acceSBarry Smith @*/
30397087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
30409b94acceSBarry Smith {
30417f7931b9SBarry Smith   PetscErrorCode ierr;
30427f7931b9SBarry Smith 
30433a40ed3dSBarry Smith   PetscFunctionBegin;
30440700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
304585385478SLisandro Dalcin   if (!func) func = SNESSkipConverged;
30467f7931b9SBarry Smith   if (snes->ops->convergeddestroy) {
30477f7931b9SBarry Smith     ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr);
30487f7931b9SBarry Smith   }
304985385478SLisandro Dalcin   snes->ops->converged        = func;
30507f7931b9SBarry Smith   snes->ops->convergeddestroy = destroy;
305185385478SLisandro Dalcin   snes->cnvP                  = cctx;
30523a40ed3dSBarry Smith   PetscFunctionReturn(0);
30539b94acceSBarry Smith }
30549b94acceSBarry Smith 
30554a2ae208SSatish Balay #undef __FUNCT__
30564a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason"
305752baeb72SSatish Balay /*@
3058184914b5SBarry Smith    SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
3059184914b5SBarry Smith 
3060184914b5SBarry Smith    Not Collective
3061184914b5SBarry Smith 
3062184914b5SBarry Smith    Input Parameter:
3063184914b5SBarry Smith .  snes - the SNES context
3064184914b5SBarry Smith 
3065184914b5SBarry Smith    Output Parameter:
30664d0a8057SBarry Smith .  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
3067184914b5SBarry Smith             manual pages for the individual convergence tests for complete lists
3068184914b5SBarry Smith 
3069184914b5SBarry Smith    Level: intermediate
3070184914b5SBarry Smith 
3071184914b5SBarry Smith    Notes: Can only be called after the call the SNESSolve() is complete.
3072184914b5SBarry Smith 
3073184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test
3074184914b5SBarry Smith 
307585385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason
3076184914b5SBarry Smith @*/
30777087cfbeSBarry Smith PetscErrorCode  SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
3078184914b5SBarry Smith {
3079184914b5SBarry Smith   PetscFunctionBegin;
30800700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
30814482741eSBarry Smith   PetscValidPointer(reason,2);
3082184914b5SBarry Smith   *reason = snes->reason;
3083184914b5SBarry Smith   PetscFunctionReturn(0);
3084184914b5SBarry Smith }
3085184914b5SBarry Smith 
30864a2ae208SSatish Balay #undef __FUNCT__
30874a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory"
3088c9005455SLois Curfman McInnes /*@
3089c9005455SLois Curfman McInnes    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
3090c9005455SLois Curfman McInnes 
30913f9fe445SBarry Smith    Logically Collective on SNES
3092fee21e36SBarry Smith 
3093c7afd0dbSLois Curfman McInnes    Input Parameters:
3094c7afd0dbSLois Curfman McInnes +  snes - iterative context obtained from SNESCreate()
30958c7482ecSBarry Smith .  a   - array to hold history, this array will contain the function norms computed at each step
3096cd5578b5SBarry Smith .  its - integer array holds the number of linear iterations for each solve.
3097758f92a0SBarry Smith .  na  - size of a and its
309864731454SLois Curfman McInnes -  reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
3099758f92a0SBarry Smith            else it continues storing new values for new nonlinear solves after the old ones
3100c7afd0dbSLois Curfman McInnes 
3101308dcc3eSBarry Smith    Notes:
3102308dcc3eSBarry Smith    If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a
3103308dcc3eSBarry Smith    default array of length 10000 is allocated.
3104308dcc3eSBarry Smith 
3105c9005455SLois Curfman McInnes    This routine is useful, e.g., when running a code for purposes
3106c9005455SLois Curfman McInnes    of accurate performance monitoring, when no I/O should be done
3107c9005455SLois Curfman McInnes    during the section of code that is being timed.
3108c9005455SLois Curfman McInnes 
310936851e7fSLois Curfman McInnes    Level: intermediate
311036851e7fSLois Curfman McInnes 
3111c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history
3112758f92a0SBarry Smith 
311308405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory()
3114758f92a0SBarry Smith 
3115c9005455SLois Curfman McInnes @*/
31167087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool  reset)
3117c9005455SLois Curfman McInnes {
3118308dcc3eSBarry Smith   PetscErrorCode ierr;
3119308dcc3eSBarry Smith 
31203a40ed3dSBarry Smith   PetscFunctionBegin;
31210700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
31224482741eSBarry Smith   if (na)  PetscValidScalarPointer(a,2);
3123a562a398SLisandro Dalcin   if (its) PetscValidIntPointer(its,3);
3124308dcc3eSBarry Smith   if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) {
3125308dcc3eSBarry Smith     if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
3126308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr);
3127308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr);
3128308dcc3eSBarry Smith     snes->conv_malloc   = PETSC_TRUE;
3129308dcc3eSBarry Smith   }
3130c9005455SLois Curfman McInnes   snes->conv_hist       = a;
3131758f92a0SBarry Smith   snes->conv_hist_its   = its;
3132758f92a0SBarry Smith   snes->conv_hist_max   = na;
3133a12bc48fSLisandro Dalcin   snes->conv_hist_len   = 0;
3134758f92a0SBarry Smith   snes->conv_hist_reset = reset;
3135758f92a0SBarry Smith   PetscFunctionReturn(0);
3136758f92a0SBarry Smith }
3137758f92a0SBarry Smith 
3138308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3139c6db04a5SJed Brown #include <engine.h>   /* MATLAB include file */
3140c6db04a5SJed Brown #include <mex.h>      /* MATLAB include file */
3141308dcc3eSBarry Smith EXTERN_C_BEGIN
3142308dcc3eSBarry Smith #undef __FUNCT__
3143308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab"
3144308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes)
3145308dcc3eSBarry Smith {
3146308dcc3eSBarry Smith   mxArray        *mat;
3147308dcc3eSBarry Smith   PetscInt       i;
3148308dcc3eSBarry Smith   PetscReal      *ar;
3149308dcc3eSBarry Smith 
3150308dcc3eSBarry Smith   PetscFunctionBegin;
3151308dcc3eSBarry Smith   mat  = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL);
3152308dcc3eSBarry Smith   ar   = (PetscReal*) mxGetData(mat);
3153308dcc3eSBarry Smith   for (i=0; i<snes->conv_hist_len; i++) {
3154308dcc3eSBarry Smith     ar[i] = snes->conv_hist[i];
3155308dcc3eSBarry Smith   }
3156308dcc3eSBarry Smith   PetscFunctionReturn(mat);
3157308dcc3eSBarry Smith }
3158308dcc3eSBarry Smith EXTERN_C_END
3159308dcc3eSBarry Smith #endif
3160308dcc3eSBarry Smith 
3161308dcc3eSBarry Smith 
31624a2ae208SSatish Balay #undef __FUNCT__
31634a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory"
31640c4c9dddSBarry Smith /*@C
3165758f92a0SBarry Smith    SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
3166758f92a0SBarry Smith 
31673f9fe445SBarry Smith    Not Collective
3168758f92a0SBarry Smith 
3169758f92a0SBarry Smith    Input Parameter:
3170758f92a0SBarry Smith .  snes - iterative context obtained from SNESCreate()
3171758f92a0SBarry Smith 
3172758f92a0SBarry Smith    Output Parameters:
3173758f92a0SBarry Smith .  a   - array to hold history
3174758f92a0SBarry Smith .  its - integer array holds the number of linear iterations (or
3175758f92a0SBarry Smith          negative if not converged) for each solve.
3176758f92a0SBarry Smith -  na  - size of a and its
3177758f92a0SBarry Smith 
3178758f92a0SBarry Smith    Notes:
3179758f92a0SBarry Smith     The calling sequence for this routine in Fortran is
3180758f92a0SBarry Smith $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
3181758f92a0SBarry Smith 
3182758f92a0SBarry Smith    This routine is useful, e.g., when running a code for purposes
3183758f92a0SBarry Smith    of accurate performance monitoring, when no I/O should be done
3184758f92a0SBarry Smith    during the section of code that is being timed.
3185758f92a0SBarry Smith 
3186758f92a0SBarry Smith    Level: intermediate
3187758f92a0SBarry Smith 
3188758f92a0SBarry Smith .keywords: SNES, get, convergence, history
3189758f92a0SBarry Smith 
3190758f92a0SBarry Smith .seealso: SNESSetConvergencHistory()
3191758f92a0SBarry Smith 
3192758f92a0SBarry Smith @*/
31937087cfbeSBarry Smith PetscErrorCode  SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
3194758f92a0SBarry Smith {
3195758f92a0SBarry Smith   PetscFunctionBegin;
31960700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3197758f92a0SBarry Smith   if (a)   *a   = snes->conv_hist;
3198758f92a0SBarry Smith   if (its) *its = snes->conv_hist_its;
3199758f92a0SBarry Smith   if (na)  *na  = snes->conv_hist_len;
32003a40ed3dSBarry Smith   PetscFunctionReturn(0);
3201c9005455SLois Curfman McInnes }
3202c9005455SLois Curfman McInnes 
3203e74ef692SMatthew Knepley #undef __FUNCT__
3204e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate"
3205ac226902SBarry Smith /*@C
320676b2cf59SMatthew Knepley   SNESSetUpdate - Sets the general-purpose update function called
3207eec8f646SJed Brown   at the beginning of every iteration of the nonlinear solve. Specifically
32087e4bb74cSBarry Smith   it is called just before the Jacobian is "evaluated".
320976b2cf59SMatthew Knepley 
32103f9fe445SBarry Smith   Logically Collective on SNES
321176b2cf59SMatthew Knepley 
321276b2cf59SMatthew Knepley   Input Parameters:
321376b2cf59SMatthew Knepley . snes - The nonlinear solver context
321476b2cf59SMatthew Knepley . func - The function
321576b2cf59SMatthew Knepley 
321676b2cf59SMatthew Knepley   Calling sequence of func:
3217b5d30489SBarry Smith . func (SNES snes, PetscInt step);
321876b2cf59SMatthew Knepley 
321976b2cf59SMatthew Knepley . step - The current step of the iteration
322076b2cf59SMatthew Knepley 
3221fe97e370SBarry Smith   Level: advanced
3222fe97e370SBarry Smith 
3223fe97e370SBarry 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()
3224fe97e370SBarry Smith         This is not used by most users.
322576b2cf59SMatthew Knepley 
322676b2cf59SMatthew Knepley .keywords: SNES, update
3227b5d30489SBarry Smith 
322885385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve()
322976b2cf59SMatthew Knepley @*/
32307087cfbeSBarry Smith PetscErrorCode  SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
323176b2cf59SMatthew Knepley {
323276b2cf59SMatthew Knepley   PetscFunctionBegin;
32330700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID,1);
3234e7788613SBarry Smith   snes->ops->update = func;
323576b2cf59SMatthew Knepley   PetscFunctionReturn(0);
323676b2cf59SMatthew Knepley }
323776b2cf59SMatthew Knepley 
3238e74ef692SMatthew Knepley #undef __FUNCT__
3239e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate"
324076b2cf59SMatthew Knepley /*@
324176b2cf59SMatthew Knepley   SNESDefaultUpdate - The default update function which does nothing.
324276b2cf59SMatthew Knepley 
324376b2cf59SMatthew Knepley   Not collective
324476b2cf59SMatthew Knepley 
324576b2cf59SMatthew Knepley   Input Parameters:
324676b2cf59SMatthew Knepley . snes - The nonlinear solver context
324776b2cf59SMatthew Knepley . step - The current step of the iteration
324876b2cf59SMatthew Knepley 
3249205452f4SMatthew Knepley   Level: intermediate
3250205452f4SMatthew Knepley 
325176b2cf59SMatthew Knepley .keywords: SNES, update
3252a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC()
325376b2cf59SMatthew Knepley @*/
32547087cfbeSBarry Smith PetscErrorCode  SNESDefaultUpdate(SNES snes, PetscInt step)
325576b2cf59SMatthew Knepley {
325676b2cf59SMatthew Knepley   PetscFunctionBegin;
325776b2cf59SMatthew Knepley   PetscFunctionReturn(0);
325876b2cf59SMatthew Knepley }
325976b2cf59SMatthew Knepley 
32604a2ae208SSatish Balay #undef __FUNCT__
32614a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private"
32629b94acceSBarry Smith /*
32639b94acceSBarry Smith    SNESScaleStep_Private - Scales a step so that its length is less than the
32649b94acceSBarry Smith    positive parameter delta.
32659b94acceSBarry Smith 
32669b94acceSBarry Smith     Input Parameters:
3267c7afd0dbSLois Curfman McInnes +   snes - the SNES context
32689b94acceSBarry Smith .   y - approximate solution of linear system
32699b94acceSBarry Smith .   fnorm - 2-norm of current function
3270c7afd0dbSLois Curfman McInnes -   delta - trust region size
32719b94acceSBarry Smith 
32729b94acceSBarry Smith     Output Parameters:
3273c7afd0dbSLois Curfman McInnes +   gpnorm - predicted function norm at the new point, assuming local
32749b94acceSBarry Smith     linearization.  The value is zero if the step lies within the trust
32759b94acceSBarry Smith     region, and exceeds zero otherwise.
3276c7afd0dbSLois Curfman McInnes -   ynorm - 2-norm of the step
32779b94acceSBarry Smith 
32789b94acceSBarry Smith     Note:
32794b27c08aSLois Curfman McInnes     For non-trust region methods such as SNESLS, the parameter delta
32809b94acceSBarry Smith     is set to be the maximum allowable step size.
32819b94acceSBarry Smith 
32829b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step
32839b94acceSBarry Smith */
3284dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
32859b94acceSBarry Smith {
3286064f8208SBarry Smith   PetscReal      nrm;
3287ea709b57SSatish Balay   PetscScalar    cnorm;
3288dfbe8321SBarry Smith   PetscErrorCode ierr;
32893a40ed3dSBarry Smith 
32903a40ed3dSBarry Smith   PetscFunctionBegin;
32910700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
32920700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3293c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,2);
3294184914b5SBarry Smith 
3295064f8208SBarry Smith   ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr);
3296064f8208SBarry Smith   if (nrm > *delta) {
3297064f8208SBarry Smith      nrm = *delta/nrm;
3298064f8208SBarry Smith      *gpnorm = (1.0 - nrm)*(*fnorm);
3299064f8208SBarry Smith      cnorm = nrm;
33002dcb1b2aSMatthew Knepley      ierr = VecScale(y,cnorm);CHKERRQ(ierr);
33019b94acceSBarry Smith      *ynorm = *delta;
33029b94acceSBarry Smith   } else {
33039b94acceSBarry Smith      *gpnorm = 0.0;
3304064f8208SBarry Smith      *ynorm = nrm;
33059b94acceSBarry Smith   }
33063a40ed3dSBarry Smith   PetscFunctionReturn(0);
33079b94acceSBarry Smith }
33089b94acceSBarry Smith 
33094a2ae208SSatish Balay #undef __FUNCT__
33104a2ae208SSatish Balay #define __FUNCT__ "SNESSolve"
33116ce558aeSBarry Smith /*@C
3312f69a0ea3SMatthew Knepley    SNESSolve - Solves a nonlinear system F(x) = b.
3313f69a0ea3SMatthew Knepley    Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
33149b94acceSBarry Smith 
3315c7afd0dbSLois Curfman McInnes    Collective on SNES
3316c7afd0dbSLois Curfman McInnes 
3317b2002411SLois Curfman McInnes    Input Parameters:
3318c7afd0dbSLois Curfman McInnes +  snes - the SNES context
33193cebf274SJed Brown .  b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero.
332085385478SLisandro Dalcin -  x - the solution vector.
33219b94acceSBarry Smith 
3322b2002411SLois Curfman McInnes    Notes:
33238ddd3da0SLois Curfman McInnes    The user should initialize the vector,x, with the initial guess
33248ddd3da0SLois Curfman McInnes    for the nonlinear solve prior to calling SNESSolve.  In particular,
33258ddd3da0SLois Curfman McInnes    to employ an initial guess of zero, the user should explicitly set
33268ddd3da0SLois Curfman McInnes    this vector to zero by calling VecSet().
33278ddd3da0SLois Curfman McInnes 
332836851e7fSLois Curfman McInnes    Level: beginner
332936851e7fSLois Curfman McInnes 
33309b94acceSBarry Smith .keywords: SNES, nonlinear, solve
33319b94acceSBarry Smith 
3332c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution()
33339b94acceSBarry Smith @*/
33347087cfbeSBarry Smith PetscErrorCode  SNESSolve(SNES snes,Vec b,Vec x)
33359b94acceSBarry Smith {
3336dfbe8321SBarry Smith   PetscErrorCode ierr;
3337ace3abfcSBarry Smith   PetscBool      flg;
3338eabae89aSBarry Smith   char           filename[PETSC_MAX_PATH_LEN];
3339eabae89aSBarry Smith   PetscViewer    viewer;
3340efd51863SBarry Smith   PetscInt       grid;
3341a69afd8bSBarry Smith   Vec            xcreated = PETSC_NULL;
3342caa4e7f2SJed Brown   DM             dm;
3343052efed2SBarry Smith 
33443a40ed3dSBarry Smith   PetscFunctionBegin;
33450700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3346a69afd8bSBarry Smith   if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3347a69afd8bSBarry Smith   if (x) PetscCheckSameComm(snes,1,x,3);
33480700a824SBarry Smith   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2);
334985385478SLisandro Dalcin   if (b) PetscCheckSameComm(snes,1,b,2);
335085385478SLisandro Dalcin 
3351caa4e7f2SJed Brown   if (!x) {
3352caa4e7f2SJed Brown     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3353caa4e7f2SJed Brown     ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr);
3354a69afd8bSBarry Smith     x    = xcreated;
3355a69afd8bSBarry Smith   }
3356a69afd8bSBarry Smith 
3357a8248277SBarry Smith   for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);}
3358efd51863SBarry Smith   for (grid=0; grid<snes->gridsequence+1; grid++) {
3359efd51863SBarry Smith 
336085385478SLisandro Dalcin     /* set solution vector */
3361efd51863SBarry Smith     if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);}
33626bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
336385385478SLisandro Dalcin     snes->vec_sol = x;
3364caa4e7f2SJed Brown     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3365caa4e7f2SJed Brown 
3366caa4e7f2SJed Brown     /* set affine vector if provided */
336785385478SLisandro Dalcin     if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); }
33686bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
336985385478SLisandro Dalcin     snes->vec_rhs = b;
337085385478SLisandro Dalcin 
337170e92668SMatthew Knepley     ierr = SNESSetUp(snes);CHKERRQ(ierr);
33723f149594SLisandro Dalcin 
33737eee914bSBarry Smith     if (!grid) {
33747eee914bSBarry Smith       if (snes->ops->computeinitialguess) {
3375d25893d9SBarry Smith         ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr);
3376dd568438SSatish Balay       } else if (snes->dm) {
3377dd568438SSatish Balay         PetscBool ig;
3378dd568438SSatish Balay         ierr = DMHasInitialGuess(snes->dm,&ig);CHKERRQ(ierr);
3379dd568438SSatish Balay         if (ig) {
33807eee914bSBarry Smith           ierr = DMComputeInitialGuess(snes->dm,snes->vec_sol);CHKERRQ(ierr);
33817eee914bSBarry Smith         }
3382d25893d9SBarry Smith       }
3383dd568438SSatish Balay     }
3384d25893d9SBarry Smith 
3385abc0a331SBarry Smith     if (snes->conv_hist_reset) snes->conv_hist_len = 0;
338650ffb88aSMatthew Knepley     snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;
3387d5e45103SBarry Smith 
33883f149594SLisandro Dalcin     ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
33894936397dSBarry Smith     ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr);
339085385478SLisandro Dalcin     ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
33914936397dSBarry Smith     if (snes->domainerror){
33924936397dSBarry Smith       snes->reason      = SNES_DIVERGED_FUNCTION_DOMAIN;
33934936397dSBarry Smith       snes->domainerror = PETSC_FALSE;
33944936397dSBarry Smith     }
339517186662SBarry Smith     if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
33963f149594SLisandro Dalcin 
33977adad957SLisandro Dalcin     ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
3398eabae89aSBarry Smith     if (flg && !PetscPreLoadingOn) {
33997adad957SLisandro Dalcin       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr);
3400eabae89aSBarry Smith       ierr = SNESView(snes,viewer);CHKERRQ(ierr);
34016bf464f9SBarry Smith       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
3402eabae89aSBarry Smith     }
3403eabae89aSBarry Smith 
340490d69ab7SBarry Smith     flg  = PETSC_FALSE;
3405acfcf0e5SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr);
3406da9b6338SBarry Smith     if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); }
34075968eb51SBarry Smith     if (snes->printreason) {
3408a8248277SBarry Smith       ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
34095968eb51SBarry Smith       if (snes->reason > 0) {
3410c7e7b494SJed 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);
34115968eb51SBarry Smith       } else {
3412c7e7b494SJed 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);
34135968eb51SBarry Smith       }
3414a8248277SBarry Smith       ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
34155968eb51SBarry Smith     }
34165968eb51SBarry Smith 
34178501fc72SJed Brown     flg = PETSC_FALSE;
34188501fc72SJed Brown     ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
34198501fc72SJed Brown     if (flg) {
34208501fc72SJed Brown       PetscViewer viewer;
34218501fc72SJed Brown       ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr);
34228501fc72SJed Brown       ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr);
34238501fc72SJed Brown       ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr);
34248501fc72SJed Brown       ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr);
34258501fc72SJed Brown       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
34268501fc72SJed Brown     }
34278501fc72SJed Brown 
3428e113a28aSBarry Smith     if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged");
3429efd51863SBarry Smith     if (grid <  snes->gridsequence) {
3430efd51863SBarry Smith       DM  fine;
3431efd51863SBarry Smith       Vec xnew;
3432efd51863SBarry Smith       Mat interp;
3433efd51863SBarry Smith 
3434efd51863SBarry Smith       ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr);
3435c5c77316SJed Brown       if (!fine) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing");
3436e727c939SJed Brown       ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr);
3437efd51863SBarry Smith       ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr);
3438efd51863SBarry Smith       ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr);
3439efd51863SBarry Smith       ierr = MatDestroy(&interp);CHKERRQ(ierr);
3440efd51863SBarry Smith       x    = xnew;
3441efd51863SBarry Smith 
3442efd51863SBarry Smith       ierr = SNESReset(snes);CHKERRQ(ierr);
3443efd51863SBarry Smith       ierr = SNESSetDM(snes,fine);CHKERRQ(ierr);
3444efd51863SBarry Smith       ierr = DMDestroy(&fine);CHKERRQ(ierr);
3445a8248277SBarry Smith       ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);
3446efd51863SBarry Smith     }
3447efd51863SBarry Smith   }
3448a69afd8bSBarry Smith   ierr = VecDestroy(&xcreated);CHKERRQ(ierr);
34493a40ed3dSBarry Smith   PetscFunctionReturn(0);
34509b94acceSBarry Smith }
34519b94acceSBarry Smith 
34529b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */
34539b94acceSBarry Smith 
34544a2ae208SSatish Balay #undef __FUNCT__
34554a2ae208SSatish Balay #define __FUNCT__ "SNESSetType"
345682bf6240SBarry Smith /*@C
34574b0e389bSBarry Smith    SNESSetType - Sets the method for the nonlinear solver.
34589b94acceSBarry Smith 
3459fee21e36SBarry Smith    Collective on SNES
3460fee21e36SBarry Smith 
3461c7afd0dbSLois Curfman McInnes    Input Parameters:
3462c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3463454a90a3SBarry Smith -  type - a known method
3464c7afd0dbSLois Curfman McInnes 
3465c7afd0dbSLois Curfman McInnes    Options Database Key:
3466454a90a3SBarry Smith .  -snes_type <type> - Sets the method; use -help for a list
3467c7afd0dbSLois Curfman McInnes    of available methods (for instance, ls or tr)
3468ae12b187SLois Curfman McInnes 
34699b94acceSBarry Smith    Notes:
3470e090d566SSatish Balay    See "petsc/include/petscsnes.h" for available methods (for instance)
34714b27c08aSLois Curfman McInnes +    SNESLS - Newton's method with line search
3472c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
34734b27c08aSLois Curfman McInnes .    SNESTR - Newton's method with trust region
3474c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
34759b94acceSBarry Smith 
3476ae12b187SLois Curfman McInnes   Normally, it is best to use the SNESSetFromOptions() command and then
3477ae12b187SLois Curfman McInnes   set the SNES solver type from the options database rather than by using
3478ae12b187SLois Curfman McInnes   this routine.  Using the options database provides the user with
3479ae12b187SLois Curfman McInnes   maximum flexibility in evaluating the many nonlinear solvers.
3480ae12b187SLois Curfman McInnes   The SNESSetType() routine is provided for those situations where it
3481ae12b187SLois Curfman McInnes   is necessary to set the nonlinear solver independently of the command
3482ae12b187SLois Curfman McInnes   line or options database.  This might be the case, for example, when
3483ae12b187SLois Curfman McInnes   the choice of solver changes during the execution of the program,
3484ae12b187SLois Curfman McInnes   and the user's application is taking responsibility for choosing the
3485b0a32e0cSBarry Smith   appropriate method.
348636851e7fSLois Curfman McInnes 
348736851e7fSLois Curfman McInnes   Level: intermediate
3488a703fe33SLois Curfman McInnes 
3489454a90a3SBarry Smith .keywords: SNES, set, type
3490435da068SBarry Smith 
3491435da068SBarry Smith .seealso: SNESType, SNESCreate()
3492435da068SBarry Smith 
34939b94acceSBarry Smith @*/
34947087cfbeSBarry Smith PetscErrorCode  SNESSetType(SNES snes,const SNESType type)
34959b94acceSBarry Smith {
3496dfbe8321SBarry Smith   PetscErrorCode ierr,(*r)(SNES);
3497ace3abfcSBarry Smith   PetscBool      match;
34983a40ed3dSBarry Smith 
34993a40ed3dSBarry Smith   PetscFunctionBegin;
35000700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
35014482741eSBarry Smith   PetscValidCharPointer(type,2);
350282bf6240SBarry Smith 
35036831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr);
35040f5bd95cSBarry Smith   if (match) PetscFunctionReturn(0);
350592ff6ae8SBarry Smith 
35064b91b6eaSBarry Smith   ierr =  PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr);
3507e32f2f54SBarry Smith   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
350875396ef9SLisandro Dalcin   /* Destroy the previous private SNES context */
3509b5c23020SJed Brown   if (snes->ops->destroy) {
3510b5c23020SJed Brown     ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr);
3511b5c23020SJed Brown     snes->ops->destroy = PETSC_NULL;
3512b5c23020SJed Brown   }
351375396ef9SLisandro Dalcin   /* Reinitialize function pointers in SNESOps structure */
351475396ef9SLisandro Dalcin   snes->ops->setup          = 0;
351575396ef9SLisandro Dalcin   snes->ops->solve          = 0;
351675396ef9SLisandro Dalcin   snes->ops->view           = 0;
351775396ef9SLisandro Dalcin   snes->ops->setfromoptions = 0;
351875396ef9SLisandro Dalcin   snes->ops->destroy        = 0;
351975396ef9SLisandro Dalcin   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
352075396ef9SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
3521454a90a3SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr);
352203bfa161SLisandro Dalcin   ierr = (*r)(snes);CHKERRQ(ierr);
35239fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS)
35249fb22e1aSBarry Smith   if (PetscAMSPublishAll) {
35259fb22e1aSBarry Smith     ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr);
35269fb22e1aSBarry Smith   }
35279fb22e1aSBarry Smith #endif
35283a40ed3dSBarry Smith   PetscFunctionReturn(0);
35299b94acceSBarry Smith }
35309b94acceSBarry Smith 
3531a847f771SSatish Balay 
35329b94acceSBarry Smith /* --------------------------------------------------------------------- */
35334a2ae208SSatish Balay #undef __FUNCT__
35344a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy"
353552baeb72SSatish Balay /*@
35369b94acceSBarry Smith    SNESRegisterDestroy - Frees the list of nonlinear solvers that were
3537f1af5d2fSBarry Smith    registered by SNESRegisterDynamic().
35389b94acceSBarry Smith 
3539fee21e36SBarry Smith    Not Collective
3540fee21e36SBarry Smith 
354136851e7fSLois Curfman McInnes    Level: advanced
354236851e7fSLois Curfman McInnes 
35439b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy
35449b94acceSBarry Smith 
35459b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll()
35469b94acceSBarry Smith @*/
35477087cfbeSBarry Smith PetscErrorCode  SNESRegisterDestroy(void)
35489b94acceSBarry Smith {
3549dfbe8321SBarry Smith   PetscErrorCode ierr;
355082bf6240SBarry Smith 
35513a40ed3dSBarry Smith   PetscFunctionBegin;
35521441b1d3SBarry Smith   ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr);
35534c49b128SBarry Smith   SNESRegisterAllCalled = PETSC_FALSE;
35543a40ed3dSBarry Smith   PetscFunctionReturn(0);
35559b94acceSBarry Smith }
35569b94acceSBarry Smith 
35574a2ae208SSatish Balay #undef __FUNCT__
35584a2ae208SSatish Balay #define __FUNCT__ "SNESGetType"
35599b94acceSBarry Smith /*@C
35609a28b0a6SLois Curfman McInnes    SNESGetType - Gets the SNES method type and name (as a string).
35619b94acceSBarry Smith 
3562c7afd0dbSLois Curfman McInnes    Not Collective
3563c7afd0dbSLois Curfman McInnes 
35649b94acceSBarry Smith    Input Parameter:
35654b0e389bSBarry Smith .  snes - nonlinear solver context
35669b94acceSBarry Smith 
35679b94acceSBarry Smith    Output Parameter:
35683a7fca6bSBarry Smith .  type - SNES method (a character string)
35699b94acceSBarry Smith 
357036851e7fSLois Curfman McInnes    Level: intermediate
357136851e7fSLois Curfman McInnes 
3572454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name
35739b94acceSBarry Smith @*/
35747087cfbeSBarry Smith PetscErrorCode  SNESGetType(SNES snes,const SNESType *type)
35759b94acceSBarry Smith {
35763a40ed3dSBarry Smith   PetscFunctionBegin;
35770700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
35784482741eSBarry Smith   PetscValidPointer(type,2);
35797adad957SLisandro Dalcin   *type = ((PetscObject)snes)->type_name;
35803a40ed3dSBarry Smith   PetscFunctionReturn(0);
35819b94acceSBarry Smith }
35829b94acceSBarry Smith 
35834a2ae208SSatish Balay #undef __FUNCT__
35844a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution"
358552baeb72SSatish Balay /*@
35869b94acceSBarry Smith    SNESGetSolution - Returns the vector where the approximate solution is
3587c0df2a02SJed Brown    stored. This is the fine grid solution when using SNESSetGridSequence().
35889b94acceSBarry Smith 
3589c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3590c7afd0dbSLois Curfman McInnes 
35919b94acceSBarry Smith    Input Parameter:
35929b94acceSBarry Smith .  snes - the SNES context
35939b94acceSBarry Smith 
35949b94acceSBarry Smith    Output Parameter:
35959b94acceSBarry Smith .  x - the solution
35969b94acceSBarry Smith 
359770e92668SMatthew Knepley    Level: intermediate
359836851e7fSLois Curfman McInnes 
35999b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution
36009b94acceSBarry Smith 
360185385478SLisandro Dalcin .seealso:  SNESGetSolutionUpdate(), SNESGetFunction()
36029b94acceSBarry Smith @*/
36037087cfbeSBarry Smith PetscErrorCode  SNESGetSolution(SNES snes,Vec *x)
36049b94acceSBarry Smith {
36053a40ed3dSBarry Smith   PetscFunctionBegin;
36060700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
36074482741eSBarry Smith   PetscValidPointer(x,2);
360885385478SLisandro Dalcin   *x = snes->vec_sol;
360970e92668SMatthew Knepley   PetscFunctionReturn(0);
361070e92668SMatthew Knepley }
361170e92668SMatthew Knepley 
361270e92668SMatthew Knepley #undef __FUNCT__
36134a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate"
361452baeb72SSatish Balay /*@
36159b94acceSBarry Smith    SNESGetSolutionUpdate - Returns the vector where the solution update is
36169b94acceSBarry Smith    stored.
36179b94acceSBarry Smith 
3618c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3619c7afd0dbSLois Curfman McInnes 
36209b94acceSBarry Smith    Input Parameter:
36219b94acceSBarry Smith .  snes - the SNES context
36229b94acceSBarry Smith 
36239b94acceSBarry Smith    Output Parameter:
36249b94acceSBarry Smith .  x - the solution update
36259b94acceSBarry Smith 
362636851e7fSLois Curfman McInnes    Level: advanced
362736851e7fSLois Curfman McInnes 
36289b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update
36299b94acceSBarry Smith 
363085385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction()
36319b94acceSBarry Smith @*/
36327087cfbeSBarry Smith PetscErrorCode  SNESGetSolutionUpdate(SNES snes,Vec *x)
36339b94acceSBarry Smith {
36343a40ed3dSBarry Smith   PetscFunctionBegin;
36350700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
36364482741eSBarry Smith   PetscValidPointer(x,2);
363785385478SLisandro Dalcin   *x = snes->vec_sol_update;
36383a40ed3dSBarry Smith   PetscFunctionReturn(0);
36399b94acceSBarry Smith }
36409b94acceSBarry Smith 
36414a2ae208SSatish Balay #undef __FUNCT__
36424a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction"
36439b94acceSBarry Smith /*@C
36443638b69dSLois Curfman McInnes    SNESGetFunction - Returns the vector where the function is stored.
36459b94acceSBarry Smith 
3646a63bb30eSJed Brown    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
3647c7afd0dbSLois Curfman McInnes 
36489b94acceSBarry Smith    Input Parameter:
36499b94acceSBarry Smith .  snes - the SNES context
36509b94acceSBarry Smith 
36519b94acceSBarry Smith    Output Parameter:
36527bf4e008SBarry Smith +  r - the function (or PETSC_NULL)
365370e92668SMatthew Knepley .  func - the function (or PETSC_NULL)
365470e92668SMatthew Knepley -  ctx - the function context (or PETSC_NULL)
36559b94acceSBarry Smith 
365636851e7fSLois Curfman McInnes    Level: advanced
365736851e7fSLois Curfman McInnes 
3658a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function
36599b94acceSBarry Smith 
36604b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution()
36619b94acceSBarry Smith @*/
36627087cfbeSBarry Smith PetscErrorCode  SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
36639b94acceSBarry Smith {
3664a63bb30eSJed Brown   PetscErrorCode ierr;
36656cab3a1bSJed Brown   DM             dm;
3666a63bb30eSJed Brown 
36673a40ed3dSBarry Smith   PetscFunctionBegin;
36680700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3669a63bb30eSJed Brown   if (r) {
3670a63bb30eSJed Brown     if (!snes->vec_func) {
3671a63bb30eSJed Brown       if (snes->vec_rhs) {
3672a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr);
3673a63bb30eSJed Brown       } else if (snes->vec_sol) {
3674a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr);
3675a63bb30eSJed Brown       } else if (snes->dm) {
3676a63bb30eSJed Brown         ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr);
3677a63bb30eSJed Brown       }
3678a63bb30eSJed Brown     }
3679a63bb30eSJed Brown     *r = snes->vec_func;
3680a63bb30eSJed Brown   }
36816cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
36826cab3a1bSJed Brown   ierr = DMSNESGetFunction(dm,func,ctx);CHKERRQ(ierr);
36833a40ed3dSBarry Smith   PetscFunctionReturn(0);
36849b94acceSBarry Smith }
36859b94acceSBarry Smith 
3686c79ef259SPeter Brune /*@C
3687c79ef259SPeter Brune    SNESGetGS - Returns the GS function and context.
3688c79ef259SPeter Brune 
3689c79ef259SPeter Brune    Input Parameter:
3690c79ef259SPeter Brune .  snes - the SNES context
3691c79ef259SPeter Brune 
3692c79ef259SPeter Brune    Output Parameter:
3693c79ef259SPeter Brune +  gsfunc - the function (or PETSC_NULL)
3694c79ef259SPeter Brune -  ctx    - the function context (or PETSC_NULL)
3695c79ef259SPeter Brune 
3696c79ef259SPeter Brune    Level: advanced
3697c79ef259SPeter Brune 
3698c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function
3699c79ef259SPeter Brune 
3700c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction()
3701c79ef259SPeter Brune @*/
3702c79ef259SPeter Brune 
37034a2ae208SSatish Balay #undef __FUNCT__
3704646217ecSPeter Brune #define __FUNCT__ "SNESGetGS"
3705646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx)
3706646217ecSPeter Brune {
37076cab3a1bSJed Brown   PetscErrorCode ierr;
37086cab3a1bSJed Brown   DM             dm;
37096cab3a1bSJed Brown 
3710646217ecSPeter Brune   PetscFunctionBegin;
3711646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
37126cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
37136cab3a1bSJed Brown   ierr = DMSNESGetGS(dm,func,ctx);CHKERRQ(ierr);
3714646217ecSPeter Brune   PetscFunctionReturn(0);
3715646217ecSPeter Brune }
3716646217ecSPeter Brune 
37174a2ae208SSatish Balay #undef __FUNCT__
37184a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix"
37193c7409f5SSatish Balay /*@C
37203c7409f5SSatish Balay    SNESSetOptionsPrefix - Sets the prefix used for searching for all
3721d850072dSLois Curfman McInnes    SNES options in the database.
37223c7409f5SSatish Balay 
37233f9fe445SBarry Smith    Logically Collective on SNES
3724fee21e36SBarry Smith 
3725c7afd0dbSLois Curfman McInnes    Input Parameter:
3726c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3727c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3728c7afd0dbSLois Curfman McInnes 
3729d850072dSLois Curfman McInnes    Notes:
3730a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
3731c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
3732d850072dSLois Curfman McInnes 
373336851e7fSLois Curfman McInnes    Level: advanced
373436851e7fSLois Curfman McInnes 
37353c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database
3736a86d99e1SLois Curfman McInnes 
3737a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions()
37383c7409f5SSatish Balay @*/
37397087cfbeSBarry Smith PetscErrorCode  SNESSetOptionsPrefix(SNES snes,const char prefix[])
37403c7409f5SSatish Balay {
3741dfbe8321SBarry Smith   PetscErrorCode ierr;
37423c7409f5SSatish Balay 
37433a40ed3dSBarry Smith   PetscFunctionBegin;
37440700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3745639f9d9dSBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
37461cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
374794b7f48cSBarry Smith   ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
37483a40ed3dSBarry Smith   PetscFunctionReturn(0);
37493c7409f5SSatish Balay }
37503c7409f5SSatish Balay 
37514a2ae208SSatish Balay #undef __FUNCT__
37524a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix"
37533c7409f5SSatish Balay /*@C
3754f525115eSLois Curfman McInnes    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
3755d850072dSLois Curfman McInnes    SNES options in the database.
37563c7409f5SSatish Balay 
37573f9fe445SBarry Smith    Logically Collective on SNES
3758fee21e36SBarry Smith 
3759c7afd0dbSLois Curfman McInnes    Input Parameters:
3760c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3761c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3762c7afd0dbSLois Curfman McInnes 
3763d850072dSLois Curfman McInnes    Notes:
3764a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
3765c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
3766d850072dSLois Curfman McInnes 
376736851e7fSLois Curfman McInnes    Level: advanced
376836851e7fSLois Curfman McInnes 
37693c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database
3770a86d99e1SLois Curfman McInnes 
3771a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix()
37723c7409f5SSatish Balay @*/
37737087cfbeSBarry Smith PetscErrorCode  SNESAppendOptionsPrefix(SNES snes,const char prefix[])
37743c7409f5SSatish Balay {
3775dfbe8321SBarry Smith   PetscErrorCode ierr;
37763c7409f5SSatish Balay 
37773a40ed3dSBarry Smith   PetscFunctionBegin;
37780700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3779639f9d9dSBarry Smith   ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
37801cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
378194b7f48cSBarry Smith   ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
37823a40ed3dSBarry Smith   PetscFunctionReturn(0);
37833c7409f5SSatish Balay }
37843c7409f5SSatish Balay 
37854a2ae208SSatish Balay #undef __FUNCT__
37864a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix"
37879ab63eb5SSatish Balay /*@C
37883c7409f5SSatish Balay    SNESGetOptionsPrefix - Sets the prefix used for searching for all
37893c7409f5SSatish Balay    SNES options in the database.
37903c7409f5SSatish Balay 
3791c7afd0dbSLois Curfman McInnes    Not Collective
3792c7afd0dbSLois Curfman McInnes 
37933c7409f5SSatish Balay    Input Parameter:
37943c7409f5SSatish Balay .  snes - the SNES context
37953c7409f5SSatish Balay 
37963c7409f5SSatish Balay    Output Parameter:
37973c7409f5SSatish Balay .  prefix - pointer to the prefix string used
37983c7409f5SSatish Balay 
37994ef407dbSRichard Tran Mills    Notes: On the fortran side, the user should pass in a string 'prefix' of
38009ab63eb5SSatish Balay    sufficient length to hold the prefix.
38019ab63eb5SSatish Balay 
380236851e7fSLois Curfman McInnes    Level: advanced
380336851e7fSLois Curfman McInnes 
38043c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database
3805a86d99e1SLois Curfman McInnes 
3806a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix()
38073c7409f5SSatish Balay @*/
38087087cfbeSBarry Smith PetscErrorCode  SNESGetOptionsPrefix(SNES snes,const char *prefix[])
38093c7409f5SSatish Balay {
3810dfbe8321SBarry Smith   PetscErrorCode ierr;
38113c7409f5SSatish Balay 
38123a40ed3dSBarry Smith   PetscFunctionBegin;
38130700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3814639f9d9dSBarry Smith   ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
38153a40ed3dSBarry Smith   PetscFunctionReturn(0);
38163c7409f5SSatish Balay }
38173c7409f5SSatish Balay 
3818b2002411SLois Curfman McInnes 
38194a2ae208SSatish Balay #undef __FUNCT__
38204a2ae208SSatish Balay #define __FUNCT__ "SNESRegister"
38213cea93caSBarry Smith /*@C
38223cea93caSBarry Smith   SNESRegister - See SNESRegisterDynamic()
38233cea93caSBarry Smith 
38247f6c08e0SMatthew Knepley   Level: advanced
38253cea93caSBarry Smith @*/
38267087cfbeSBarry Smith PetscErrorCode  SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES))
3827b2002411SLois Curfman McInnes {
3828e2d1d2b7SBarry Smith   char           fullname[PETSC_MAX_PATH_LEN];
3829dfbe8321SBarry Smith   PetscErrorCode ierr;
3830b2002411SLois Curfman McInnes 
3831b2002411SLois Curfman McInnes   PetscFunctionBegin;
3832b0a32e0cSBarry Smith   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
3833c134de8dSSatish Balay   ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
3834b2002411SLois Curfman McInnes   PetscFunctionReturn(0);
3835b2002411SLois Curfman McInnes }
3836da9b6338SBarry Smith 
3837da9b6338SBarry Smith #undef __FUNCT__
3838da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin"
38397087cfbeSBarry Smith PetscErrorCode  SNESTestLocalMin(SNES snes)
3840da9b6338SBarry Smith {
3841dfbe8321SBarry Smith   PetscErrorCode ierr;
384277431f27SBarry Smith   PetscInt       N,i,j;
3843da9b6338SBarry Smith   Vec            u,uh,fh;
3844da9b6338SBarry Smith   PetscScalar    value;
3845da9b6338SBarry Smith   PetscReal      norm;
3846da9b6338SBarry Smith 
3847da9b6338SBarry Smith   PetscFunctionBegin;
3848da9b6338SBarry Smith   ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr);
3849da9b6338SBarry Smith   ierr = VecDuplicate(u,&uh);CHKERRQ(ierr);
3850da9b6338SBarry Smith   ierr = VecDuplicate(u,&fh);CHKERRQ(ierr);
3851da9b6338SBarry Smith 
3852da9b6338SBarry Smith   /* currently only works for sequential */
3853da9b6338SBarry Smith   ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");
3854da9b6338SBarry Smith   ierr = VecGetSize(u,&N);CHKERRQ(ierr);
3855da9b6338SBarry Smith   for (i=0; i<N; i++) {
3856da9b6338SBarry Smith     ierr = VecCopy(u,uh);CHKERRQ(ierr);
385777431f27SBarry Smith     ierr  = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr);
3858da9b6338SBarry Smith     for (j=-10; j<11; j++) {
3859ccae9161SBarry Smith       value = PetscSign(j)*exp(PetscAbs(j)-10.0);
3860da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
38613ab0aad5SBarry Smith       ierr  = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr);
3862da9b6338SBarry Smith       ierr  = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr);
386377431f27SBarry Smith       ierr  = PetscPrintf(PETSC_COMM_WORLD,"       j norm %D %18.16e\n",j,norm);CHKERRQ(ierr);
3864da9b6338SBarry Smith       value = -value;
3865da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
3866da9b6338SBarry Smith     }
3867da9b6338SBarry Smith   }
38686bf464f9SBarry Smith   ierr = VecDestroy(&uh);CHKERRQ(ierr);
38696bf464f9SBarry Smith   ierr = VecDestroy(&fh);CHKERRQ(ierr);
3870da9b6338SBarry Smith   PetscFunctionReturn(0);
3871da9b6338SBarry Smith }
387271f87433Sdalcinl 
387371f87433Sdalcinl #undef __FUNCT__
3874fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW"
387571f87433Sdalcinl /*@
3876fa9f3622SBarry Smith    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
387771f87433Sdalcinl    computing relative tolerance for linear solvers within an inexact
387871f87433Sdalcinl    Newton method.
387971f87433Sdalcinl 
38803f9fe445SBarry Smith    Logically Collective on SNES
388171f87433Sdalcinl 
388271f87433Sdalcinl    Input Parameters:
388371f87433Sdalcinl +  snes - SNES context
388471f87433Sdalcinl -  flag - PETSC_TRUE or PETSC_FALSE
388571f87433Sdalcinl 
388664ba62caSBarry Smith     Options Database:
388764ba62caSBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
388864ba62caSBarry Smith .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
388964ba62caSBarry Smith .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
389064ba62caSBarry Smith .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
389164ba62caSBarry Smith .  -snes_ksp_ew_gamma <gamma> - Sets gamma
389264ba62caSBarry Smith .  -snes_ksp_ew_alpha <alpha> - Sets alpha
389364ba62caSBarry Smith .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
389464ba62caSBarry Smith -  -snes_ksp_ew_threshold <threshold> - Sets threshold
389564ba62caSBarry Smith 
389671f87433Sdalcinl    Notes:
389771f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
389871f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
389971f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
390071f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
390171f87433Sdalcinl    solver.
390271f87433Sdalcinl 
390371f87433Sdalcinl    Level: advanced
390471f87433Sdalcinl 
390571f87433Sdalcinl    Reference:
390671f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
390771f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
390871f87433Sdalcinl 
390971f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
391071f87433Sdalcinl 
3911fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
391271f87433Sdalcinl @*/
39137087cfbeSBarry Smith PetscErrorCode  SNESKSPSetUseEW(SNES snes,PetscBool  flag)
391471f87433Sdalcinl {
391571f87433Sdalcinl   PetscFunctionBegin;
39160700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3917acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flag,2);
391871f87433Sdalcinl   snes->ksp_ewconv = flag;
391971f87433Sdalcinl   PetscFunctionReturn(0);
392071f87433Sdalcinl }
392171f87433Sdalcinl 
392271f87433Sdalcinl #undef __FUNCT__
3923fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW"
392471f87433Sdalcinl /*@
3925fa9f3622SBarry Smith    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
392671f87433Sdalcinl    for computing relative tolerance for linear solvers within an
392771f87433Sdalcinl    inexact Newton method.
392871f87433Sdalcinl 
392971f87433Sdalcinl    Not Collective
393071f87433Sdalcinl 
393171f87433Sdalcinl    Input Parameter:
393271f87433Sdalcinl .  snes - SNES context
393371f87433Sdalcinl 
393471f87433Sdalcinl    Output Parameter:
393571f87433Sdalcinl .  flag - PETSC_TRUE or PETSC_FALSE
393671f87433Sdalcinl 
393771f87433Sdalcinl    Notes:
393871f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
393971f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
394071f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
394171f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
394271f87433Sdalcinl    solver.
394371f87433Sdalcinl 
394471f87433Sdalcinl    Level: advanced
394571f87433Sdalcinl 
394671f87433Sdalcinl    Reference:
394771f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
394871f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
394971f87433Sdalcinl 
395071f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
395171f87433Sdalcinl 
3952fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
395371f87433Sdalcinl @*/
39547087cfbeSBarry Smith PetscErrorCode  SNESKSPGetUseEW(SNES snes, PetscBool  *flag)
395571f87433Sdalcinl {
395671f87433Sdalcinl   PetscFunctionBegin;
39570700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
395871f87433Sdalcinl   PetscValidPointer(flag,2);
395971f87433Sdalcinl   *flag = snes->ksp_ewconv;
396071f87433Sdalcinl   PetscFunctionReturn(0);
396171f87433Sdalcinl }
396271f87433Sdalcinl 
396371f87433Sdalcinl #undef __FUNCT__
3964fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW"
396571f87433Sdalcinl /*@
3966fa9f3622SBarry Smith    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
396771f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
396871f87433Sdalcinl    Newton method.
396971f87433Sdalcinl 
39703f9fe445SBarry Smith    Logically Collective on SNES
397171f87433Sdalcinl 
397271f87433Sdalcinl    Input Parameters:
397371f87433Sdalcinl +    snes - SNES context
397471f87433Sdalcinl .    version - version 1, 2 (default is 2) or 3
397571f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
397671f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
397771f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
397871f87433Sdalcinl              (0 <= gamma2 <= 1)
397971f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
398071f87433Sdalcinl .    alpha2 - power for safeguard
398171f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
398271f87433Sdalcinl 
398371f87433Sdalcinl    Note:
398471f87433Sdalcinl    Version 3 was contributed by Luis Chacon, June 2006.
398571f87433Sdalcinl 
398671f87433Sdalcinl    Use PETSC_DEFAULT to retain the default for any of the parameters.
398771f87433Sdalcinl 
398871f87433Sdalcinl    Level: advanced
398971f87433Sdalcinl 
399071f87433Sdalcinl    Reference:
399171f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
399271f87433Sdalcinl    inexact Newton method", Utah State University Math. Stat. Dept. Res.
399371f87433Sdalcinl    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
399471f87433Sdalcinl 
399571f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
399671f87433Sdalcinl 
3997fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
399871f87433Sdalcinl @*/
39997087cfbeSBarry Smith PetscErrorCode  SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,
400071f87433Sdalcinl 							    PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
400171f87433Sdalcinl {
4002fa9f3622SBarry Smith   SNESKSPEW *kctx;
400371f87433Sdalcinl   PetscFunctionBegin;
40040700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4005fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
4006e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
4007c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,version,2);
4008c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_0,3);
4009c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_max,4);
4010c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,gamma,5);
4011c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha,6);
4012c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha2,7);
4013c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,threshold,8);
401471f87433Sdalcinl 
401571f87433Sdalcinl   if (version != PETSC_DEFAULT)   kctx->version   = version;
401671f87433Sdalcinl   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
401771f87433Sdalcinl   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
401871f87433Sdalcinl   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
401971f87433Sdalcinl   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
402071f87433Sdalcinl   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
402171f87433Sdalcinl   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
402271f87433Sdalcinl 
402371f87433Sdalcinl   if (kctx->version < 1 || kctx->version > 3) {
4024e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version);
402571f87433Sdalcinl   }
402671f87433Sdalcinl   if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
4027e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0);
402871f87433Sdalcinl   }
402971f87433Sdalcinl   if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
4030e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max);
403171f87433Sdalcinl   }
403271f87433Sdalcinl   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
4033e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma);
403471f87433Sdalcinl   }
403571f87433Sdalcinl   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
4036e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha);
403771f87433Sdalcinl   }
403871f87433Sdalcinl   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
4039e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold);
404071f87433Sdalcinl   }
404171f87433Sdalcinl   PetscFunctionReturn(0);
404271f87433Sdalcinl }
404371f87433Sdalcinl 
404471f87433Sdalcinl #undef __FUNCT__
4045fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW"
404671f87433Sdalcinl /*@
4047fa9f3622SBarry Smith    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
404871f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
404971f87433Sdalcinl    Newton method.
405071f87433Sdalcinl 
405171f87433Sdalcinl    Not Collective
405271f87433Sdalcinl 
405371f87433Sdalcinl    Input Parameters:
405471f87433Sdalcinl      snes - SNES context
405571f87433Sdalcinl 
405671f87433Sdalcinl    Output Parameters:
405771f87433Sdalcinl +    version - version 1, 2 (default is 2) or 3
405871f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
405971f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
406071f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
406171f87433Sdalcinl              (0 <= gamma2 <= 1)
406271f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
406371f87433Sdalcinl .    alpha2 - power for safeguard
406471f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
406571f87433Sdalcinl 
406671f87433Sdalcinl    Level: advanced
406771f87433Sdalcinl 
406871f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters
406971f87433Sdalcinl 
4070fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
407171f87433Sdalcinl @*/
40727087cfbeSBarry Smith PetscErrorCode  SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,
407371f87433Sdalcinl 							    PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
407471f87433Sdalcinl {
4075fa9f3622SBarry Smith   SNESKSPEW *kctx;
407671f87433Sdalcinl   PetscFunctionBegin;
40770700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4078fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
4079e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
408071f87433Sdalcinl   if(version)   *version   = kctx->version;
408171f87433Sdalcinl   if(rtol_0)    *rtol_0    = kctx->rtol_0;
408271f87433Sdalcinl   if(rtol_max)  *rtol_max  = kctx->rtol_max;
408371f87433Sdalcinl   if(gamma)     *gamma     = kctx->gamma;
408471f87433Sdalcinl   if(alpha)     *alpha     = kctx->alpha;
408571f87433Sdalcinl   if(alpha2)    *alpha2    = kctx->alpha2;
408671f87433Sdalcinl   if(threshold) *threshold = kctx->threshold;
408771f87433Sdalcinl   PetscFunctionReturn(0);
408871f87433Sdalcinl }
408971f87433Sdalcinl 
409071f87433Sdalcinl #undef __FUNCT__
4091fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve"
4092fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x)
409371f87433Sdalcinl {
409471f87433Sdalcinl   PetscErrorCode ierr;
4095fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
409671f87433Sdalcinl   PetscReal      rtol=PETSC_DEFAULT,stol;
409771f87433Sdalcinl 
409871f87433Sdalcinl   PetscFunctionBegin;
4099e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
410071f87433Sdalcinl   if (!snes->iter) { /* first time in, so use the original user rtol */
410171f87433Sdalcinl     rtol = kctx->rtol_0;
410271f87433Sdalcinl   } else {
410371f87433Sdalcinl     if (kctx->version == 1) {
410471f87433Sdalcinl       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
410571f87433Sdalcinl       if (rtol < 0.0) rtol = -rtol;
410671f87433Sdalcinl       stol = pow(kctx->rtol_last,kctx->alpha2);
410771f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
410871f87433Sdalcinl     } else if (kctx->version == 2) {
410971f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
411071f87433Sdalcinl       stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
411171f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
411271f87433Sdalcinl     } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */
411371f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
411471f87433Sdalcinl       /* safeguard: avoid sharp decrease of rtol */
411571f87433Sdalcinl       stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha);
411671f87433Sdalcinl       stol = PetscMax(rtol,stol);
411771f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
411871f87433Sdalcinl       /* safeguard: avoid oversolving */
411971f87433Sdalcinl       stol = kctx->gamma*(snes->ttol)/snes->norm;
412071f87433Sdalcinl       stol = PetscMax(rtol,stol);
412171f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
4122e32f2f54SBarry Smith     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
412371f87433Sdalcinl   }
412471f87433Sdalcinl   /* safeguard: avoid rtol greater than one */
412571f87433Sdalcinl   rtol = PetscMin(rtol,kctx->rtol_max);
412671f87433Sdalcinl   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
412771f87433Sdalcinl   ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr);
412871f87433Sdalcinl   PetscFunctionReturn(0);
412971f87433Sdalcinl }
413071f87433Sdalcinl 
413171f87433Sdalcinl #undef __FUNCT__
4132fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve"
4133fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x)
413471f87433Sdalcinl {
413571f87433Sdalcinl   PetscErrorCode ierr;
4136fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
413771f87433Sdalcinl   PCSide         pcside;
413871f87433Sdalcinl   Vec            lres;
413971f87433Sdalcinl 
414071f87433Sdalcinl   PetscFunctionBegin;
4141e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
414271f87433Sdalcinl   ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr);
414371f87433Sdalcinl   ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr);
414471f87433Sdalcinl   if (kctx->version == 1) {
4145b037da10SBarry Smith     ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr);
414671f87433Sdalcinl     if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
414771f87433Sdalcinl       /* KSP residual is true linear residual */
414871f87433Sdalcinl       ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr);
414971f87433Sdalcinl     } else {
415071f87433Sdalcinl       /* KSP residual is preconditioned residual */
415171f87433Sdalcinl       /* compute true linear residual norm */
415271f87433Sdalcinl       ierr = VecDuplicate(b,&lres);CHKERRQ(ierr);
415371f87433Sdalcinl       ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr);
415471f87433Sdalcinl       ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr);
415571f87433Sdalcinl       ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr);
41566bf464f9SBarry Smith       ierr = VecDestroy(&lres);CHKERRQ(ierr);
415771f87433Sdalcinl     }
415871f87433Sdalcinl   }
415971f87433Sdalcinl   PetscFunctionReturn(0);
416071f87433Sdalcinl }
416171f87433Sdalcinl 
416271f87433Sdalcinl #undef __FUNCT__
416371f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve"
416471f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x)
416571f87433Sdalcinl {
416671f87433Sdalcinl   PetscErrorCode ierr;
416771f87433Sdalcinl 
416871f87433Sdalcinl   PetscFunctionBegin;
4169fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr);  }
417071f87433Sdalcinl   ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr);
4171fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); }
417271f87433Sdalcinl   PetscFunctionReturn(0);
417371f87433Sdalcinl }
41746c699258SBarry Smith 
41756c699258SBarry Smith #undef __FUNCT__
41766c699258SBarry Smith #define __FUNCT__ "SNESSetDM"
41776c699258SBarry Smith /*@
41786c699258SBarry Smith    SNESSetDM - Sets the DM that may be used by some preconditioners
41796c699258SBarry Smith 
41803f9fe445SBarry Smith    Logically Collective on SNES
41816c699258SBarry Smith 
41826c699258SBarry Smith    Input Parameters:
41836c699258SBarry Smith +  snes - the preconditioner context
41846c699258SBarry Smith -  dm - the dm
41856c699258SBarry Smith 
41866c699258SBarry Smith    Level: intermediate
41876c699258SBarry Smith 
41886c699258SBarry Smith 
41896c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM()
41906c699258SBarry Smith @*/
41917087cfbeSBarry Smith PetscErrorCode  SNESSetDM(SNES snes,DM dm)
41926c699258SBarry Smith {
41936c699258SBarry Smith   PetscErrorCode ierr;
4194345fed2cSBarry Smith   KSP            ksp;
41956cab3a1bSJed Brown   SNESDM         sdm;
41966c699258SBarry Smith 
41976c699258SBarry Smith   PetscFunctionBegin;
41980700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4199d0660788SBarry Smith   if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);}
42006cab3a1bSJed Brown   if (snes->dm) {               /* Move the SNESDM context over to the new DM unless the new DM already has one */
42016cab3a1bSJed Brown     PetscContainer oldcontainer,container;
42026cab3a1bSJed Brown     ierr = PetscObjectQuery((PetscObject)snes->dm,"SNESDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr);
42036cab3a1bSJed Brown     ierr = PetscObjectQuery((PetscObject)dm,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr);
42046cab3a1bSJed Brown     if (oldcontainer && !container) {
42056cab3a1bSJed Brown       ierr = DMSNESCopyContext(snes->dm,dm);CHKERRQ(ierr);
42066cab3a1bSJed Brown       ierr = DMSNESGetContext(snes->dm,&sdm);CHKERRQ(ierr);
42076cab3a1bSJed Brown       if (sdm->originaldm == snes->dm) { /* Grant write privileges to the replacement DM */
42086cab3a1bSJed Brown         sdm->originaldm = dm;
42096cab3a1bSJed Brown       }
42106cab3a1bSJed Brown     }
42116bf464f9SBarry Smith     ierr = DMDestroy(&snes->dm);CHKERRQ(ierr);
42126cab3a1bSJed Brown   }
42136c699258SBarry Smith   snes->dm = dm;
4214345fed2cSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
4215345fed2cSBarry Smith   ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr);
4216f22f69f0SBarry Smith   ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr);
42172c155ee1SBarry Smith   if (snes->pc) {
42182c155ee1SBarry Smith     ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr);
42192c155ee1SBarry Smith   }
42206c699258SBarry Smith   PetscFunctionReturn(0);
42216c699258SBarry Smith }
42226c699258SBarry Smith 
42236c699258SBarry Smith #undef __FUNCT__
42246c699258SBarry Smith #define __FUNCT__ "SNESGetDM"
42256c699258SBarry Smith /*@
42266c699258SBarry Smith    SNESGetDM - Gets the DM that may be used by some preconditioners
42276c699258SBarry Smith 
42283f9fe445SBarry Smith    Not Collective but DM obtained is parallel on SNES
42296c699258SBarry Smith 
42306c699258SBarry Smith    Input Parameter:
42316c699258SBarry Smith . snes - the preconditioner context
42326c699258SBarry Smith 
42336c699258SBarry Smith    Output Parameter:
42346c699258SBarry Smith .  dm - the dm
42356c699258SBarry Smith 
42366c699258SBarry Smith    Level: intermediate
42376c699258SBarry Smith 
42386c699258SBarry Smith 
42396c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM()
42406c699258SBarry Smith @*/
42417087cfbeSBarry Smith PetscErrorCode  SNESGetDM(SNES snes,DM *dm)
42426c699258SBarry Smith {
42436cab3a1bSJed Brown   PetscErrorCode ierr;
42446cab3a1bSJed Brown 
42456c699258SBarry Smith   PetscFunctionBegin;
42460700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
42476cab3a1bSJed Brown   if (!snes->dm) {
42486cab3a1bSJed Brown     ierr = DMShellCreate(((PetscObject)snes)->comm,&snes->dm);CHKERRQ(ierr);
42496cab3a1bSJed Brown   }
42506c699258SBarry Smith   *dm = snes->dm;
42516c699258SBarry Smith   PetscFunctionReturn(0);
42526c699258SBarry Smith }
42530807856dSBarry Smith 
425431823bd8SMatthew G Knepley #undef __FUNCT__
425531823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC"
425631823bd8SMatthew G Knepley /*@
4257fd4b34e9SJed Brown   SNESSetPC - Sets the nonlinear preconditioner to be used.
425831823bd8SMatthew G Knepley 
425931823bd8SMatthew G Knepley   Collective on SNES
426031823bd8SMatthew G Knepley 
426131823bd8SMatthew G Knepley   Input Parameters:
426231823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate()
426331823bd8SMatthew G Knepley - pc   - the preconditioner object
426431823bd8SMatthew G Knepley 
426531823bd8SMatthew G Knepley   Notes:
426631823bd8SMatthew G Knepley   Use SNESGetPC() to retrieve the preconditioner context (for example,
426731823bd8SMatthew G Knepley   to configure it using the API).
426831823bd8SMatthew G Knepley 
426931823bd8SMatthew G Knepley   Level: developer
427031823bd8SMatthew G Knepley 
427131823bd8SMatthew G Knepley .keywords: SNES, set, precondition
427231823bd8SMatthew G Knepley .seealso: SNESGetPC()
427331823bd8SMatthew G Knepley @*/
427431823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc)
427531823bd8SMatthew G Knepley {
427631823bd8SMatthew G Knepley   PetscErrorCode ierr;
427731823bd8SMatthew G Knepley 
427831823bd8SMatthew G Knepley   PetscFunctionBegin;
427931823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
428031823bd8SMatthew G Knepley   PetscValidHeaderSpecific(pc, SNES_CLASSID, 2);
428131823bd8SMatthew G Knepley   PetscCheckSameComm(snes, 1, pc, 2);
428231823bd8SMatthew G Knepley   ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr);
4283bf11d3b6SBarry Smith   ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr);
428431823bd8SMatthew G Knepley   snes->pc = pc;
428531823bd8SMatthew G Knepley   ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr);
428631823bd8SMatthew G Knepley   PetscFunctionReturn(0);
428731823bd8SMatthew G Knepley }
428831823bd8SMatthew G Knepley 
428931823bd8SMatthew G Knepley #undef __FUNCT__
429031823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC"
429131823bd8SMatthew G Knepley /*@
4292fd4b34e9SJed Brown   SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC().
429331823bd8SMatthew G Knepley 
429431823bd8SMatthew G Knepley   Not Collective
429531823bd8SMatthew G Knepley 
429631823bd8SMatthew G Knepley   Input Parameter:
429731823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate()
429831823bd8SMatthew G Knepley 
429931823bd8SMatthew G Knepley   Output Parameter:
430031823bd8SMatthew G Knepley . pc - preconditioner context
430131823bd8SMatthew G Knepley 
430231823bd8SMatthew G Knepley   Level: developer
430331823bd8SMatthew G Knepley 
430431823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner
430531823bd8SMatthew G Knepley .seealso: SNESSetPC()
430631823bd8SMatthew G Knepley @*/
430731823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc)
430831823bd8SMatthew G Knepley {
430931823bd8SMatthew G Knepley   PetscErrorCode ierr;
431031823bd8SMatthew G Knepley 
431131823bd8SMatthew G Knepley   PetscFunctionBegin;
431231823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
431331823bd8SMatthew G Knepley   PetscValidPointer(pc, 2);
431431823bd8SMatthew G Knepley   if (!snes->pc) {
431531823bd8SMatthew G Knepley     ierr = SNESCreate(((PetscObject) snes)->comm, &snes->pc);CHKERRQ(ierr);
43164a0c5b0cSMatthew G Knepley     ierr = PetscObjectIncrementTabLevel((PetscObject) snes->pc, (PetscObject) snes, 1);CHKERRQ(ierr);
431731823bd8SMatthew G Knepley     ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr);
431831823bd8SMatthew G Knepley   }
431931823bd8SMatthew G Knepley   *pc = snes->pc;
432031823bd8SMatthew G Knepley   PetscFunctionReturn(0);
432131823bd8SMatthew G Knepley }
432231823bd8SMatthew G Knepley 
43239e764e56SPeter Brune #undef __FUNCT__
4324f1c6b773SPeter Brune #define __FUNCT__ "SNESSetSNESLineSearch"
43259e764e56SPeter Brune /*@
4326f1c6b773SPeter Brune   SNESSetSNESLineSearch - Sets the linesearch.
43279e764e56SPeter Brune 
43289e764e56SPeter Brune   Collective on SNES
43299e764e56SPeter Brune 
43309e764e56SPeter Brune   Input Parameters:
43319e764e56SPeter Brune + snes - iterative context obtained from SNESCreate()
43329e764e56SPeter Brune - linesearch   - the linesearch object
43339e764e56SPeter Brune 
43349e764e56SPeter Brune   Notes:
4335f1c6b773SPeter Brune   Use SNESGetSNESLineSearch() to retrieve the preconditioner context (for example,
43369e764e56SPeter Brune   to configure it using the API).
43379e764e56SPeter Brune 
43389e764e56SPeter Brune   Level: developer
43399e764e56SPeter Brune 
43409e764e56SPeter Brune .keywords: SNES, set, linesearch
4341f1c6b773SPeter Brune .seealso: SNESGetSNESLineSearch()
43429e764e56SPeter Brune @*/
4343f1c6b773SPeter Brune PetscErrorCode SNESSetSNESLineSearch(SNES snes, SNESLineSearch linesearch)
43449e764e56SPeter Brune {
43459e764e56SPeter Brune   PetscErrorCode ierr;
43469e764e56SPeter Brune 
43479e764e56SPeter Brune   PetscFunctionBegin;
43489e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4349f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2);
43509e764e56SPeter Brune   PetscCheckSameComm(snes, 1, linesearch, 2);
43519e764e56SPeter Brune   ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr);
4352f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr);
43539e764e56SPeter Brune   snes->linesearch = linesearch;
43549e764e56SPeter Brune   ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr);
43559e764e56SPeter Brune   PetscFunctionReturn(0);
43569e764e56SPeter Brune }
43579e764e56SPeter Brune 
43589e764e56SPeter Brune #undef __FUNCT__
4359f1c6b773SPeter Brune #define __FUNCT__ "SNESGetSNESLineSearch"
4360ea5d4fccSPeter Brune /*@C
4361f1c6b773SPeter Brune   SNESGetSNESLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch().
43629e764e56SPeter Brune 
43639e764e56SPeter Brune   Not Collective
43649e764e56SPeter Brune 
43659e764e56SPeter Brune   Input Parameter:
43669e764e56SPeter Brune . snes - iterative context obtained from SNESCreate()
43679e764e56SPeter Brune 
43689e764e56SPeter Brune   Output Parameter:
43699e764e56SPeter Brune . linesearch - linesearch context
43709e764e56SPeter Brune 
43719e764e56SPeter Brune   Level: developer
43729e764e56SPeter Brune 
43739e764e56SPeter Brune .keywords: SNES, get, linesearch
4374f1c6b773SPeter Brune .seealso: SNESSetSNESLineSearch()
43759e764e56SPeter Brune @*/
4376f1c6b773SPeter Brune PetscErrorCode SNESGetSNESLineSearch(SNES snes, SNESLineSearch *linesearch)
43779e764e56SPeter Brune {
43789e764e56SPeter Brune   PetscErrorCode ierr;
43799e764e56SPeter Brune   const char     *optionsprefix;
43809e764e56SPeter Brune 
43819e764e56SPeter Brune   PetscFunctionBegin;
43829e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
43839e764e56SPeter Brune   PetscValidPointer(linesearch, 2);
43849e764e56SPeter Brune   if (!snes->linesearch) {
43859e764e56SPeter Brune     ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
4386f1c6b773SPeter Brune     ierr = SNESLineSearchCreate(((PetscObject) snes)->comm, &snes->linesearch);CHKERRQ(ierr);
4387f1c6b773SPeter Brune     ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr);
4388b1dca40bSPeter Brune     ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr);
43899e764e56SPeter Brune     ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr);
43909e764e56SPeter Brune     ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr);
43919e764e56SPeter Brune   }
43929e764e56SPeter Brune   *linesearch = snes->linesearch;
43939e764e56SPeter Brune   PetscFunctionReturn(0);
43949e764e56SPeter Brune }
43959e764e56SPeter Brune 
439669b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
4397c6db04a5SJed Brown #include <mex.h>
439869b4f73cSBarry Smith 
43998f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext;
44008f6e6473SBarry Smith 
44010807856dSBarry Smith #undef __FUNCT__
44020807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab"
44030807856dSBarry Smith /*
44040807856dSBarry Smith    SNESComputeFunction_Matlab - Calls the function that has been set with
44050807856dSBarry Smith                          SNESSetFunctionMatlab().
44060807856dSBarry Smith 
44070807856dSBarry Smith    Collective on SNES
44080807856dSBarry Smith 
44090807856dSBarry Smith    Input Parameters:
44100807856dSBarry Smith +  snes - the SNES context
44110807856dSBarry Smith -  x - input vector
44120807856dSBarry Smith 
44130807856dSBarry Smith    Output Parameter:
44140807856dSBarry Smith .  y - function vector, as set by SNESSetFunction()
44150807856dSBarry Smith 
44160807856dSBarry Smith    Notes:
44170807856dSBarry Smith    SNESComputeFunction() is typically used within nonlinear solvers
44180807856dSBarry Smith    implementations, so most users would not generally call this routine
44190807856dSBarry Smith    themselves.
44200807856dSBarry Smith 
44210807856dSBarry Smith    Level: developer
44220807856dSBarry Smith 
44230807856dSBarry Smith .keywords: SNES, nonlinear, compute, function
44240807856dSBarry Smith 
44250807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
442661b2408cSBarry Smith */
44277087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx)
44280807856dSBarry Smith {
4429e650e774SBarry Smith   PetscErrorCode    ierr;
44308f6e6473SBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
44318f6e6473SBarry Smith   int               nlhs = 1,nrhs = 5;
44328f6e6473SBarry Smith   mxArray	    *plhs[1],*prhs[5];
443391621f2eSBarry Smith   long long int     lx = 0,ly = 0,ls = 0;
4434e650e774SBarry Smith 
44350807856dSBarry Smith   PetscFunctionBegin;
44360807856dSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
44370807856dSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
44380807856dSBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
44390807856dSBarry Smith   PetscCheckSameComm(snes,1,x,2);
44400807856dSBarry Smith   PetscCheckSameComm(snes,1,y,3);
44410807856dSBarry Smith 
44420807856dSBarry Smith   /* call Matlab function in ctx with arguments x and y */
4443e650e774SBarry Smith 
444491621f2eSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4445e650e774SBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4446e650e774SBarry Smith   ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr);
444791621f2eSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
444891621f2eSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
444991621f2eSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)ly);
44508f6e6473SBarry Smith   prhs[3] =  mxCreateString(sctx->funcname);
44518f6e6473SBarry Smith   prhs[4] =  sctx->ctx;
4452b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr);
4453e650e774SBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4454e650e774SBarry Smith   mxDestroyArray(prhs[0]);
4455e650e774SBarry Smith   mxDestroyArray(prhs[1]);
4456e650e774SBarry Smith   mxDestroyArray(prhs[2]);
44578f6e6473SBarry Smith   mxDestroyArray(prhs[3]);
4458e650e774SBarry Smith   mxDestroyArray(plhs[0]);
44590807856dSBarry Smith   PetscFunctionReturn(0);
44600807856dSBarry Smith }
44610807856dSBarry Smith 
44620807856dSBarry Smith 
44630807856dSBarry Smith #undef __FUNCT__
44640807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab"
446561b2408cSBarry Smith /*
44660807856dSBarry Smith    SNESSetFunctionMatlab - Sets the function evaluation routine and function
44670807856dSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4468e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
44690807856dSBarry Smith 
44700807856dSBarry Smith    Logically Collective on SNES
44710807856dSBarry Smith 
44720807856dSBarry Smith    Input Parameters:
44730807856dSBarry Smith +  snes - the SNES context
44740807856dSBarry Smith .  r - vector to store function value
44750807856dSBarry Smith -  func - function evaluation routine
44760807856dSBarry Smith 
44770807856dSBarry Smith    Calling sequence of func:
447861b2408cSBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
44790807856dSBarry Smith 
44800807856dSBarry Smith 
44810807856dSBarry Smith    Notes:
44820807856dSBarry Smith    The Newton-like methods typically solve linear systems of the form
44830807856dSBarry Smith $      f'(x) x = -f(x),
44840807856dSBarry Smith    where f'(x) denotes the Jacobian matrix and f(x) is the function.
44850807856dSBarry Smith 
44860807856dSBarry Smith    Level: beginner
44870807856dSBarry Smith 
44880807856dSBarry Smith .keywords: SNES, nonlinear, set, function
44890807856dSBarry Smith 
44900807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
449161b2408cSBarry Smith */
44927087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx)
44930807856dSBarry Smith {
44940807856dSBarry Smith   PetscErrorCode    ierr;
44958f6e6473SBarry Smith   SNESMatlabContext *sctx;
44960807856dSBarry Smith 
44970807856dSBarry Smith   PetscFunctionBegin;
44988f6e6473SBarry Smith   /* currently sctx is memory bleed */
44998f6e6473SBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
45008f6e6473SBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
45018f6e6473SBarry Smith   /*
45028f6e6473SBarry Smith      This should work, but it doesn't
45038f6e6473SBarry Smith   sctx->ctx = ctx;
45048f6e6473SBarry Smith   mexMakeArrayPersistent(sctx->ctx);
45058f6e6473SBarry Smith   */
45068f6e6473SBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
45078f6e6473SBarry Smith   ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr);
45080807856dSBarry Smith   PetscFunctionReturn(0);
45090807856dSBarry Smith }
451069b4f73cSBarry Smith 
451161b2408cSBarry Smith #undef __FUNCT__
451261b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab"
451361b2408cSBarry Smith /*
451461b2408cSBarry Smith    SNESComputeJacobian_Matlab - Calls the function that has been set with
451561b2408cSBarry Smith                          SNESSetJacobianMatlab().
451661b2408cSBarry Smith 
451761b2408cSBarry Smith    Collective on SNES
451861b2408cSBarry Smith 
451961b2408cSBarry Smith    Input Parameters:
452061b2408cSBarry Smith +  snes - the SNES context
452161b2408cSBarry Smith .  x - input vector
452261b2408cSBarry Smith .  A, B - the matrices
452361b2408cSBarry Smith -  ctx - user context
452461b2408cSBarry Smith 
452561b2408cSBarry Smith    Output Parameter:
452661b2408cSBarry Smith .  flag - structure of the matrix
452761b2408cSBarry Smith 
452861b2408cSBarry Smith    Level: developer
452961b2408cSBarry Smith 
453061b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function
453161b2408cSBarry Smith 
453261b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
453361b2408cSBarry Smith @*/
45347087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx)
453561b2408cSBarry Smith {
453661b2408cSBarry Smith   PetscErrorCode    ierr;
453761b2408cSBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
453861b2408cSBarry Smith   int               nlhs = 2,nrhs = 6;
453961b2408cSBarry Smith   mxArray	    *plhs[2],*prhs[6];
454061b2408cSBarry Smith   long long int     lx = 0,lA = 0,ls = 0, lB = 0;
454161b2408cSBarry Smith 
454261b2408cSBarry Smith   PetscFunctionBegin;
454361b2408cSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
454461b2408cSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
454561b2408cSBarry Smith 
454661b2408cSBarry Smith   /* call Matlab function in ctx with arguments x and y */
454761b2408cSBarry Smith 
454861b2408cSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
454961b2408cSBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
455061b2408cSBarry Smith   ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr);
455161b2408cSBarry Smith   ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr);
455261b2408cSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
455361b2408cSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
455461b2408cSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)lA);
455561b2408cSBarry Smith   prhs[3] =  mxCreateDoubleScalar((double)lB);
455661b2408cSBarry Smith   prhs[4] =  mxCreateString(sctx->funcname);
455761b2408cSBarry Smith   prhs[5] =  sctx->ctx;
4558b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr);
455961b2408cSBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
456061b2408cSBarry Smith   *flag   =  (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr);
456161b2408cSBarry Smith   mxDestroyArray(prhs[0]);
456261b2408cSBarry Smith   mxDestroyArray(prhs[1]);
456361b2408cSBarry Smith   mxDestroyArray(prhs[2]);
456461b2408cSBarry Smith   mxDestroyArray(prhs[3]);
456561b2408cSBarry Smith   mxDestroyArray(prhs[4]);
456661b2408cSBarry Smith   mxDestroyArray(plhs[0]);
456761b2408cSBarry Smith   mxDestroyArray(plhs[1]);
456861b2408cSBarry Smith   PetscFunctionReturn(0);
456961b2408cSBarry Smith }
457061b2408cSBarry Smith 
457161b2408cSBarry Smith 
457261b2408cSBarry Smith #undef __FUNCT__
457361b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab"
457461b2408cSBarry Smith /*
457561b2408cSBarry Smith    SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
457661b2408cSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4577e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
457861b2408cSBarry Smith 
457961b2408cSBarry Smith    Logically Collective on SNES
458061b2408cSBarry Smith 
458161b2408cSBarry Smith    Input Parameters:
458261b2408cSBarry Smith +  snes - the SNES context
458361b2408cSBarry Smith .  A,B - Jacobian matrices
458461b2408cSBarry Smith .  func - function evaluation routine
458561b2408cSBarry Smith -  ctx - user context
458661b2408cSBarry Smith 
458761b2408cSBarry Smith    Calling sequence of func:
458861b2408cSBarry Smith $    flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx);
458961b2408cSBarry Smith 
459061b2408cSBarry Smith 
459161b2408cSBarry Smith    Level: developer
459261b2408cSBarry Smith 
459361b2408cSBarry Smith .keywords: SNES, nonlinear, set, function
459461b2408cSBarry Smith 
459561b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
459661b2408cSBarry Smith */
45977087cfbeSBarry Smith PetscErrorCode  SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx)
459861b2408cSBarry Smith {
459961b2408cSBarry Smith   PetscErrorCode    ierr;
460061b2408cSBarry Smith   SNESMatlabContext *sctx;
460161b2408cSBarry Smith 
460261b2408cSBarry Smith   PetscFunctionBegin;
460361b2408cSBarry Smith   /* currently sctx is memory bleed */
460461b2408cSBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
460561b2408cSBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
460661b2408cSBarry Smith   /*
460761b2408cSBarry Smith      This should work, but it doesn't
460861b2408cSBarry Smith   sctx->ctx = ctx;
460961b2408cSBarry Smith   mexMakeArrayPersistent(sctx->ctx);
461061b2408cSBarry Smith   */
461161b2408cSBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
461261b2408cSBarry Smith   ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
461361b2408cSBarry Smith   PetscFunctionReturn(0);
461461b2408cSBarry Smith }
461569b4f73cSBarry Smith 
4616f9eb7ae2SShri Abhyankar #undef __FUNCT__
4617f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab"
4618f9eb7ae2SShri Abhyankar /*
4619f9eb7ae2SShri Abhyankar    SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab().
4620f9eb7ae2SShri Abhyankar 
4621f9eb7ae2SShri Abhyankar    Collective on SNES
4622f9eb7ae2SShri Abhyankar 
4623f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction()
4624f9eb7ae2SShri Abhyankar @*/
46257087cfbeSBarry Smith PetscErrorCode  SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx)
4626f9eb7ae2SShri Abhyankar {
4627f9eb7ae2SShri Abhyankar   PetscErrorCode  ierr;
462848f37e70SShri Abhyankar   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
4629f9eb7ae2SShri Abhyankar   int             nlhs = 1,nrhs = 6;
4630f9eb7ae2SShri Abhyankar   mxArray	  *plhs[1],*prhs[6];
4631f9eb7ae2SShri Abhyankar   long long int   lx = 0,ls = 0;
4632f9eb7ae2SShri Abhyankar   Vec             x=snes->vec_sol;
4633f9eb7ae2SShri Abhyankar 
4634f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4635f9eb7ae2SShri Abhyankar   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4636f9eb7ae2SShri Abhyankar 
4637f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4638f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4639f9eb7ae2SShri Abhyankar   prhs[0] =  mxCreateDoubleScalar((double)ls);
4640f9eb7ae2SShri Abhyankar   prhs[1] =  mxCreateDoubleScalar((double)it);
4641f9eb7ae2SShri Abhyankar   prhs[2] =  mxCreateDoubleScalar((double)fnorm);
4642f9eb7ae2SShri Abhyankar   prhs[3] =  mxCreateDoubleScalar((double)lx);
4643f9eb7ae2SShri Abhyankar   prhs[4] =  mxCreateString(sctx->funcname);
4644f9eb7ae2SShri Abhyankar   prhs[5] =  sctx->ctx;
4645f9eb7ae2SShri Abhyankar   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr);
4646f9eb7ae2SShri Abhyankar   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4647f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[0]);
4648f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[1]);
4649f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[2]);
4650f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[3]);
4651f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[4]);
4652f9eb7ae2SShri Abhyankar   mxDestroyArray(plhs[0]);
4653f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
4654f9eb7ae2SShri Abhyankar }
4655f9eb7ae2SShri Abhyankar 
4656f9eb7ae2SShri Abhyankar 
4657f9eb7ae2SShri Abhyankar #undef __FUNCT__
4658f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab"
4659f9eb7ae2SShri Abhyankar /*
4660e3c5b3baSBarry Smith    SNESMonitorSetMatlab - Sets the monitor function from MATLAB
4661f9eb7ae2SShri Abhyankar 
4662f9eb7ae2SShri Abhyankar    Level: developer
4663f9eb7ae2SShri Abhyankar 
4664f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function
4665f9eb7ae2SShri Abhyankar 
4666f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
4667f9eb7ae2SShri Abhyankar */
46687087cfbeSBarry Smith PetscErrorCode  SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx)
4669f9eb7ae2SShri Abhyankar {
4670f9eb7ae2SShri Abhyankar   PetscErrorCode    ierr;
4671f9eb7ae2SShri Abhyankar   SNESMatlabContext *sctx;
4672f9eb7ae2SShri Abhyankar 
4673f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4674f9eb7ae2SShri Abhyankar   /* currently sctx is memory bleed */
4675f9eb7ae2SShri Abhyankar   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
4676f9eb7ae2SShri Abhyankar   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
4677f9eb7ae2SShri Abhyankar   /*
4678f9eb7ae2SShri Abhyankar      This should work, but it doesn't
4679f9eb7ae2SShri Abhyankar   sctx->ctx = ctx;
4680f9eb7ae2SShri Abhyankar   mexMakeArrayPersistent(sctx->ctx);
4681f9eb7ae2SShri Abhyankar   */
4682f9eb7ae2SShri Abhyankar   sctx->ctx = mxDuplicateArray(ctx);
4683f9eb7ae2SShri Abhyankar   ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr);
4684f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
4685f9eb7ae2SShri Abhyankar }
4686f9eb7ae2SShri Abhyankar 
468769b4f73cSBarry Smith #endif
4688