xref: /petsc/src/snes/interface/snes.c (revision c7e7b494335814a8ea0a9fdb66ddef5267ac44b9)
19b94acceSBarry Smith 
2c6db04a5SJed Brown #include <private/snesimpl.h>      /*I "petscsnes.h"  I*/
36cab3a1bSJed Brown #include <petscdmshell.h>          /*I "petscdmshell.h" I*/
49b94acceSBarry Smith 
5ace3abfcSBarry Smith PetscBool  SNESRegisterAllCalled = PETSC_FALSE;
68ba1e511SMatthew Knepley PetscFList SNESList              = PETSC_NULL;
78ba1e511SMatthew Knepley 
88ba1e511SMatthew Knepley /* Logging support */
97087cfbeSBarry Smith PetscClassId  SNES_CLASSID;
10701cf23dSPeter Brune PetscLogEvent  SNES_Solve, SNES_LineSearch, 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
16cab2e9ccSBarry Smith */
17cab2e9ccSBarry Smith PetscErrorCode SNESDMComputeJacobian(SNES snes,Vec X,Mat *J,Mat *B,MatStructure *flag,void *ptr)
18cab2e9ccSBarry Smith {
19cab2e9ccSBarry Smith   PetscErrorCode ierr;
20cab2e9ccSBarry Smith   DM             dm;
21cab2e9ccSBarry Smith 
22cab2e9ccSBarry Smith   PetscFunctionBegin;
23cab2e9ccSBarry Smith   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
24cab2e9ccSBarry Smith   ierr = DMComputeJacobian(dm,X,*J,*B,flag);CHKERRQ(ierr);
25cab2e9ccSBarry Smith   PetscFunctionReturn(0);
26cab2e9ccSBarry Smith }
27cab2e9ccSBarry Smith 
28cab2e9ccSBarry Smith #undef __FUNCT__
29e113a28aSBarry Smith #define __FUNCT__ "SNESSetErrorIfNotConverged"
30e113a28aSBarry Smith /*@
31e113a28aSBarry Smith    SNESSetErrorIfNotConverged - Causes SNESSolve() to generate an error if the solver has not converged.
32e113a28aSBarry Smith 
333f9fe445SBarry Smith    Logically Collective on SNES
34e113a28aSBarry Smith 
35e113a28aSBarry Smith    Input Parameters:
36e113a28aSBarry Smith +  snes - iterative context obtained from SNESCreate()
37e113a28aSBarry Smith -  flg - PETSC_TRUE indicates you want the error generated
38e113a28aSBarry Smith 
39e113a28aSBarry Smith    Options database keys:
40e113a28aSBarry Smith .  -snes_error_if_not_converged : this takes an optional truth value (0/1/no/yes/true/false)
41e113a28aSBarry Smith 
42e113a28aSBarry Smith    Level: intermediate
43e113a28aSBarry Smith 
44e113a28aSBarry Smith    Notes:
45e113a28aSBarry Smith     Normally PETSc continues if a linear solver fails to converge, you can call SNESGetConvergedReason() after a SNESSolve()
46e113a28aSBarry Smith     to determine if it has converged.
47e113a28aSBarry Smith 
48e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero
49e113a28aSBarry Smith 
50e113a28aSBarry Smith .seealso: SNESGetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged()
51e113a28aSBarry Smith @*/
527087cfbeSBarry Smith PetscErrorCode  SNESSetErrorIfNotConverged(SNES snes,PetscBool  flg)
53e113a28aSBarry Smith {
54e113a28aSBarry Smith   PetscFunctionBegin;
55e113a28aSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
56acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flg,2);
57e113a28aSBarry Smith   snes->errorifnotconverged = flg;
58dd568438SSatish Balay 
59e113a28aSBarry Smith   PetscFunctionReturn(0);
60e113a28aSBarry Smith }
61e113a28aSBarry Smith 
62e113a28aSBarry Smith #undef __FUNCT__
63e113a28aSBarry Smith #define __FUNCT__ "SNESGetErrorIfNotConverged"
64e113a28aSBarry Smith /*@
65e113a28aSBarry Smith    SNESGetErrorIfNotConverged - Will SNESSolve() generate an error if the solver does not converge?
66e113a28aSBarry Smith 
67e113a28aSBarry Smith    Not Collective
68e113a28aSBarry Smith 
69e113a28aSBarry Smith    Input Parameter:
70e113a28aSBarry Smith .  snes - iterative context obtained from SNESCreate()
71e113a28aSBarry Smith 
72e113a28aSBarry Smith    Output Parameter:
73e113a28aSBarry Smith .  flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE
74e113a28aSBarry Smith 
75e113a28aSBarry Smith    Level: intermediate
76e113a28aSBarry Smith 
77e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero
78e113a28aSBarry Smith 
79e113a28aSBarry Smith .seealso:  SNESSetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged()
80e113a28aSBarry Smith @*/
817087cfbeSBarry Smith PetscErrorCode  SNESGetErrorIfNotConverged(SNES snes,PetscBool  *flag)
82e113a28aSBarry Smith {
83e113a28aSBarry Smith   PetscFunctionBegin;
84e113a28aSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
85e113a28aSBarry Smith   PetscValidPointer(flag,2);
86e113a28aSBarry Smith   *flag = snes->errorifnotconverged;
87e113a28aSBarry Smith   PetscFunctionReturn(0);
88e113a28aSBarry Smith }
89e113a28aSBarry Smith 
90e113a28aSBarry Smith #undef __FUNCT__
914936397dSBarry Smith #define __FUNCT__ "SNESSetFunctionDomainError"
92e725d27bSBarry Smith /*@
934936397dSBarry Smith    SNESSetFunctionDomainError - tells SNES that the input vector to your FormFunction is not
944936397dSBarry Smith      in the functions domain. For example, negative pressure.
954936397dSBarry Smith 
963f9fe445SBarry Smith    Logically Collective on SNES
974936397dSBarry Smith 
984936397dSBarry Smith    Input Parameters:
996a388c36SPeter Brune .  snes - the SNES context
1004936397dSBarry Smith 
10128529972SSatish Balay    Level: advanced
1024936397dSBarry Smith 
1034936397dSBarry Smith .keywords: SNES, view
1044936397dSBarry Smith 
1054936397dSBarry Smith .seealso: SNESCreate(), SNESSetFunction()
1064936397dSBarry Smith @*/
1077087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionDomainError(SNES snes)
1084936397dSBarry Smith {
1094936397dSBarry Smith   PetscFunctionBegin;
1100700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1114936397dSBarry Smith   snes->domainerror = PETSC_TRUE;
1124936397dSBarry Smith   PetscFunctionReturn(0);
1134936397dSBarry Smith }
1144936397dSBarry Smith 
1156a388c36SPeter Brune 
1166a388c36SPeter Brune #undef __FUNCT__
1176a388c36SPeter Brune #define __FUNCT__ "SNESGetFunctionDomainError"
1186a388c36SPeter Brune /*@
119c77b2880SPeter Brune    SNESGetFunctionDomainError - Gets the status of the domain error after a call to SNESComputeFunction;
1206a388c36SPeter Brune 
1216a388c36SPeter Brune    Logically Collective on SNES
1226a388c36SPeter Brune 
1236a388c36SPeter Brune    Input Parameters:
1246a388c36SPeter Brune .  snes - the SNES context
1256a388c36SPeter Brune 
1266a388c36SPeter Brune    Output Parameters:
1276a388c36SPeter Brune .  domainerror Set to PETSC_TRUE if there's a domain error; PETSC_FALSE otherwise.
1286a388c36SPeter Brune 
1296a388c36SPeter Brune    Level: advanced
1306a388c36SPeter Brune 
1316a388c36SPeter Brune .keywords: SNES, view
1326a388c36SPeter Brune 
1336a388c36SPeter Brune .seealso: SNESSetFunctionDomainError, SNESComputeFunction()
1346a388c36SPeter Brune @*/
1356a388c36SPeter Brune PetscErrorCode  SNESGetFunctionDomainError(SNES snes, PetscBool *domainerror)
1366a388c36SPeter Brune {
1376a388c36SPeter Brune   PetscFunctionBegin;
1386a388c36SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1396a388c36SPeter Brune   PetscValidPointer(domainerror, 2);
1406a388c36SPeter Brune   *domainerror = snes->domainerror;
1416a388c36SPeter Brune   PetscFunctionReturn(0);
1426a388c36SPeter Brune }
1436a388c36SPeter Brune 
1446a388c36SPeter Brune 
1454936397dSBarry Smith #undef __FUNCT__
1464a2ae208SSatish Balay #define __FUNCT__ "SNESView"
1477e2c5f70SBarry Smith /*@C
1489b94acceSBarry Smith    SNESView - Prints the SNES data structure.
1499b94acceSBarry Smith 
1504c49b128SBarry Smith    Collective on SNES
151fee21e36SBarry Smith 
152c7afd0dbSLois Curfman McInnes    Input Parameters:
153c7afd0dbSLois Curfman McInnes +  SNES - the SNES context
154c7afd0dbSLois Curfman McInnes -  viewer - visualization context
155c7afd0dbSLois Curfman McInnes 
1569b94acceSBarry Smith    Options Database Key:
157c8a8ba5cSLois Curfman McInnes .  -snes_view - Calls SNESView() at end of SNESSolve()
1589b94acceSBarry Smith 
1599b94acceSBarry Smith    Notes:
1609b94acceSBarry Smith    The available visualization contexts include
161b0a32e0cSBarry Smith +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
162b0a32e0cSBarry Smith -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
163c8a8ba5cSLois Curfman McInnes          output where only the first processor opens
164c8a8ba5cSLois Curfman McInnes          the file.  All other processors send their
165c8a8ba5cSLois Curfman McInnes          data to the first processor to print.
1669b94acceSBarry Smith 
1673e081fefSLois Curfman McInnes    The user can open an alternative visualization context with
168b0a32e0cSBarry Smith    PetscViewerASCIIOpen() - output to a specified file.
1699b94acceSBarry Smith 
17036851e7fSLois Curfman McInnes    Level: beginner
17136851e7fSLois Curfman McInnes 
1729b94acceSBarry Smith .keywords: SNES, view
1739b94acceSBarry Smith 
174b0a32e0cSBarry Smith .seealso: PetscViewerASCIIOpen()
1759b94acceSBarry Smith @*/
1767087cfbeSBarry Smith PetscErrorCode  SNESView(SNES snes,PetscViewer viewer)
1779b94acceSBarry Smith {
178fa9f3622SBarry Smith   SNESKSPEW           *kctx;
179dfbe8321SBarry Smith   PetscErrorCode      ierr;
18094b7f48cSBarry Smith   KSP                 ksp;
181ace3abfcSBarry Smith   PetscBool           iascii,isstring;
1829b94acceSBarry Smith 
1833a40ed3dSBarry Smith   PetscFunctionBegin;
1840700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1853050cee2SBarry Smith   if (!viewer) {
1867adad957SLisandro Dalcin     ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr);
1873050cee2SBarry Smith   }
1880700a824SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
189c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,viewer,2);
19074679c65SBarry Smith 
1912692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1922692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr);
19332077d6dSBarry Smith   if (iascii) {
194317d6ea6SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer,"SNES Object");CHKERRQ(ierr);
195e7788613SBarry Smith     if (snes->ops->view) {
196b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
197e7788613SBarry Smith       ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr);
198b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1990ef38995SBarry Smith     }
20077431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);CHKERRQ(ierr);
201a83599f4SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  tolerances: relative=%G, absolute=%G, solution=%G\n",
20270441072SBarry Smith                  snes->rtol,snes->abstol,snes->xtol);CHKERRQ(ierr);
20377431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr);
20477431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr);
2059b94acceSBarry Smith     if (snes->ksp_ewconv) {
206fa9f3622SBarry Smith       kctx = (SNESKSPEW *)snes->kspconvctx;
2079b94acceSBarry Smith       if (kctx) {
20877431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"  Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr);
209a83599f4SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    rtol_0=%G, rtol_max=%G, threshold=%G\n",kctx->rtol_0,kctx->rtol_max,kctx->threshold);CHKERRQ(ierr);
210a83599f4SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    gamma=%G, alpha=%G, alpha2=%G\n",kctx->gamma,kctx->alpha,kctx->alpha2);CHKERRQ(ierr);
2119b94acceSBarry Smith       }
2129b94acceSBarry Smith     }
213eb1f6c34SBarry Smith     if (snes->lagpreconditioner == -1) {
214eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is never rebuilt\n");CHKERRQ(ierr);
215eb1f6c34SBarry Smith     } else if (snes->lagpreconditioner > 1) {
216eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr);
217eb1f6c34SBarry Smith     }
218eb1f6c34SBarry Smith     if (snes->lagjacobian == -1) {
219eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is never rebuilt\n");CHKERRQ(ierr);
220eb1f6c34SBarry Smith     } else if (snes->lagjacobian > 1) {
22142f4f86dSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian);CHKERRQ(ierr);
222eb1f6c34SBarry Smith     }
2230f5bd95cSBarry Smith   } else if (isstring) {
224317d6ea6SBarry Smith     const char *type;
225454a90a3SBarry Smith     ierr = SNESGetType(snes,&type);CHKERRQ(ierr);
226b0a32e0cSBarry Smith     ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr);
22719bcc07fSBarry Smith   }
22842f4f86dSBarry Smith   if (snes->pc && snes->usespc) {
2294a0c5b0cSMatthew G Knepley     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
2304a0c5b0cSMatthew G Knepley     ierr = SNESView(snes->pc, viewer);CHKERRQ(ierr);
2314a0c5b0cSMatthew G Knepley     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2324a0c5b0cSMatthew G Knepley   }
2332c155ee1SBarry Smith   if (snes->usesksp) {
2342c155ee1SBarry Smith     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
235b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
23694b7f48cSBarry Smith     ierr = KSPView(ksp,viewer);CHKERRQ(ierr);
237b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2382c155ee1SBarry Smith   }
2393a40ed3dSBarry Smith   PetscFunctionReturn(0);
2409b94acceSBarry Smith }
2419b94acceSBarry Smith 
24276b2cf59SMatthew Knepley /*
24376b2cf59SMatthew Knepley   We retain a list of functions that also take SNES command
24476b2cf59SMatthew Knepley   line options. These are called at the end SNESSetFromOptions()
24576b2cf59SMatthew Knepley */
24676b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5
247a7cc72afSBarry Smith static PetscInt numberofsetfromoptions;
2486849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES);
24976b2cf59SMatthew Knepley 
250e74ef692SMatthew Knepley #undef __FUNCT__
251e74ef692SMatthew Knepley #define __FUNCT__ "SNESAddOptionsChecker"
252ac226902SBarry Smith /*@C
25376b2cf59SMatthew Knepley   SNESAddOptionsChecker - Adds an additional function to check for SNES options.
25476b2cf59SMatthew Knepley 
25576b2cf59SMatthew Knepley   Not Collective
25676b2cf59SMatthew Knepley 
25776b2cf59SMatthew Knepley   Input Parameter:
25876b2cf59SMatthew Knepley . snescheck - function that checks for options
25976b2cf59SMatthew Knepley 
26076b2cf59SMatthew Knepley   Level: developer
26176b2cf59SMatthew Knepley 
26276b2cf59SMatthew Knepley .seealso: SNESSetFromOptions()
26376b2cf59SMatthew Knepley @*/
2647087cfbeSBarry Smith PetscErrorCode  SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES))
26576b2cf59SMatthew Knepley {
26676b2cf59SMatthew Knepley   PetscFunctionBegin;
26776b2cf59SMatthew Knepley   if (numberofsetfromoptions >= MAXSETFROMOPTIONS) {
268e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS);
26976b2cf59SMatthew Knepley   }
27076b2cf59SMatthew Knepley   othersetfromoptions[numberofsetfromoptions++] = snescheck;
27176b2cf59SMatthew Knepley   PetscFunctionReturn(0);
27276b2cf59SMatthew Knepley }
27376b2cf59SMatthew Knepley 
2747087cfbeSBarry Smith extern PetscErrorCode  SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*);
275aa3661deSLisandro Dalcin 
276aa3661deSLisandro Dalcin #undef __FUNCT__
277aa3661deSLisandro Dalcin #define __FUNCT__ "SNESSetUpMatrixFree_Private"
278ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool  hasOperator, PetscInt version)
279aa3661deSLisandro Dalcin {
280aa3661deSLisandro Dalcin   Mat            J;
281aa3661deSLisandro Dalcin   KSP            ksp;
282aa3661deSLisandro Dalcin   PC             pc;
283ace3abfcSBarry Smith   PetscBool      match;
284aa3661deSLisandro Dalcin   PetscErrorCode ierr;
285aa3661deSLisandro Dalcin 
286aa3661deSLisandro Dalcin   PetscFunctionBegin;
2870700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
288aa3661deSLisandro Dalcin 
28998613b67SLisandro Dalcin   if(!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) {
29098613b67SLisandro Dalcin     Mat A = snes->jacobian, B = snes->jacobian_pre;
29198613b67SLisandro Dalcin     ierr = MatGetVecs(A ? A : B, PETSC_NULL,&snes->vec_func);CHKERRQ(ierr);
29298613b67SLisandro Dalcin   }
29398613b67SLisandro Dalcin 
294aa3661deSLisandro Dalcin   if (version == 1) {
295aa3661deSLisandro Dalcin     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
29698613b67SLisandro Dalcin     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
2979c6ac3b3SBarry Smith     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
298aa3661deSLisandro Dalcin   } else if (version == 2) {
299e32f2f54SBarry Smith     if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first");
30082a7e548SBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
301aa3661deSLisandro Dalcin     ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr);
302aa3661deSLisandro Dalcin #else
303e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)");
304aa3661deSLisandro Dalcin #endif
305a8248277SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2");
306aa3661deSLisandro Dalcin 
307aa3661deSLisandro Dalcin   ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr);
308d3462f78SMatthew Knepley   if (hasOperator) {
309aa3661deSLisandro Dalcin     /* This version replaces the user provided Jacobian matrix with a
310aa3661deSLisandro Dalcin        matrix-free version but still employs the user-provided preconditioner matrix. */
311aa3661deSLisandro Dalcin     ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr);
312aa3661deSLisandro Dalcin   } else {
313aa3661deSLisandro Dalcin     /* This version replaces both the user-provided Jacobian and the user-
314aa3661deSLisandro Dalcin        provided preconditioner matrix with the default matrix free version. */
3156cab3a1bSJed Brown     void *functx;
3166cab3a1bSJed Brown     ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
3176cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr);
318aa3661deSLisandro Dalcin     /* Force no preconditioner */
319aa3661deSLisandro Dalcin     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
320aa3661deSLisandro Dalcin     ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr);
321aa3661deSLisandro Dalcin     ierr = PetscTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr);
322aa3661deSLisandro Dalcin     if (!match) {
323aa3661deSLisandro Dalcin       ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr);
324aa3661deSLisandro Dalcin       ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr);
325aa3661deSLisandro Dalcin     }
326aa3661deSLisandro Dalcin   }
3276bf464f9SBarry Smith   ierr = MatDestroy(&J);CHKERRQ(ierr);
328aa3661deSLisandro Dalcin   PetscFunctionReturn(0);
329aa3661deSLisandro Dalcin }
330aa3661deSLisandro Dalcin 
3314a2ae208SSatish Balay #undef __FUNCT__
3326cab3a1bSJed Brown #define __FUNCT__ "SNESSetUpMatrices"
3336cab3a1bSJed Brown /*@
3346cab3a1bSJed Brown    SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX()
3356cab3a1bSJed Brown 
3366cab3a1bSJed Brown    Collective
3376cab3a1bSJed Brown 
3386cab3a1bSJed Brown    Input Arguments:
3396cab3a1bSJed Brown .  snes - snes to configure
3406cab3a1bSJed Brown 
3416cab3a1bSJed Brown    Level: developer
3426cab3a1bSJed Brown 
3436cab3a1bSJed Brown .seealso: SNESSetUp()
3446cab3a1bSJed Brown @*/
3456cab3a1bSJed Brown PetscErrorCode SNESSetUpMatrices(SNES snes)
3466cab3a1bSJed Brown {
3476cab3a1bSJed Brown   PetscErrorCode ierr;
3486cab3a1bSJed Brown   DM             dm;
3496cab3a1bSJed Brown   SNESDM         sdm;
3506cab3a1bSJed Brown 
3516cab3a1bSJed Brown   PetscFunctionBegin;
3526cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3536cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
3546cab3a1bSJed Brown   if (!sdm->computejacobian && snes->dm) {
3556cab3a1bSJed Brown     Mat J,B;
3566cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
3576cab3a1bSJed Brown     if (snes->mf_operator) {
3586cab3a1bSJed Brown       ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
3596cab3a1bSJed Brown       ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
3606cab3a1bSJed Brown       ierr = MatSetFromOptions(J);CHKERRQ(ierr);
3616cab3a1bSJed Brown     } else {
3626cab3a1bSJed Brown       J = B;
3636cab3a1bSJed Brown       ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
3646cab3a1bSJed Brown     }
3656cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,PETSC_NULL);CHKERRQ(ierr);
3666cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
3676cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
3686cab3a1bSJed Brown   } else if (!snes->jacobian && sdm->computejacobian == MatMFFDComputeJacobian) {
3696cab3a1bSJed Brown     Mat J;
3706cab3a1bSJed Brown     void *functx;
3716cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
3726cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
3736cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
3746cab3a1bSJed Brown     ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
3756cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr);
3766cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
3776cab3a1bSJed Brown   } else if (snes->dm && snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) {
3786cab3a1bSJed Brown     Mat J,B;
3796cab3a1bSJed Brown     void *functx;
3806cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
3816cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
3826cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
3836cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
3846cab3a1bSJed Brown     ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
3856cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,functx);CHKERRQ(ierr);
3866cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
3876cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
3886cab3a1bSJed Brown   } else if (snes->dm && !snes->jacobian_pre) {
3896cab3a1bSJed Brown     Mat J,B;
3906cab3a1bSJed Brown     J = snes->jacobian;
3916cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
3926cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J?J:B,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
3936cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
3946cab3a1bSJed Brown   }
3956cab3a1bSJed Brown   PetscFunctionReturn(0);
3966cab3a1bSJed Brown }
3976cab3a1bSJed Brown 
3986cab3a1bSJed Brown #undef __FUNCT__
3994a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions"
4009b94acceSBarry Smith /*@
40194b7f48cSBarry Smith    SNESSetFromOptions - Sets various SNES and KSP parameters from user options.
4029b94acceSBarry Smith 
403c7afd0dbSLois Curfman McInnes    Collective on SNES
404c7afd0dbSLois Curfman McInnes 
4059b94acceSBarry Smith    Input Parameter:
4069b94acceSBarry Smith .  snes - the SNES context
4079b94acceSBarry Smith 
40836851e7fSLois Curfman McInnes    Options Database Keys:
409ea630c6eSPeter Brune +  -snes_type <type> - ls, tr, ngmres, ncg, richardson, qn, vi, fas
41082738288SBarry Smith .  -snes_stol - convergence tolerance in terms of the norm
41182738288SBarry Smith                 of the change in the solution between steps
41270441072SBarry Smith .  -snes_atol <abstol> - absolute tolerance of residual norm
413b39c3a46SLois Curfman McInnes .  -snes_rtol <rtol> - relative decrease in tolerance norm from initial
414b39c3a46SLois Curfman McInnes .  -snes_max_it <max_it> - maximum number of iterations
415b39c3a46SLois Curfman McInnes .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
4164839bfe8SBarry Smith .  -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none
417ddf469c8SBarry Smith .  -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops
418a8054027SBarry Smith .  -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild)
419e35cf81dSBarry Smith .  -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild)
420b39c3a46SLois Curfman McInnes .  -snes_trtol <trtol> - trust region tolerance
4212492ecdbSBarry Smith .  -snes_no_convergence_test - skip convergence test in nonlinear
42282738288SBarry Smith                                solver; hence iterations will continue until max_it
4231fbbfb26SLois Curfman McInnes                                or some other criterion is reached. Saves expense
42482738288SBarry Smith                                of convergence test
425e8105e01SRichard Katz .  -snes_monitor <optional filename> - prints residual norm at each iteration. if no
426e8105e01SRichard Katz                                        filename given prints to stdout
427a6570f20SBarry Smith .  -snes_monitor_solution - plots solution at each iteration
428a6570f20SBarry Smith .  -snes_monitor_residual - plots residual (not its norm) at each iteration
429a6570f20SBarry Smith .  -snes_monitor_solution_update - plots update to solution at each iteration
430a6570f20SBarry Smith .  -snes_monitor_draw - plots residual norm at each iteration
431e24b481bSBarry Smith .  -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
4325968eb51SBarry Smith .  -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
433fee2055bSBarry Smith -  -snes_converged_reason - print the reason for convergence/divergence after each solve
43482738288SBarry Smith 
43582738288SBarry Smith     Options Database for Eisenstat-Walker method:
436fa9f3622SBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
4374b27c08aSLois Curfman McInnes .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
43836851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
43936851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
44036851e7fSLois Curfman McInnes .  -snes_ksp_ew_gamma <gamma> - Sets gamma
44136851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha <alpha> - Sets alpha
44236851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
44336851e7fSLois Curfman McInnes -  -snes_ksp_ew_threshold <threshold> - Sets threshold
44482738288SBarry Smith 
44511ca99fdSLois Curfman McInnes    Notes:
44611ca99fdSLois Curfman McInnes    To see all options, run your program with the -help option or consult
4470598bfebSBarry Smith    the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>.
44883e2fdc7SBarry Smith 
44936851e7fSLois Curfman McInnes    Level: beginner
45036851e7fSLois Curfman McInnes 
4519b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database
4529b94acceSBarry Smith 
45369ed319cSSatish Balay .seealso: SNESSetOptionsPrefix()
4549b94acceSBarry Smith @*/
4557087cfbeSBarry Smith PetscErrorCode  SNESSetFromOptions(SNES snes)
4569b94acceSBarry Smith {
457ea630c6eSPeter Brune   PetscBool               flg,set,mf,mf_operator,pcset;
458efd51863SBarry Smith   PetscInt                i,indx,lag,mf_version,grids;
459aa3661deSLisandro Dalcin   MatStructure            matflag;
46085385478SLisandro Dalcin   const char              *deft = SNESLS;
46185385478SLisandro Dalcin   const char              *convtests[] = {"default","skip"};
46285385478SLisandro Dalcin   SNESKSPEW               *kctx = NULL;
463e8105e01SRichard Katz   char                    type[256], monfilename[PETSC_MAX_PATH_LEN];
46451e86f29SPeter Brune   const char              *optionsprefix;
465649052a6SBarry Smith   PetscViewer             monviewer;
46685385478SLisandro Dalcin   PetscErrorCode          ierr;
4679b94acceSBarry Smith 
4683a40ed3dSBarry Smith   PetscFunctionBegin;
4690700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
470ca161407SBarry Smith 
471186905e3SBarry Smith   if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
4723194b578SJed Brown   ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr);
4737adad957SLisandro Dalcin     if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; }
474b0a32e0cSBarry Smith     ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr);
475d64ed03dSBarry Smith     if (flg) {
476186905e3SBarry Smith       ierr = SNESSetType(snes,type);CHKERRQ(ierr);
4777adad957SLisandro Dalcin     } else if (!((PetscObject)snes)->type_name) {
478186905e3SBarry Smith       ierr = SNESSetType(snes,deft);CHKERRQ(ierr);
479d64ed03dSBarry Smith     }
48090d69ab7SBarry Smith     /* not used here, but called so will go into help messaage */
481909c8a9fSBarry Smith     ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr);
48293c39befSBarry Smith 
48357034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->xtol,&snes->xtol,0);CHKERRQ(ierr);
48457034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr);
485186905e3SBarry Smith 
48657034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr);
487b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr);
488b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr);
48950ffb88aSMatthew Knepley     ierr = PetscOptionsInt("-snes_max_fail","Maximum failures","SNESSetTolerances",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr);
490ddf469c8SBarry Smith     ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr);
491acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);CHKERRQ(ierr);
49285385478SLisandro Dalcin 
493a8054027SBarry Smith     ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr);
494a8054027SBarry Smith     if (flg) {
495a8054027SBarry Smith       ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr);
496a8054027SBarry Smith     }
497e35cf81dSBarry Smith     ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr);
498e35cf81dSBarry Smith     if (flg) {
499e35cf81dSBarry Smith       ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr);
500e35cf81dSBarry Smith     }
501efd51863SBarry Smith     ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr);
502efd51863SBarry Smith     if (flg) {
503efd51863SBarry Smith       ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr);
504efd51863SBarry Smith     }
505a8054027SBarry Smith 
50685385478SLisandro Dalcin     ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr);
50785385478SLisandro Dalcin     if (flg) {
50885385478SLisandro Dalcin       switch (indx) {
5097f7931b9SBarry Smith       case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break;
5107f7931b9SBarry Smith       case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);    break;
51185385478SLisandro Dalcin       }
51285385478SLisandro Dalcin     }
51385385478SLisandro Dalcin 
514acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr);
515186905e3SBarry Smith 
51685385478SLisandro Dalcin     kctx = (SNESKSPEW *)snes->kspconvctx;
51785385478SLisandro Dalcin 
518acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr);
519186905e3SBarry Smith 
520fa9f3622SBarry Smith     ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr);
521fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr);
522fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr);
523fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr);
524fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr);
525fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr);
526fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr);
527186905e3SBarry Smith 
52890d69ab7SBarry Smith     flg  = PETSC_FALSE;
529acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
530a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);}
531eabae89aSBarry Smith 
532a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
533e8105e01SRichard Katz     if (flg) {
534649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
535649052a6SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
536e8105e01SRichard Katz     }
537eabae89aSBarry Smith 
538b271bb04SBarry Smith     ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
539b271bb04SBarry Smith     if (flg) {
540b271bb04SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr);
541b271bb04SBarry Smith     }
542b271bb04SBarry Smith 
543a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
544eabae89aSBarry Smith     if (flg) {
545649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
546f1bef1bcSMatthew Knepley       ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr);
547e8105e01SRichard Katz     }
548eabae89aSBarry Smith 
549a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
550eabae89aSBarry Smith     if (flg) {
551649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
552649052a6SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
553eabae89aSBarry Smith     }
554eabae89aSBarry Smith 
5555180491cSLisandro Dalcin     ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
5565180491cSLisandro Dalcin     if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);}
5575180491cSLisandro Dalcin 
55890d69ab7SBarry Smith     flg  = PETSC_FALSE;
559acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
560a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);}
56190d69ab7SBarry Smith     flg  = PETSC_FALSE;
562acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
563a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);}
56490d69ab7SBarry Smith     flg  = PETSC_FALSE;
565acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
566a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);}
56790d69ab7SBarry Smith     flg  = PETSC_FALSE;
568acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
569a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
57090d69ab7SBarry Smith     flg  = PETSC_FALSE;
571acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
572b271bb04SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
573e24b481bSBarry Smith 
57490d69ab7SBarry Smith     flg  = PETSC_FALSE;
575acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
5764b27c08aSLois Curfman McInnes     if (flg) {
5776cab3a1bSJed Brown       void *functx;
5786cab3a1bSJed Brown       ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
5796cab3a1bSJed Brown       ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,functx);CHKERRQ(ierr);
580ae15b995SBarry Smith       ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr);
5819b94acceSBarry Smith     }
582639f9d9dSBarry Smith 
583aa3661deSLisandro Dalcin     mf = mf_operator = PETSC_FALSE;
584aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
585acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr);
586a8248277SBarry Smith     if (flg && mf_operator) {
587a8248277SBarry Smith       snes->mf_operator = PETSC_TRUE;
588a8248277SBarry Smith       mf = PETSC_TRUE;
589a8248277SBarry Smith     }
590aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
591acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);CHKERRQ(ierr);
592aa3661deSLisandro Dalcin     if (!flg && mf_operator) mf = PETSC_TRUE;
593aa3661deSLisandro Dalcin     mf_version = 1;
594aa3661deSLisandro Dalcin     ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);CHKERRQ(ierr);
595aa3661deSLisandro Dalcin 
596d28543b3SPeter Brune 
59789b92e6fSPeter Brune     /* GS Options */
59889b92e6fSPeter Brune     ierr = PetscOptionsInt("-snes_gs_sweeps","Number of sweeps of GS to apply","SNESComputeGS",snes->gssweeps,&snes->gssweeps,PETSC_NULL);CHKERRQ(ierr);
59989b92e6fSPeter Brune 
600ea630c6eSPeter Brune     /* line search options */
601ea630c6eSPeter Brune     ierr = PetscOptionsReal("-snes_ls_alpha","Constant function norm must decrease by","None",snes->ls_alpha,&snes->ls_alpha,0);CHKERRQ(ierr);
602ea630c6eSPeter Brune     ierr = PetscOptionsReal("-snes_ls_maxstep","Step must be less than","None",snes->maxstep,&snes->maxstep,0);CHKERRQ(ierr);
603ea630c6eSPeter Brune     ierr = PetscOptionsReal("-snes_ls_steptol","Minimum lambda allowed","None",snes->steptol,&snes->steptol,0);CHKERRQ(ierr);
604ea630c6eSPeter Brune     ierr = PetscOptionsReal("-snes_ls_damping","Damping parameter","SNES",snes->damping,&snes->damping,&flg);CHKERRQ(ierr);
605af60355fSPeter Brune     ierr = PetscOptionsInt("-snes_ls_it"      ,"Line search iterations","SNES",snes->ls_its,&snes->ls_its,&flg);CHKERRQ(ierr);
606ea630c6eSPeter Brune     ierr = PetscOptionsBool("-snes_ls_monitor","Print progress of line searches","SNESLineSearchSetMonitor",snes->ls_monitor ? PETSC_TRUE : PETSC_FALSE,&flg,&set);CHKERRQ(ierr);
607ea630c6eSPeter Brune     if (set) {ierr = SNESLineSearchSetMonitor(snes,flg);CHKERRQ(ierr);}
60815f5eeeaSPeter Brune     ierr = PetscOptionsEnum("-snes_ls","Line search used","SNESLineSearchSet",SNESLineSearchTypes,(PetscEnum)snes->ls_type,(PetscEnum*)&indx,&flg);CHKERRQ(ierr);
60915f5eeeaSPeter Brune     if (flg) {
610ea630c6eSPeter Brune       ierr = SNESLineSearchSetType(snes,(SNESLineSearchType)indx);CHKERRQ(ierr);
61115f5eeeaSPeter Brune     }
6128e3fc8c0SJed Brown     flg = snes->ops->precheckstep == SNESLineSearchPreCheckPicard ? PETSC_TRUE : PETSC_FALSE;
6138e3fc8c0SJed Brown     ierr = PetscOptionsBool("-snes_ls_precheck_picard","Use a correction that sometimes improves convergence of Picard iteration","SNESLineSearchPreCheckPicard",flg,&flg,&set);CHKERRQ(ierr);
6148e3fc8c0SJed Brown     if (set) {
6158e3fc8c0SJed Brown       if (flg) {
6168e3fc8c0SJed Brown         snes->precheck_picard_angle = 10.; /* correction only active if angle is less than 10 degrees */
6178e3fc8c0SJed Brown         ierr = PetscOptionsReal("-snes_ls_precheck_picard_angle","Maximum angle at which to activate the correction","none",snes->precheck_picard_angle,&snes->precheck_picard_angle,PETSC_NULL);CHKERRQ(ierr);
6188e3fc8c0SJed Brown         ierr = SNESLineSearchSetPreCheck(snes,SNESLineSearchPreCheckPicard,&snes->precheck_picard_angle);CHKERRQ(ierr);
6198e3fc8c0SJed Brown       } else {
6208e3fc8c0SJed Brown         ierr = SNESLineSearchSetPreCheck(snes,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
6218e3fc8c0SJed Brown       }
6228e3fc8c0SJed Brown     }
6238e3fc8c0SJed Brown 
62476b2cf59SMatthew Knepley     for(i = 0; i < numberofsetfromoptions; i++) {
62576b2cf59SMatthew Knepley       ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr);
62676b2cf59SMatthew Knepley     }
62776b2cf59SMatthew Knepley 
628e7788613SBarry Smith     if (snes->ops->setfromoptions) {
629e7788613SBarry Smith       ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr);
630639f9d9dSBarry Smith     }
6315d973c19SBarry Smith 
6325d973c19SBarry Smith     /* process any options handlers added with PetscObjectAddOptionsHandler() */
6335d973c19SBarry Smith     ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr);
634b0a32e0cSBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
6354bbc92c1SBarry Smith 
636aa3661deSLisandro Dalcin   if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); }
6371cee3971SBarry Smith 
6381cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
639aa3661deSLisandro Dalcin   ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag);
640aa3661deSLisandro Dalcin   ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr);
64185385478SLisandro Dalcin   ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr);
64293993e2dSLois Curfman McInnes 
64351e86f29SPeter Brune   /* if someone has set the SNES PC type, create it. */
64451e86f29SPeter Brune   ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
64551e86f29SPeter Brune   ierr = PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr);
64651e86f29SPeter Brune   if (pcset && (!snes->pc)) {
64751e86f29SPeter Brune     ierr = SNESGetPC(snes, &snes->pc);CHKERRQ(ierr);
64851e86f29SPeter Brune   }
6494a0c5b0cSMatthew G Knepley   if (snes->pc) {
650fde0ff24SPeter Brune     ierr = SNESSetOptionsPrefix(snes->pc, optionsprefix);CHKERRQ(ierr);
651fde0ff24SPeter Brune     ierr = SNESAppendOptionsPrefix(snes->pc, "npc_");CHKERRQ(ierr);
6524a0c5b0cSMatthew G Knepley     ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr);
6534a0c5b0cSMatthew G Knepley     ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr);
6544a0c5b0cSMatthew G Knepley   }
6553a40ed3dSBarry Smith   PetscFunctionReturn(0);
6569b94acceSBarry Smith }
6579b94acceSBarry Smith 
658d25893d9SBarry Smith #undef __FUNCT__
659d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext"
660d25893d9SBarry Smith /*@
661d25893d9SBarry Smith    SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for
662d25893d9SBarry Smith    the nonlinear solvers.
663d25893d9SBarry Smith 
664d25893d9SBarry Smith    Logically Collective on SNES
665d25893d9SBarry Smith 
666d25893d9SBarry Smith    Input Parameters:
667d25893d9SBarry Smith +  snes - the SNES context
668d25893d9SBarry Smith .  compute - function to compute the context
669d25893d9SBarry Smith -  destroy - function to destroy the context
670d25893d9SBarry Smith 
671d25893d9SBarry Smith    Level: intermediate
672d25893d9SBarry Smith 
673d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context
674d25893d9SBarry Smith 
675d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext()
676d25893d9SBarry Smith @*/
677d25893d9SBarry Smith PetscErrorCode  SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**))
678d25893d9SBarry Smith {
679d25893d9SBarry Smith   PetscFunctionBegin;
680d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
681d25893d9SBarry Smith   snes->ops->usercompute = compute;
682d25893d9SBarry Smith   snes->ops->userdestroy = destroy;
683d25893d9SBarry Smith   PetscFunctionReturn(0);
684d25893d9SBarry Smith }
685a847f771SSatish Balay 
6864a2ae208SSatish Balay #undef __FUNCT__
6874a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext"
688b07ff414SBarry Smith /*@
6899b94acceSBarry Smith    SNESSetApplicationContext - Sets the optional user-defined context for
6909b94acceSBarry Smith    the nonlinear solvers.
6919b94acceSBarry Smith 
6923f9fe445SBarry Smith    Logically Collective on SNES
693fee21e36SBarry Smith 
694c7afd0dbSLois Curfman McInnes    Input Parameters:
695c7afd0dbSLois Curfman McInnes +  snes - the SNES context
696c7afd0dbSLois Curfman McInnes -  usrP - optional user context
697c7afd0dbSLois Curfman McInnes 
69836851e7fSLois Curfman McInnes    Level: intermediate
69936851e7fSLois Curfman McInnes 
7009b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context
7019b94acceSBarry Smith 
702d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetApplicationContext()
7039b94acceSBarry Smith @*/
7047087cfbeSBarry Smith PetscErrorCode  SNESSetApplicationContext(SNES snes,void *usrP)
7059b94acceSBarry Smith {
7061b2093e4SBarry Smith   PetscErrorCode ierr;
707b07ff414SBarry Smith   KSP            ksp;
7081b2093e4SBarry Smith 
7093a40ed3dSBarry Smith   PetscFunctionBegin;
7100700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
711b07ff414SBarry Smith   ierr       = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
712b07ff414SBarry Smith   ierr       = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr);
7139b94acceSBarry Smith   snes->user = usrP;
7143a40ed3dSBarry Smith   PetscFunctionReturn(0);
7159b94acceSBarry Smith }
71674679c65SBarry Smith 
7174a2ae208SSatish Balay #undef __FUNCT__
7184a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext"
719b07ff414SBarry Smith /*@
7209b94acceSBarry Smith    SNESGetApplicationContext - Gets the user-defined context for the
7219b94acceSBarry Smith    nonlinear solvers.
7229b94acceSBarry Smith 
723c7afd0dbSLois Curfman McInnes    Not Collective
724c7afd0dbSLois Curfman McInnes 
7259b94acceSBarry Smith    Input Parameter:
7269b94acceSBarry Smith .  snes - SNES context
7279b94acceSBarry Smith 
7289b94acceSBarry Smith    Output Parameter:
7299b94acceSBarry Smith .  usrP - user context
7309b94acceSBarry Smith 
73136851e7fSLois Curfman McInnes    Level: intermediate
73236851e7fSLois Curfman McInnes 
7339b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context
7349b94acceSBarry Smith 
7359b94acceSBarry Smith .seealso: SNESSetApplicationContext()
7369b94acceSBarry Smith @*/
737e71120c6SJed Brown PetscErrorCode  SNESGetApplicationContext(SNES snes,void *usrP)
7389b94acceSBarry Smith {
7393a40ed3dSBarry Smith   PetscFunctionBegin;
7400700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
741e71120c6SJed Brown   *(void**)usrP = snes->user;
7423a40ed3dSBarry Smith   PetscFunctionReturn(0);
7439b94acceSBarry Smith }
74474679c65SBarry Smith 
7454a2ae208SSatish Balay #undef __FUNCT__
7464a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber"
7479b94acceSBarry Smith /*@
748c8228a4eSBarry Smith    SNESGetIterationNumber - Gets the number of nonlinear iterations completed
749c8228a4eSBarry Smith    at this time.
7509b94acceSBarry Smith 
751c7afd0dbSLois Curfman McInnes    Not Collective
752c7afd0dbSLois Curfman McInnes 
7539b94acceSBarry Smith    Input Parameter:
7549b94acceSBarry Smith .  snes - SNES context
7559b94acceSBarry Smith 
7569b94acceSBarry Smith    Output Parameter:
7579b94acceSBarry Smith .  iter - iteration number
7589b94acceSBarry Smith 
759c8228a4eSBarry Smith    Notes:
760c8228a4eSBarry Smith    For example, during the computation of iteration 2 this would return 1.
761c8228a4eSBarry Smith 
762c8228a4eSBarry Smith    This is useful for using lagged Jacobians (where one does not recompute the
76308405cd6SLois Curfman McInnes    Jacobian at each SNES iteration). For example, the code
76408405cd6SLois Curfman McInnes .vb
76508405cd6SLois Curfman McInnes       ierr = SNESGetIterationNumber(snes,&it);
76608405cd6SLois Curfman McInnes       if (!(it % 2)) {
76708405cd6SLois Curfman McInnes         [compute Jacobian here]
76808405cd6SLois Curfman McInnes       }
76908405cd6SLois Curfman McInnes .ve
770c8228a4eSBarry Smith    can be used in your ComputeJacobian() function to cause the Jacobian to be
77108405cd6SLois Curfman McInnes    recomputed every second SNES iteration.
772c8228a4eSBarry Smith 
77336851e7fSLois Curfman McInnes    Level: intermediate
77436851e7fSLois Curfman McInnes 
7752b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number,
7762b668275SBarry Smith 
777b850b91aSLisandro Dalcin .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
7789b94acceSBarry Smith @*/
7797087cfbeSBarry Smith PetscErrorCode  SNESGetIterationNumber(SNES snes,PetscInt* iter)
7809b94acceSBarry Smith {
7813a40ed3dSBarry Smith   PetscFunctionBegin;
7820700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
7834482741eSBarry Smith   PetscValidIntPointer(iter,2);
7849b94acceSBarry Smith   *iter = snes->iter;
7853a40ed3dSBarry Smith   PetscFunctionReturn(0);
7869b94acceSBarry Smith }
78774679c65SBarry Smith 
7884a2ae208SSatish Balay #undef __FUNCT__
789360c497dSPeter Brune #define __FUNCT__ "SNESSetIterationNumber"
790360c497dSPeter Brune /*@
791360c497dSPeter Brune    SNESSetIterationNumber - Sets the current iteration number.
792360c497dSPeter Brune 
793360c497dSPeter Brune    Not Collective
794360c497dSPeter Brune 
795360c497dSPeter Brune    Input Parameter:
796360c497dSPeter Brune .  snes - SNES context
797360c497dSPeter Brune .  iter - iteration number
798360c497dSPeter Brune 
799360c497dSPeter Brune    Level: developer
800360c497dSPeter Brune 
801360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number,
802360c497dSPeter Brune 
803360c497dSPeter Brune .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
804360c497dSPeter Brune @*/
805360c497dSPeter Brune PetscErrorCode  SNESSetIterationNumber(SNES snes,PetscInt iter)
806360c497dSPeter Brune {
807360c497dSPeter Brune   PetscErrorCode ierr;
808360c497dSPeter Brune 
809360c497dSPeter Brune   PetscFunctionBegin;
810360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
811360c497dSPeter Brune   ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr);
812360c497dSPeter Brune   snes->iter = iter;
813360c497dSPeter Brune   ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr);
814360c497dSPeter Brune   PetscFunctionReturn(0);
815360c497dSPeter Brune }
816360c497dSPeter Brune 
817360c497dSPeter Brune #undef __FUNCT__
8184a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm"
8199b94acceSBarry Smith /*@
8209b94acceSBarry Smith    SNESGetFunctionNorm - Gets the norm of the current function that was set
8219b94acceSBarry Smith    with SNESSSetFunction().
8229b94acceSBarry Smith 
823c7afd0dbSLois Curfman McInnes    Collective on SNES
824c7afd0dbSLois Curfman McInnes 
8259b94acceSBarry Smith    Input Parameter:
8269b94acceSBarry Smith .  snes - SNES context
8279b94acceSBarry Smith 
8289b94acceSBarry Smith    Output Parameter:
8299b94acceSBarry Smith .  fnorm - 2-norm of function
8309b94acceSBarry Smith 
83136851e7fSLois Curfman McInnes    Level: intermediate
83236851e7fSLois Curfman McInnes 
8339b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm
834a86d99e1SLois Curfman McInnes 
835b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations()
8369b94acceSBarry Smith @*/
8377087cfbeSBarry Smith PetscErrorCode  SNESGetFunctionNorm(SNES snes,PetscReal *fnorm)
8389b94acceSBarry Smith {
8393a40ed3dSBarry Smith   PetscFunctionBegin;
8400700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
8414482741eSBarry Smith   PetscValidScalarPointer(fnorm,2);
8429b94acceSBarry Smith   *fnorm = snes->norm;
8433a40ed3dSBarry Smith   PetscFunctionReturn(0);
8449b94acceSBarry Smith }
84574679c65SBarry Smith 
846360c497dSPeter Brune 
847360c497dSPeter Brune #undef __FUNCT__
848360c497dSPeter Brune #define __FUNCT__ "SNESSetFunctionNorm"
849360c497dSPeter Brune /*@
850360c497dSPeter Brune    SNESSetFunctionNorm - Sets the 2-norm of the current function computed using VecNorm().
851360c497dSPeter Brune 
852360c497dSPeter Brune    Collective on SNES
853360c497dSPeter Brune 
854360c497dSPeter Brune    Input Parameter:
855360c497dSPeter Brune .  snes - SNES context
856360c497dSPeter Brune .  fnorm - 2-norm of function
857360c497dSPeter Brune 
858360c497dSPeter Brune    Level: developer
859360c497dSPeter Brune 
860360c497dSPeter Brune .keywords: SNES, nonlinear, set, function, norm
861360c497dSPeter Brune 
862360c497dSPeter Brune .seealso: SNESSetFunction(), SNESSetIterationNumber(), VecNorm().
863360c497dSPeter Brune @*/
864360c497dSPeter Brune PetscErrorCode  SNESSetFunctionNorm(SNES snes,PetscReal fnorm)
865360c497dSPeter Brune {
866360c497dSPeter Brune 
867360c497dSPeter Brune   PetscErrorCode ierr;
868360c497dSPeter Brune 
869360c497dSPeter Brune   PetscFunctionBegin;
870360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
871360c497dSPeter Brune   ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr);
872360c497dSPeter Brune   snes->norm = fnorm;
873360c497dSPeter Brune   ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr);
874360c497dSPeter Brune   PetscFunctionReturn(0);
875360c497dSPeter Brune }
876360c497dSPeter Brune 
8774a2ae208SSatish Balay #undef __FUNCT__
878b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures"
8799b94acceSBarry Smith /*@
880b850b91aSLisandro Dalcin    SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
8819b94acceSBarry Smith    attempted by the nonlinear solver.
8829b94acceSBarry Smith 
883c7afd0dbSLois Curfman McInnes    Not Collective
884c7afd0dbSLois Curfman McInnes 
8859b94acceSBarry Smith    Input Parameter:
8869b94acceSBarry Smith .  snes - SNES context
8879b94acceSBarry Smith 
8889b94acceSBarry Smith    Output Parameter:
8899b94acceSBarry Smith .  nfails - number of unsuccessful steps attempted
8909b94acceSBarry Smith 
891c96a6f78SLois Curfman McInnes    Notes:
892c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
893c96a6f78SLois Curfman McInnes 
89436851e7fSLois Curfman McInnes    Level: intermediate
89536851e7fSLois Curfman McInnes 
8969b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
89758ebbce7SBarry Smith 
898e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
89958ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures()
9009b94acceSBarry Smith @*/
9017087cfbeSBarry Smith PetscErrorCode  SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails)
9029b94acceSBarry Smith {
9033a40ed3dSBarry Smith   PetscFunctionBegin;
9040700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9054482741eSBarry Smith   PetscValidIntPointer(nfails,2);
90650ffb88aSMatthew Knepley   *nfails = snes->numFailures;
90750ffb88aSMatthew Knepley   PetscFunctionReturn(0);
90850ffb88aSMatthew Knepley }
90950ffb88aSMatthew Knepley 
91050ffb88aSMatthew Knepley #undef __FUNCT__
911b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures"
91250ffb88aSMatthew Knepley /*@
913b850b91aSLisandro Dalcin    SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
91450ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
91550ffb88aSMatthew Knepley 
91650ffb88aSMatthew Knepley    Not Collective
91750ffb88aSMatthew Knepley 
91850ffb88aSMatthew Knepley    Input Parameters:
91950ffb88aSMatthew Knepley +  snes     - SNES context
92050ffb88aSMatthew Knepley -  maxFails - maximum of unsuccessful steps
92150ffb88aSMatthew Knepley 
92250ffb88aSMatthew Knepley    Level: intermediate
92350ffb88aSMatthew Knepley 
92450ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
92558ebbce7SBarry Smith 
926e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
92758ebbce7SBarry Smith           SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
92850ffb88aSMatthew Knepley @*/
9297087cfbeSBarry Smith PetscErrorCode  SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
93050ffb88aSMatthew Knepley {
93150ffb88aSMatthew Knepley   PetscFunctionBegin;
9320700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
93350ffb88aSMatthew Knepley   snes->maxFailures = maxFails;
93450ffb88aSMatthew Knepley   PetscFunctionReturn(0);
93550ffb88aSMatthew Knepley }
93650ffb88aSMatthew Knepley 
93750ffb88aSMatthew Knepley #undef __FUNCT__
938b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures"
93950ffb88aSMatthew Knepley /*@
940b850b91aSLisandro Dalcin    SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
94150ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
94250ffb88aSMatthew Knepley 
94350ffb88aSMatthew Knepley    Not Collective
94450ffb88aSMatthew Knepley 
94550ffb88aSMatthew Knepley    Input Parameter:
94650ffb88aSMatthew Knepley .  snes     - SNES context
94750ffb88aSMatthew Knepley 
94850ffb88aSMatthew Knepley    Output Parameter:
94950ffb88aSMatthew Knepley .  maxFails - maximum of unsuccessful steps
95050ffb88aSMatthew Knepley 
95150ffb88aSMatthew Knepley    Level: intermediate
95250ffb88aSMatthew Knepley 
95350ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
95458ebbce7SBarry Smith 
955e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
95658ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
95758ebbce7SBarry Smith 
95850ffb88aSMatthew Knepley @*/
9597087cfbeSBarry Smith PetscErrorCode  SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
96050ffb88aSMatthew Knepley {
96150ffb88aSMatthew Knepley   PetscFunctionBegin;
9620700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9634482741eSBarry Smith   PetscValidIntPointer(maxFails,2);
96450ffb88aSMatthew Knepley   *maxFails = snes->maxFailures;
9653a40ed3dSBarry Smith   PetscFunctionReturn(0);
9669b94acceSBarry Smith }
967a847f771SSatish Balay 
9684a2ae208SSatish Balay #undef __FUNCT__
9692541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals"
9702541af92SBarry Smith /*@
9712541af92SBarry Smith    SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations
9722541af92SBarry Smith      done by SNES.
9732541af92SBarry Smith 
9742541af92SBarry Smith    Not Collective
9752541af92SBarry Smith 
9762541af92SBarry Smith    Input Parameter:
9772541af92SBarry Smith .  snes     - SNES context
9782541af92SBarry Smith 
9792541af92SBarry Smith    Output Parameter:
9802541af92SBarry Smith .  nfuncs - number of evaluations
9812541af92SBarry Smith 
9822541af92SBarry Smith    Level: intermediate
9832541af92SBarry Smith 
9842541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
98558ebbce7SBarry Smith 
986e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures()
9872541af92SBarry Smith @*/
9887087cfbeSBarry Smith PetscErrorCode  SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs)
9892541af92SBarry Smith {
9902541af92SBarry Smith   PetscFunctionBegin;
9910700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9922541af92SBarry Smith   PetscValidIntPointer(nfuncs,2);
9932541af92SBarry Smith   *nfuncs = snes->nfuncs;
9942541af92SBarry Smith   PetscFunctionReturn(0);
9952541af92SBarry Smith }
9962541af92SBarry Smith 
9972541af92SBarry Smith #undef __FUNCT__
9983d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures"
9993d4c4710SBarry Smith /*@
10003d4c4710SBarry Smith    SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
10013d4c4710SBarry Smith    linear solvers.
10023d4c4710SBarry Smith 
10033d4c4710SBarry Smith    Not Collective
10043d4c4710SBarry Smith 
10053d4c4710SBarry Smith    Input Parameter:
10063d4c4710SBarry Smith .  snes - SNES context
10073d4c4710SBarry Smith 
10083d4c4710SBarry Smith    Output Parameter:
10093d4c4710SBarry Smith .  nfails - number of failed solves
10103d4c4710SBarry Smith 
10113d4c4710SBarry Smith    Notes:
10123d4c4710SBarry Smith    This counter is reset to zero for each successive call to SNESSolve().
10133d4c4710SBarry Smith 
10143d4c4710SBarry Smith    Level: intermediate
10153d4c4710SBarry Smith 
10163d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
101758ebbce7SBarry Smith 
1018e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures()
10193d4c4710SBarry Smith @*/
10207087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails)
10213d4c4710SBarry Smith {
10223d4c4710SBarry Smith   PetscFunctionBegin;
10230700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10243d4c4710SBarry Smith   PetscValidIntPointer(nfails,2);
10253d4c4710SBarry Smith   *nfails = snes->numLinearSolveFailures;
10263d4c4710SBarry Smith   PetscFunctionReturn(0);
10273d4c4710SBarry Smith }
10283d4c4710SBarry Smith 
10293d4c4710SBarry Smith #undef __FUNCT__
10303d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures"
10313d4c4710SBarry Smith /*@
10323d4c4710SBarry Smith    SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
10333d4c4710SBarry Smith    allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE
10343d4c4710SBarry Smith 
10353f9fe445SBarry Smith    Logically Collective on SNES
10363d4c4710SBarry Smith 
10373d4c4710SBarry Smith    Input Parameters:
10383d4c4710SBarry Smith +  snes     - SNES context
10393d4c4710SBarry Smith -  maxFails - maximum allowed linear solve failures
10403d4c4710SBarry Smith 
10413d4c4710SBarry Smith    Level: intermediate
10423d4c4710SBarry Smith 
1043a6796414SBarry Smith    Notes: By default this is 0; that is SNES returns on the first failed linear solve
10443d4c4710SBarry Smith 
10453d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
10463d4c4710SBarry Smith 
104758ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations()
10483d4c4710SBarry Smith @*/
10497087cfbeSBarry Smith PetscErrorCode  SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
10503d4c4710SBarry Smith {
10513d4c4710SBarry Smith   PetscFunctionBegin;
10520700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1053c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxFails,2);
10543d4c4710SBarry Smith   snes->maxLinearSolveFailures = maxFails;
10553d4c4710SBarry Smith   PetscFunctionReturn(0);
10563d4c4710SBarry Smith }
10573d4c4710SBarry Smith 
10583d4c4710SBarry Smith #undef __FUNCT__
10593d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures"
10603d4c4710SBarry Smith /*@
10613d4c4710SBarry Smith    SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
10623d4c4710SBarry Smith      are allowed before SNES terminates
10633d4c4710SBarry Smith 
10643d4c4710SBarry Smith    Not Collective
10653d4c4710SBarry Smith 
10663d4c4710SBarry Smith    Input Parameter:
10673d4c4710SBarry Smith .  snes     - SNES context
10683d4c4710SBarry Smith 
10693d4c4710SBarry Smith    Output Parameter:
10703d4c4710SBarry Smith .  maxFails - maximum of unsuccessful solves allowed
10713d4c4710SBarry Smith 
10723d4c4710SBarry Smith    Level: intermediate
10733d4c4710SBarry Smith 
10743d4c4710SBarry Smith    Notes: By default this is 1; that is SNES returns on the first failed linear solve
10753d4c4710SBarry Smith 
10763d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
10773d4c4710SBarry Smith 
1078e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(),
10793d4c4710SBarry Smith @*/
10807087cfbeSBarry Smith PetscErrorCode  SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
10813d4c4710SBarry Smith {
10823d4c4710SBarry Smith   PetscFunctionBegin;
10830700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10843d4c4710SBarry Smith   PetscValidIntPointer(maxFails,2);
10853d4c4710SBarry Smith   *maxFails = snes->maxLinearSolveFailures;
10863d4c4710SBarry Smith   PetscFunctionReturn(0);
10873d4c4710SBarry Smith }
10883d4c4710SBarry Smith 
10893d4c4710SBarry Smith #undef __FUNCT__
1090b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations"
1091c96a6f78SLois Curfman McInnes /*@
1092b850b91aSLisandro Dalcin    SNESGetLinearSolveIterations - Gets the total number of linear iterations
1093c96a6f78SLois Curfman McInnes    used by the nonlinear solver.
1094c96a6f78SLois Curfman McInnes 
1095c7afd0dbSLois Curfman McInnes    Not Collective
1096c7afd0dbSLois Curfman McInnes 
1097c96a6f78SLois Curfman McInnes    Input Parameter:
1098c96a6f78SLois Curfman McInnes .  snes - SNES context
1099c96a6f78SLois Curfman McInnes 
1100c96a6f78SLois Curfman McInnes    Output Parameter:
1101c96a6f78SLois Curfman McInnes .  lits - number of linear iterations
1102c96a6f78SLois Curfman McInnes 
1103c96a6f78SLois Curfman McInnes    Notes:
1104c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
1105c96a6f78SLois Curfman McInnes 
110636851e7fSLois Curfman McInnes    Level: intermediate
110736851e7fSLois Curfman McInnes 
1108c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations
11092b668275SBarry Smith 
11108c7482ecSBarry Smith .seealso:  SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures()
1111c96a6f78SLois Curfman McInnes @*/
11127087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveIterations(SNES snes,PetscInt* lits)
1113c96a6f78SLois Curfman McInnes {
11143a40ed3dSBarry Smith   PetscFunctionBegin;
11150700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11164482741eSBarry Smith   PetscValidIntPointer(lits,2);
1117c96a6f78SLois Curfman McInnes   *lits = snes->linear_its;
11183a40ed3dSBarry Smith   PetscFunctionReturn(0);
1119c96a6f78SLois Curfman McInnes }
1120c96a6f78SLois Curfman McInnes 
11214a2ae208SSatish Balay #undef __FUNCT__
112294b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP"
112352baeb72SSatish Balay /*@
112494b7f48cSBarry Smith    SNESGetKSP - Returns the KSP context for a SNES solver.
11259b94acceSBarry Smith 
112694b7f48cSBarry Smith    Not Collective, but if SNES object is parallel, then KSP object is parallel
1127c7afd0dbSLois Curfman McInnes 
11289b94acceSBarry Smith    Input Parameter:
11299b94acceSBarry Smith .  snes - the SNES context
11309b94acceSBarry Smith 
11319b94acceSBarry Smith    Output Parameter:
113294b7f48cSBarry Smith .  ksp - the KSP context
11339b94acceSBarry Smith 
11349b94acceSBarry Smith    Notes:
113594b7f48cSBarry Smith    The user can then directly manipulate the KSP context to set various
11369b94acceSBarry Smith    options, etc.  Likewise, the user can then extract and manipulate the
11372999313aSBarry Smith    PC contexts as well.
11389b94acceSBarry Smith 
113936851e7fSLois Curfman McInnes    Level: beginner
114036851e7fSLois Curfman McInnes 
114194b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
11429b94acceSBarry Smith 
11432999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
11449b94acceSBarry Smith @*/
11457087cfbeSBarry Smith PetscErrorCode  SNESGetKSP(SNES snes,KSP *ksp)
11469b94acceSBarry Smith {
11471cee3971SBarry Smith   PetscErrorCode ierr;
11481cee3971SBarry Smith 
11493a40ed3dSBarry Smith   PetscFunctionBegin;
11500700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11514482741eSBarry Smith   PetscValidPointer(ksp,2);
11521cee3971SBarry Smith 
11531cee3971SBarry Smith   if (!snes->ksp) {
11541cee3971SBarry Smith     ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr);
11551cee3971SBarry Smith     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr);
11561cee3971SBarry Smith     ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr);
11571cee3971SBarry Smith   }
115894b7f48cSBarry Smith   *ksp = snes->ksp;
11593a40ed3dSBarry Smith   PetscFunctionReturn(0);
11609b94acceSBarry Smith }
116182bf6240SBarry Smith 
11624a2ae208SSatish Balay #undef __FUNCT__
11632999313aSBarry Smith #define __FUNCT__ "SNESSetKSP"
11642999313aSBarry Smith /*@
11652999313aSBarry Smith    SNESSetKSP - Sets a KSP context for the SNES object to use
11662999313aSBarry Smith 
11672999313aSBarry Smith    Not Collective, but the SNES and KSP objects must live on the same MPI_Comm
11682999313aSBarry Smith 
11692999313aSBarry Smith    Input Parameters:
11702999313aSBarry Smith +  snes - the SNES context
11712999313aSBarry Smith -  ksp - the KSP context
11722999313aSBarry Smith 
11732999313aSBarry Smith    Notes:
11742999313aSBarry Smith    The SNES object already has its KSP object, you can obtain with SNESGetKSP()
11752999313aSBarry Smith    so this routine is rarely needed.
11762999313aSBarry Smith 
11772999313aSBarry Smith    The KSP object that is already in the SNES object has its reference count
11782999313aSBarry Smith    decreased by one.
11792999313aSBarry Smith 
11802999313aSBarry Smith    Level: developer
11812999313aSBarry Smith 
11822999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
11832999313aSBarry Smith 
11842999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
11852999313aSBarry Smith @*/
11867087cfbeSBarry Smith PetscErrorCode  SNESSetKSP(SNES snes,KSP ksp)
11872999313aSBarry Smith {
11882999313aSBarry Smith   PetscErrorCode ierr;
11892999313aSBarry Smith 
11902999313aSBarry Smith   PetscFunctionBegin;
11910700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11920700a824SBarry Smith   PetscValidHeaderSpecific(ksp,KSP_CLASSID,2);
11932999313aSBarry Smith   PetscCheckSameComm(snes,1,ksp,2);
11947dcf0eaaSdalcinl   ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr);
1195906ed7ccSBarry Smith   if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);}
11962999313aSBarry Smith   snes->ksp = ksp;
11972999313aSBarry Smith   PetscFunctionReturn(0);
11982999313aSBarry Smith }
11992999313aSBarry Smith 
12007adad957SLisandro Dalcin #if 0
12012999313aSBarry Smith #undef __FUNCT__
12024a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc"
12036849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj)
1204e24b481bSBarry Smith {
1205e24b481bSBarry Smith   PetscFunctionBegin;
1206e24b481bSBarry Smith   PetscFunctionReturn(0);
1207e24b481bSBarry Smith }
12087adad957SLisandro Dalcin #endif
1209e24b481bSBarry Smith 
12109b94acceSBarry Smith /* -----------------------------------------------------------*/
12114a2ae208SSatish Balay #undef __FUNCT__
12124a2ae208SSatish Balay #define __FUNCT__ "SNESCreate"
121352baeb72SSatish Balay /*@
12149b94acceSBarry Smith    SNESCreate - Creates a nonlinear solver context.
12159b94acceSBarry Smith 
1216c7afd0dbSLois Curfman McInnes    Collective on MPI_Comm
1217c7afd0dbSLois Curfman McInnes 
1218c7afd0dbSLois Curfman McInnes    Input Parameters:
1219906ed7ccSBarry Smith .  comm - MPI communicator
12209b94acceSBarry Smith 
12219b94acceSBarry Smith    Output Parameter:
12229b94acceSBarry Smith .  outsnes - the new SNES context
12239b94acceSBarry Smith 
1224c7afd0dbSLois Curfman McInnes    Options Database Keys:
1225c7afd0dbSLois Curfman McInnes +   -snes_mf - Activates default matrix-free Jacobian-vector products,
1226c7afd0dbSLois Curfman McInnes                and no preconditioning matrix
1227c7afd0dbSLois Curfman McInnes .   -snes_mf_operator - Activates default matrix-free Jacobian-vector
1228c7afd0dbSLois Curfman McInnes                products, and a user-provided preconditioning matrix
1229c7afd0dbSLois Curfman McInnes                as set by SNESSetJacobian()
1230c7afd0dbSLois Curfman McInnes -   -snes_fd - Uses (slow!) finite differences to compute Jacobian
1231c1f60f51SBarry Smith 
123236851e7fSLois Curfman McInnes    Level: beginner
123336851e7fSLois Curfman McInnes 
12349b94acceSBarry Smith .keywords: SNES, nonlinear, create, context
12359b94acceSBarry Smith 
1236a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner()
1237a8054027SBarry Smith 
12389b94acceSBarry Smith @*/
12397087cfbeSBarry Smith PetscErrorCode  SNESCreate(MPI_Comm comm,SNES *outsnes)
12409b94acceSBarry Smith {
1241dfbe8321SBarry Smith   PetscErrorCode      ierr;
12429b94acceSBarry Smith   SNES                snes;
1243fa9f3622SBarry Smith   SNESKSPEW           *kctx;
124437fcc0dbSBarry Smith 
12453a40ed3dSBarry Smith   PetscFunctionBegin;
1246ed1caa07SMatthew Knepley   PetscValidPointer(outsnes,2);
12478ba1e511SMatthew Knepley   *outsnes = PETSC_NULL;
12488ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES
12498ba1e511SMatthew Knepley   ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr);
12508ba1e511SMatthew Knepley #endif
12518ba1e511SMatthew Knepley 
12523194b578SJed Brown   ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr);
12537adad957SLisandro Dalcin 
125485385478SLisandro Dalcin   snes->ops->converged    = SNESDefaultConverged;
12552c155ee1SBarry Smith   snes->usesksp           = PETSC_TRUE;
12569b94acceSBarry Smith   snes->max_its           = 50;
12579750a799SBarry Smith   snes->max_funcs	  = 10000;
12589b94acceSBarry Smith   snes->norm		  = 0.0;
1259b4874afaSBarry Smith   snes->rtol		  = 1.e-8;
1260b4874afaSBarry Smith   snes->ttol              = 0.0;
126170441072SBarry Smith   snes->abstol		  = 1.e-50;
12629b94acceSBarry Smith   snes->xtol		  = 1.e-8;
12634b27c08aSLois Curfman McInnes   snes->deltatol	  = 1.e-12;
12649b94acceSBarry Smith   snes->nfuncs            = 0;
126550ffb88aSMatthew Knepley   snes->numFailures       = 0;
126650ffb88aSMatthew Knepley   snes->maxFailures       = 1;
12677a00f4a9SLois Curfman McInnes   snes->linear_its        = 0;
1268e35cf81dSBarry Smith   snes->lagjacobian       = 1;
1269a8054027SBarry Smith   snes->lagpreconditioner = 1;
1270639f9d9dSBarry Smith   snes->numbermonitors    = 0;
12719b94acceSBarry Smith   snes->data              = 0;
12724dc4c822SBarry Smith   snes->setupcalled       = PETSC_FALSE;
1273186905e3SBarry Smith   snes->ksp_ewconv        = PETSC_FALSE;
12746f24a144SLois Curfman McInnes   snes->nwork             = 0;
127558c9b817SLisandro Dalcin   snes->work              = 0;
127658c9b817SLisandro Dalcin   snes->nvwork            = 0;
127758c9b817SLisandro Dalcin   snes->vwork             = 0;
1278758f92a0SBarry Smith   snes->conv_hist_len     = 0;
1279758f92a0SBarry Smith   snes->conv_hist_max     = 0;
1280758f92a0SBarry Smith   snes->conv_hist         = PETSC_NULL;
1281758f92a0SBarry Smith   snes->conv_hist_its     = PETSC_NULL;
1282758f92a0SBarry Smith   snes->conv_hist_reset   = PETSC_TRUE;
1283184914b5SBarry Smith   snes->reason            = SNES_CONVERGED_ITERATING;
128489b92e6fSPeter Brune   snes->gssweeps          = 1;
12859b94acceSBarry Smith 
1286ea630c6eSPeter Brune   /* initialize the line search options */
1287ea630c6eSPeter Brune   snes->ls_type           = SNES_LS_BASIC;
1288af60355fSPeter Brune   snes->ls_its            = 1;
1289ea630c6eSPeter Brune   snes->damping           = 1.0;
1290ea630c6eSPeter Brune   snes->maxstep           = 1e8;
1291ea630c6eSPeter Brune   snes->steptol           = 1e-12;
1292ea630c6eSPeter Brune   snes->ls_alpha          = 1e-4;
1293ea630c6eSPeter Brune   snes->ls_monitor        = PETSC_NULL;
1294ea630c6eSPeter Brune 
1295ea630c6eSPeter Brune   snes->ops->linesearch   = PETSC_NULL;
1296ea630c6eSPeter Brune   snes->precheck          = PETSC_NULL;
1297ea630c6eSPeter Brune   snes->ops->precheckstep = PETSC_NULL;
1298ea630c6eSPeter Brune   snes->postcheck         = PETSC_NULL;
1299ea630c6eSPeter Brune   snes->ops->postcheckstep= PETSC_NULL;
1300ea630c6eSPeter Brune 
13013d4c4710SBarry Smith   snes->numLinearSolveFailures = 0;
13023d4c4710SBarry Smith   snes->maxLinearSolveFailures = 1;
13033d4c4710SBarry Smith 
13049b94acceSBarry Smith   /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
130538f2d2fdSLisandro Dalcin   ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr);
13069b94acceSBarry Smith   snes->kspconvctx  = (void*)kctx;
13079b94acceSBarry Smith   kctx->version     = 2;
13089b94acceSBarry Smith   kctx->rtol_0      = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
13099b94acceSBarry Smith                              this was too large for some test cases */
131075567043SBarry Smith   kctx->rtol_last   = 0.0;
13119b94acceSBarry Smith   kctx->rtol_max    = .9;
13129b94acceSBarry Smith   kctx->gamma       = 1.0;
131362d1f40fSBarry Smith   kctx->alpha       = .5*(1.0 + PetscSqrtReal(5.0));
131471f87433Sdalcinl   kctx->alpha2      = kctx->alpha;
13159b94acceSBarry Smith   kctx->threshold   = .1;
131675567043SBarry Smith   kctx->lresid_last = 0.0;
131775567043SBarry Smith   kctx->norm_last   = 0.0;
13189b94acceSBarry Smith 
13199b94acceSBarry Smith   *outsnes = snes;
13203a40ed3dSBarry Smith   PetscFunctionReturn(0);
13219b94acceSBarry Smith }
13229b94acceSBarry Smith 
13234a2ae208SSatish Balay #undef __FUNCT__
13244a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction"
13259b94acceSBarry Smith /*@C
13269b94acceSBarry Smith    SNESSetFunction - Sets the function evaluation routine and function
13279b94acceSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
13289b94acceSBarry Smith    equations.
13299b94acceSBarry Smith 
13303f9fe445SBarry Smith    Logically Collective on SNES
1331fee21e36SBarry Smith 
1332c7afd0dbSLois Curfman McInnes    Input Parameters:
1333c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1334c7afd0dbSLois Curfman McInnes .  r - vector to store function value
1335de044059SHong Zhang .  func - function evaluation routine
1336c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
1337c7afd0dbSLois Curfman McInnes          function evaluation routine (may be PETSC_NULL)
13389b94acceSBarry Smith 
1339c7afd0dbSLois Curfman McInnes    Calling sequence of func:
13408d76a1e5SLois Curfman McInnes $    func (SNES snes,Vec x,Vec f,void *ctx);
1341c7afd0dbSLois Curfman McInnes 
1342313e4042SLois Curfman McInnes .  f - function vector
1343c7afd0dbSLois Curfman McInnes -  ctx - optional user-defined function context
13449b94acceSBarry Smith 
13459b94acceSBarry Smith    Notes:
13469b94acceSBarry Smith    The Newton-like methods typically solve linear systems of the form
13479b94acceSBarry Smith $      f'(x) x = -f(x),
1348c7afd0dbSLois Curfman McInnes    where f'(x) denotes the Jacobian matrix and f(x) is the function.
13499b94acceSBarry Smith 
135036851e7fSLois Curfman McInnes    Level: beginner
135136851e7fSLois Curfman McInnes 
13529b94acceSBarry Smith .keywords: SNES, nonlinear, set, function
13539b94acceSBarry Smith 
13548b0a5094SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard()
13559b94acceSBarry Smith @*/
13567087cfbeSBarry Smith PetscErrorCode  SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx)
13579b94acceSBarry Smith {
135885385478SLisandro Dalcin   PetscErrorCode ierr;
13596cab3a1bSJed Brown   DM             dm;
13606cab3a1bSJed Brown 
13613a40ed3dSBarry Smith   PetscFunctionBegin;
13620700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1363d2a683ecSLisandro Dalcin   if (r) {
1364d2a683ecSLisandro Dalcin     PetscValidHeaderSpecific(r,VEC_CLASSID,2);
1365d2a683ecSLisandro Dalcin     PetscCheckSameComm(snes,1,r,2);
136685385478SLisandro Dalcin     ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr);
13676bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
136885385478SLisandro Dalcin     snes->vec_func = r;
1369d2a683ecSLisandro Dalcin   }
13706cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
13716cab3a1bSJed Brown   ierr = DMSNESSetFunction(dm,func,ctx);CHKERRQ(ierr);
13723a40ed3dSBarry Smith   PetscFunctionReturn(0);
13739b94acceSBarry Smith }
13749b94acceSBarry Smith 
1375646217ecSPeter Brune 
1376646217ecSPeter Brune #undef __FUNCT__
1377646217ecSPeter Brune #define __FUNCT__ "SNESSetGS"
1378c79ef259SPeter Brune /*@C
1379c79ef259SPeter Brune    SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for
1380c79ef259SPeter Brune    use with composed nonlinear solvers.
1381c79ef259SPeter Brune 
1382c79ef259SPeter Brune    Input Parameters:
1383c79ef259SPeter Brune +  snes   - the SNES context
1384c79ef259SPeter Brune .  gsfunc - function evaluation routine
1385c79ef259SPeter Brune -  ctx    - [optional] user-defined context for private data for the
1386c79ef259SPeter Brune             smoother evaluation routine (may be PETSC_NULL)
1387c79ef259SPeter Brune 
1388c79ef259SPeter Brune    Calling sequence of func:
1389c79ef259SPeter Brune $    func (SNES snes,Vec x,Vec b,void *ctx);
1390c79ef259SPeter Brune 
1391c79ef259SPeter Brune +  X   - solution vector
1392c79ef259SPeter Brune .  B   - RHS vector
1393d28543b3SPeter Brune -  ctx - optional user-defined Gauss-Seidel context
1394c79ef259SPeter Brune 
1395c79ef259SPeter Brune    Notes:
1396c79ef259SPeter Brune    The GS routines are used by the composed nonlinear solver to generate
1397c79ef259SPeter Brune     a problem appropriate update to the solution, particularly FAS.
1398c79ef259SPeter Brune 
1399d28543b3SPeter Brune    Level: intermediate
1400c79ef259SPeter Brune 
1401d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel
1402c79ef259SPeter Brune 
1403c79ef259SPeter Brune .seealso: SNESGetFunction(), SNESComputeGS()
1404c79ef259SPeter Brune @*/
14056cab3a1bSJed Brown PetscErrorCode SNESSetGS(SNES snes,PetscErrorCode (*gsfunc)(SNES,Vec,Vec,void*),void *ctx)
14066cab3a1bSJed Brown {
14076cab3a1bSJed Brown   PetscErrorCode ierr;
14086cab3a1bSJed Brown   DM dm;
14096cab3a1bSJed Brown 
1410646217ecSPeter Brune   PetscFunctionBegin;
14116cab3a1bSJed Brown   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
14126cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
14136cab3a1bSJed Brown   ierr = DMSNESSetGS(dm,gsfunc,ctx);CHKERRQ(ierr);
1414646217ecSPeter Brune   PetscFunctionReturn(0);
1415646217ecSPeter Brune }
1416646217ecSPeter Brune 
1417d25893d9SBarry Smith #undef __FUNCT__
141889b92e6fSPeter Brune #define __FUNCT__ "SNESSetGSSweeps"
141989b92e6fSPeter Brune /*@
142089b92e6fSPeter Brune    SNESSetGSSweeps - Sets the number of sweeps of GS to use.
142189b92e6fSPeter Brune 
142289b92e6fSPeter Brune    Input Parameters:
142389b92e6fSPeter Brune +  snes   - the SNES context
142489b92e6fSPeter Brune -  sweeps  - the number of sweeps of GS to perform.
142589b92e6fSPeter Brune 
142689b92e6fSPeter Brune    Level: intermediate
142789b92e6fSPeter Brune 
142889b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel
142989b92e6fSPeter Brune 
143089b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGetGSSweeps()
143189b92e6fSPeter Brune @*/
143289b92e6fSPeter Brune 
143389b92e6fSPeter Brune PetscErrorCode SNESSetGSSweeps(SNES snes, PetscInt sweeps) {
143489b92e6fSPeter Brune   PetscFunctionBegin;
143589b92e6fSPeter Brune   snes->gssweeps = sweeps;
143689b92e6fSPeter Brune   PetscFunctionReturn(0);
143789b92e6fSPeter Brune }
143889b92e6fSPeter Brune 
143989b92e6fSPeter Brune 
144089b92e6fSPeter Brune #undef __FUNCT__
144189b92e6fSPeter Brune #define __FUNCT__ "SNESGetGSSweeps"
144289b92e6fSPeter Brune /*@
144389b92e6fSPeter Brune    SNESGetGSSweeps - Gets the number of sweeps GS will use.
144489b92e6fSPeter Brune 
144589b92e6fSPeter Brune    Input Parameters:
144689b92e6fSPeter Brune .  snes   - the SNES context
144789b92e6fSPeter Brune 
144889b92e6fSPeter Brune    Output Parameters:
144989b92e6fSPeter Brune .  sweeps  - the number of sweeps of GS to perform.
145089b92e6fSPeter Brune 
145189b92e6fSPeter Brune    Level: intermediate
145289b92e6fSPeter Brune 
145389b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel
145489b92e6fSPeter Brune 
145589b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESSetGSSweeps()
145689b92e6fSPeter Brune @*/
145789b92e6fSPeter Brune PetscErrorCode SNESGetGSSweeps(SNES snes, PetscInt * sweeps) {
145889b92e6fSPeter Brune   PetscFunctionBegin;
145989b92e6fSPeter Brune   *sweeps = snes->gssweeps;
146089b92e6fSPeter Brune   PetscFunctionReturn(0);
146189b92e6fSPeter Brune }
146289b92e6fSPeter Brune 
146389b92e6fSPeter Brune #undef __FUNCT__
14648b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction"
14658b0a5094SBarry Smith PetscErrorCode  SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx)
14668b0a5094SBarry Smith {
14678b0a5094SBarry Smith   PetscErrorCode ierr;
14686cab3a1bSJed Brown   void *functx,*jacctx;
14696cab3a1bSJed Brown 
14708b0a5094SBarry Smith   PetscFunctionBegin;
14716cab3a1bSJed Brown   ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
14726cab3a1bSJed Brown   ierr = SNESGetJacobian(snes,PETSC_NULL,PETSC_NULL,PETSC_NULL,&jacctx);CHKERRQ(ierr);
14738b0a5094SBarry Smith   /*  A(x)*x - b(x) */
14746cab3a1bSJed Brown   ierr = (*snes->ops->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,jacctx);CHKERRQ(ierr);
14756cab3a1bSJed Brown   ierr = (*snes->ops->computepfunction)(snes,x,f,functx);CHKERRQ(ierr);
14768b0a5094SBarry Smith   ierr = VecView(x,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr);
14778b0a5094SBarry Smith   ierr = VecView(f,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr);
14788b0a5094SBarry Smith   ierr = VecScale(f,-1.0);CHKERRQ(ierr);
14798b0a5094SBarry Smith   ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr);
14808b0a5094SBarry Smith   PetscFunctionReturn(0);
14818b0a5094SBarry Smith }
14828b0a5094SBarry Smith 
14838b0a5094SBarry Smith #undef __FUNCT__
14848b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian"
14858b0a5094SBarry Smith PetscErrorCode  SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx)
14868b0a5094SBarry Smith {
14878b0a5094SBarry Smith   PetscFunctionBegin;
14888b0a5094SBarry Smith   *flag = snes->matstruct;
14898b0a5094SBarry Smith   PetscFunctionReturn(0);
14908b0a5094SBarry Smith }
14918b0a5094SBarry Smith 
14928b0a5094SBarry Smith #undef __FUNCT__
14938b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard"
14948b0a5094SBarry Smith /*@C
14950d04baf8SBarry Smith    SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization)
14968b0a5094SBarry Smith 
14978b0a5094SBarry Smith    Logically Collective on SNES
14988b0a5094SBarry Smith 
14998b0a5094SBarry Smith    Input Parameters:
15008b0a5094SBarry Smith +  snes - the SNES context
15018b0a5094SBarry Smith .  r - vector to store function value
15028b0a5094SBarry Smith .  func - function evaluation routine
15038b0a5094SBarry Smith .  jmat - normally the same as mat but you can pass another matrix for which you compute the Jacobian of A(x) x - b(x) (see jmat below)
15048b0a5094SBarry Smith .  mat - matrix to store A
15058b0a5094SBarry Smith .  mfunc  - function to compute matrix value
15068b0a5094SBarry Smith -  ctx - [optional] user-defined context for private data for the
15078b0a5094SBarry Smith          function evaluation routine (may be PETSC_NULL)
15088b0a5094SBarry Smith 
15098b0a5094SBarry Smith    Calling sequence of func:
15108b0a5094SBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
15118b0a5094SBarry Smith 
15128b0a5094SBarry Smith +  f - function vector
15138b0a5094SBarry Smith -  ctx - optional user-defined function context
15148b0a5094SBarry Smith 
15158b0a5094SBarry Smith    Calling sequence of mfunc:
15168b0a5094SBarry Smith $     mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx);
15178b0a5094SBarry Smith 
15188b0a5094SBarry Smith +  x - input vector
15198b0a5094SBarry Smith .  jmat - Form Jacobian matrix of A(x) x - b(x) if available, not there is really no reason to use it in this way since then you can just use SNESSetJacobian(),
15208b0a5094SBarry Smith           normally just pass mat in this location
15218b0a5094SBarry Smith .  mat - form A(x) matrix
15228b0a5094SBarry Smith .  flag - flag indicating information about the preconditioner matrix
15238b0a5094SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
15248b0a5094SBarry Smith -  ctx - [optional] user-defined Jacobian context
15258b0a5094SBarry Smith 
15268b0a5094SBarry Smith    Notes:
15278b0a5094SBarry Smith     One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both
15288b0a5094SBarry Smith 
15298b0a5094SBarry Smith $     Solves the equation A(x) x = b(x) via the defect correction algorithm A(x^{n}) (x^{n+1} - x^{n}) = b(x^{n}) - A(x^{n})x^{n}
15308b0a5094SBarry Smith $     Note that when an exact solver is used this corresponds to the "classic" Picard A(x^{n}) x^{n+1} = b(x^{n}) iteration.
15318b0a5094SBarry Smith 
15328b0a5094SBarry Smith      Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner.
15338b0a5094SBarry Smith 
15340d04baf8SBarry Smith    We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then
15350d04baf8SBarry Smith    the direct Picard iteration A(x^n) x^{n+1} = b(x^n)
15368b0a5094SBarry Smith 
15378b0a5094SBarry Smith    There is some controversity over the definition of a Picard iteration for nonlinear systems but almost everyone agrees that it involves a linear solve and some
15388b0a5094SBarry Smith    believe it is the iteration  A(x^{n}) x^{n+1} = b(x^{n}) hence we use the name Picard. If anyone has an authoritative  reference that defines the Picard iteration
15398b0a5094SBarry Smith    different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-).
15408b0a5094SBarry Smith 
15418b0a5094SBarry Smith    Level: beginner
15428b0a5094SBarry Smith 
15438b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function
15448b0a5094SBarry Smith 
15450d04baf8SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard()
15468b0a5094SBarry Smith @*/
15478b0a5094SBarry Smith PetscErrorCode  SNESSetPicard(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),Mat jmat, Mat mat, PetscErrorCode (*mfunc)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
15488b0a5094SBarry Smith {
15498b0a5094SBarry Smith   PetscErrorCode ierr;
15508b0a5094SBarry Smith   PetscFunctionBegin;
15518b0a5094SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
15528b0a5094SBarry Smith   snes->ops->computepfunction = func;
15538b0a5094SBarry Smith   snes->ops->computepjacobian = mfunc;
15548b0a5094SBarry Smith   ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr);
15558b0a5094SBarry Smith   ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr);
15568b0a5094SBarry Smith   PetscFunctionReturn(0);
15578b0a5094SBarry Smith }
15588b0a5094SBarry Smith 
15598b0a5094SBarry Smith #undef __FUNCT__
1560d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess"
1561d25893d9SBarry Smith /*@C
1562d25893d9SBarry Smith    SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem
1563d25893d9SBarry Smith 
1564d25893d9SBarry Smith    Logically Collective on SNES
1565d25893d9SBarry Smith 
1566d25893d9SBarry Smith    Input Parameters:
1567d25893d9SBarry Smith +  snes - the SNES context
1568d25893d9SBarry Smith .  func - function evaluation routine
1569d25893d9SBarry Smith -  ctx - [optional] user-defined context for private data for the
1570d25893d9SBarry Smith          function evaluation routine (may be PETSC_NULL)
1571d25893d9SBarry Smith 
1572d25893d9SBarry Smith    Calling sequence of func:
1573d25893d9SBarry Smith $    func (SNES snes,Vec x,void *ctx);
1574d25893d9SBarry Smith 
1575d25893d9SBarry Smith .  f - function vector
1576d25893d9SBarry Smith -  ctx - optional user-defined function context
1577d25893d9SBarry Smith 
1578d25893d9SBarry Smith    Level: intermediate
1579d25893d9SBarry Smith 
1580d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function
1581d25893d9SBarry Smith 
1582d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
1583d25893d9SBarry Smith @*/
1584d25893d9SBarry Smith PetscErrorCode  SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx)
1585d25893d9SBarry Smith {
1586d25893d9SBarry Smith   PetscFunctionBegin;
1587d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1588d25893d9SBarry Smith   if (func) snes->ops->computeinitialguess = func;
1589d25893d9SBarry Smith   if (ctx)  snes->initialguessP            = ctx;
1590d25893d9SBarry Smith   PetscFunctionReturn(0);
1591d25893d9SBarry Smith }
1592d25893d9SBarry Smith 
15933ab0aad5SBarry Smith /* --------------------------------------------------------------- */
15943ab0aad5SBarry Smith #undef __FUNCT__
15951096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs"
15961096aae1SMatthew Knepley /*@C
15971096aae1SMatthew Knepley    SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
15981096aae1SMatthew Knepley    it assumes a zero right hand side.
15991096aae1SMatthew Knepley 
16003f9fe445SBarry Smith    Logically Collective on SNES
16011096aae1SMatthew Knepley 
16021096aae1SMatthew Knepley    Input Parameter:
16031096aae1SMatthew Knepley .  snes - the SNES context
16041096aae1SMatthew Knepley 
16051096aae1SMatthew Knepley    Output Parameter:
1606bc08b0f1SBarry Smith .  rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null
16071096aae1SMatthew Knepley 
16081096aae1SMatthew Knepley    Level: intermediate
16091096aae1SMatthew Knepley 
16101096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side
16111096aae1SMatthew Knepley 
161285385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
16131096aae1SMatthew Knepley @*/
16147087cfbeSBarry Smith PetscErrorCode  SNESGetRhs(SNES snes,Vec *rhs)
16151096aae1SMatthew Knepley {
16161096aae1SMatthew Knepley   PetscFunctionBegin;
16170700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
16181096aae1SMatthew Knepley   PetscValidPointer(rhs,2);
161985385478SLisandro Dalcin   *rhs = snes->vec_rhs;
16201096aae1SMatthew Knepley   PetscFunctionReturn(0);
16211096aae1SMatthew Knepley }
16221096aae1SMatthew Knepley 
16231096aae1SMatthew Knepley #undef __FUNCT__
16244a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction"
16259b94acceSBarry Smith /*@
162636851e7fSLois Curfman McInnes    SNESComputeFunction - Calls the function that has been set with
16279b94acceSBarry Smith                          SNESSetFunction().
16289b94acceSBarry Smith 
1629c7afd0dbSLois Curfman McInnes    Collective on SNES
1630c7afd0dbSLois Curfman McInnes 
16319b94acceSBarry Smith    Input Parameters:
1632c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1633c7afd0dbSLois Curfman McInnes -  x - input vector
16349b94acceSBarry Smith 
16359b94acceSBarry Smith    Output Parameter:
16363638b69dSLois Curfman McInnes .  y - function vector, as set by SNESSetFunction()
16379b94acceSBarry Smith 
16381bffabb2SLois Curfman McInnes    Notes:
163936851e7fSLois Curfman McInnes    SNESComputeFunction() is typically used within nonlinear solvers
164036851e7fSLois Curfman McInnes    implementations, so most users would not generally call this routine
164136851e7fSLois Curfman McInnes    themselves.
164236851e7fSLois Curfman McInnes 
164336851e7fSLois Curfman McInnes    Level: developer
164436851e7fSLois Curfman McInnes 
16459b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function
16469b94acceSBarry Smith 
1647a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction()
16489b94acceSBarry Smith @*/
16497087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction(SNES snes,Vec x,Vec y)
16509b94acceSBarry Smith {
1651dfbe8321SBarry Smith   PetscErrorCode ierr;
16526cab3a1bSJed Brown   DM             dm;
16536cab3a1bSJed Brown   SNESDM         sdm;
16549b94acceSBarry Smith 
16553a40ed3dSBarry Smith   PetscFunctionBegin;
16560700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
16570700a824SBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
16580700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
1659c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,x,2);
1660c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,3);
16614ec14c9cSBarry Smith   VecValidValues(x,2,PETSC_TRUE);
1662184914b5SBarry Smith 
16636cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
16646cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
1665d5ba7fb7SMatthew Knepley   ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
16666cab3a1bSJed Brown   if (sdm->computefunction) {
1667d64ed03dSBarry Smith     PetscStackPush("SNES user function");
16686cab3a1bSJed Brown     ierr = (*sdm->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr);
1669d64ed03dSBarry Smith     PetscStackPop;
167073250ac0SBarry Smith   } else if (snes->dm) {
1671644e2e5bSBarry Smith     ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr);
1672c90fad12SPeter Brune   } else if (snes->vec_rhs) {
1673c90fad12SPeter Brune     ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr);
1674644e2e5bSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve().");
167585385478SLisandro Dalcin   if (snes->vec_rhs) {
167685385478SLisandro Dalcin     ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr);
16773ab0aad5SBarry Smith   }
1678ae3c334cSLois Curfman McInnes   snes->nfuncs++;
1679d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
16804ec14c9cSBarry Smith   VecValidValues(y,3,PETSC_FALSE);
16813a40ed3dSBarry Smith   PetscFunctionReturn(0);
16829b94acceSBarry Smith }
16839b94acceSBarry Smith 
16844a2ae208SSatish Balay #undef __FUNCT__
1685646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS"
1686c79ef259SPeter Brune /*@
1687c79ef259SPeter Brune    SNESComputeGS - Calls the Gauss-Seidel function that has been set with
1688c79ef259SPeter Brune                    SNESSetGS().
1689c79ef259SPeter Brune 
1690c79ef259SPeter Brune    Collective on SNES
1691c79ef259SPeter Brune 
1692c79ef259SPeter Brune    Input Parameters:
1693c79ef259SPeter Brune +  snes - the SNES context
1694c79ef259SPeter Brune .  x - input vector
1695c79ef259SPeter Brune -  b - rhs vector
1696c79ef259SPeter Brune 
1697c79ef259SPeter Brune    Output Parameter:
1698c79ef259SPeter Brune .  x - new solution vector
1699c79ef259SPeter Brune 
1700c79ef259SPeter Brune    Notes:
1701c79ef259SPeter Brune    SNESComputeGS() is typically used within composed nonlinear solver
1702c79ef259SPeter Brune    implementations, so most users would not generally call this routine
1703c79ef259SPeter Brune    themselves.
1704c79ef259SPeter Brune 
1705c79ef259SPeter Brune    Level: developer
1706c79ef259SPeter Brune 
1707c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function
1708c79ef259SPeter Brune 
1709c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction()
1710c79ef259SPeter Brune @*/
1711646217ecSPeter Brune PetscErrorCode  SNESComputeGS(SNES snes,Vec b,Vec x)
1712646217ecSPeter Brune {
1713646217ecSPeter Brune   PetscErrorCode ierr;
171489b92e6fSPeter Brune   PetscInt i;
17156cab3a1bSJed Brown   DM dm;
17166cab3a1bSJed Brown   SNESDM sdm;
1717646217ecSPeter Brune 
1718646217ecSPeter Brune   PetscFunctionBegin;
1719646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1720646217ecSPeter Brune   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
1721646217ecSPeter Brune   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3);
1722646217ecSPeter Brune   PetscCheckSameComm(snes,1,x,2);
1723646217ecSPeter Brune   if(b) PetscCheckSameComm(snes,1,b,3);
17244ec14c9cSBarry Smith   if (b) VecValidValues(b,2,PETSC_TRUE);
1725701cf23dSPeter Brune   ierr = PetscLogEventBegin(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr);
17266cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
17276cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
17286cab3a1bSJed Brown   if (sdm->computegs) {
172989b92e6fSPeter Brune     for (i = 0; i < snes->gssweeps; i++) {
1730646217ecSPeter Brune       PetscStackPush("SNES user GS");
17316cab3a1bSJed Brown       ierr = (*sdm->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr);
1732646217ecSPeter Brune       PetscStackPop;
173389b92e6fSPeter Brune     }
1734646217ecSPeter Brune   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve().");
1735701cf23dSPeter Brune   ierr = PetscLogEventEnd(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr);
17364ec14c9cSBarry Smith   VecValidValues(x,3,PETSC_FALSE);
1737646217ecSPeter Brune   PetscFunctionReturn(0);
1738646217ecSPeter Brune }
1739646217ecSPeter Brune 
1740646217ecSPeter Brune 
1741646217ecSPeter Brune #undef __FUNCT__
17424a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian"
174362fef451SLois Curfman McInnes /*@
174462fef451SLois Curfman McInnes    SNESComputeJacobian - Computes the Jacobian matrix that has been
174562fef451SLois Curfman McInnes    set with SNESSetJacobian().
174662fef451SLois Curfman McInnes 
1747c7afd0dbSLois Curfman McInnes    Collective on SNES and Mat
1748c7afd0dbSLois Curfman McInnes 
174962fef451SLois Curfman McInnes    Input Parameters:
1750c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1751c7afd0dbSLois Curfman McInnes -  x - input vector
175262fef451SLois Curfman McInnes 
175362fef451SLois Curfman McInnes    Output Parameters:
1754c7afd0dbSLois Curfman McInnes +  A - Jacobian matrix
175562fef451SLois Curfman McInnes .  B - optional preconditioning matrix
17562b668275SBarry Smith -  flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER)
1757fee21e36SBarry Smith 
1758e35cf81dSBarry Smith   Options Database Keys:
1759e35cf81dSBarry Smith +    -snes_lag_preconditioner <lag>
1760693365a8SJed Brown .    -snes_lag_jacobian <lag>
1761693365a8SJed Brown .    -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences
1762693365a8SJed Brown .    -snes_compare_explicit_draw  - Compare the computed Jacobian to the finite difference Jacobian and draw the result
1763693365a8SJed Brown .    -snes_compare_explicit_contour  - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result
17644c30e9fbSJed Brown .    -snes_compare_operator  - Make the comparison options above use the operator instead of the preconditioning matrix
1765c01495d3SJed Brown .    -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference
1766c01495d3SJed Brown .    -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences
1767c01495d3SJed Brown .    -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold
1768c01495d3SJed Brown .    -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
1769c01495d3SJed Brown .    -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
17704c30e9fbSJed Brown .    -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences
1771c01495d3SJed Brown -    -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences
1772c01495d3SJed Brown 
1773e35cf81dSBarry Smith 
177462fef451SLois Curfman McInnes    Notes:
177562fef451SLois Curfman McInnes    Most users should not need to explicitly call this routine, as it
177662fef451SLois Curfman McInnes    is used internally within the nonlinear solvers.
177762fef451SLois Curfman McInnes 
177894b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the
1779dc5a77f8SLois Curfman McInnes    flag parameter.
178062fef451SLois Curfman McInnes 
178136851e7fSLois Curfman McInnes    Level: developer
178236851e7fSLois Curfman McInnes 
178362fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix
178462fef451SLois Curfman McInnes 
1785e35cf81dSBarry Smith .seealso:  SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian()
178662fef451SLois Curfman McInnes @*/
17877087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg)
17889b94acceSBarry Smith {
1789dfbe8321SBarry Smith   PetscErrorCode ierr;
1790ace3abfcSBarry Smith   PetscBool      flag;
17916cab3a1bSJed Brown   DM             dm;
17926cab3a1bSJed Brown   SNESDM         sdm;
17933a40ed3dSBarry Smith 
17943a40ed3dSBarry Smith   PetscFunctionBegin;
17950700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
17960700a824SBarry Smith   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
17974482741eSBarry Smith   PetscValidPointer(flg,5);
1798c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,X,2);
17994ec14c9cSBarry Smith   VecValidValues(X,2,PETSC_TRUE);
18006cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
18016cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
18026cab3a1bSJed Brown   if (!sdm->computejacobian) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc");
1803ebd3b9afSBarry Smith 
1804ebd3b9afSBarry Smith   /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */
1805ebd3b9afSBarry Smith 
1806fe3ffe1eSBarry Smith   if (snes->lagjacobian == -2) {
1807fe3ffe1eSBarry Smith     snes->lagjacobian = -1;
1808fe3ffe1eSBarry Smith     ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr);
1809fe3ffe1eSBarry Smith   } else if (snes->lagjacobian == -1) {
1810e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
1811e35cf81dSBarry Smith     ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr);
1812ebd3b9afSBarry Smith     ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
1813ebd3b9afSBarry Smith     if (flag) {
1814ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1815ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1816ebd3b9afSBarry Smith     }
1817e35cf81dSBarry Smith     PetscFunctionReturn(0);
1818e35cf81dSBarry Smith   } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) {
1819e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
1820e35cf81dSBarry Smith     ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr);
1821ebd3b9afSBarry Smith     ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
1822ebd3b9afSBarry Smith     if (flag) {
1823ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1824ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1825ebd3b9afSBarry Smith     }
1826e35cf81dSBarry Smith     PetscFunctionReturn(0);
1827e35cf81dSBarry Smith   }
1828e35cf81dSBarry Smith 
1829c4fc05e7SBarry Smith   *flg = DIFFERENT_NONZERO_PATTERN;
1830e35cf81dSBarry Smith   ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
1831d64ed03dSBarry Smith   PetscStackPush("SNES user Jacobian function");
18326cab3a1bSJed Brown   ierr = (*sdm->computejacobian)(snes,X,A,B,flg,sdm->jacobianctx);CHKERRQ(ierr);
1833d64ed03dSBarry Smith   PetscStackPop;
1834d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
1835a8054027SBarry Smith 
18363b4f5425SBarry Smith   if (snes->lagpreconditioner == -2) {
18373b4f5425SBarry Smith     ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr);
18383b4f5425SBarry Smith     snes->lagpreconditioner = -1;
18393b4f5425SBarry Smith   } else if (snes->lagpreconditioner == -1) {
1840a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
1841a8054027SBarry Smith     ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr);
1842a8054027SBarry Smith   } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) {
1843a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
1844a8054027SBarry Smith     ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr);
1845a8054027SBarry Smith   }
1846a8054027SBarry Smith 
18476d84be18SBarry Smith   /* make sure user returned a correct Jacobian and preconditioner */
18480700a824SBarry Smith   /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3);
18490700a824SBarry Smith     PetscValidHeaderSpecific(*B,MAT_CLASSID,4);   */
1850693365a8SJed Brown   {
1851693365a8SJed Brown     PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE;
1852693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr);
1853693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr);
1854693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr);
1855693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr);
1856693365a8SJed Brown     if (flag || flag_draw || flag_contour) {
1857693365a8SJed Brown       Mat Bexp_mine = PETSC_NULL,Bexp,FDexp;
1858693365a8SJed Brown       MatStructure mstruct;
1859693365a8SJed Brown       PetscViewer vdraw,vstdout;
18606b3a5b13SJed Brown       PetscBool flg;
1861693365a8SJed Brown       if (flag_operator) {
1862693365a8SJed Brown         ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr);
1863693365a8SJed Brown         Bexp = Bexp_mine;
1864693365a8SJed Brown       } else {
1865693365a8SJed Brown         /* See if the preconditioning matrix can be viewed and added directly */
1866693365a8SJed Brown         ierr = PetscTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr);
1867693365a8SJed Brown         if (flg) Bexp = *B;
1868693365a8SJed Brown         else {
1869693365a8SJed Brown           /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */
1870693365a8SJed Brown           ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr);
1871693365a8SJed Brown           Bexp = Bexp_mine;
1872693365a8SJed Brown         }
1873693365a8SJed Brown       }
1874693365a8SJed Brown       ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr);
1875693365a8SJed Brown       ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr);
1876693365a8SJed Brown       ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr);
1877693365a8SJed Brown       if (flag_draw || flag_contour) {
1878693365a8SJed Brown         ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
1879693365a8SJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
1880693365a8SJed Brown       } else vdraw = PETSC_NULL;
1881693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr);
1882693365a8SJed Brown       if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);}
1883693365a8SJed Brown       if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);}
1884693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr);
1885693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
1886693365a8SJed Brown       if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);}
1887693365a8SJed Brown       ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
1888693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr);
1889693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
1890693365a8SJed Brown       if (vdraw) {              /* Always use contour for the difference */
1891693365a8SJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
1892693365a8SJed Brown         ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);
1893693365a8SJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
1894693365a8SJed Brown       }
1895693365a8SJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
1896693365a8SJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
1897693365a8SJed Brown       ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr);
1898693365a8SJed Brown       ierr = MatDestroy(&FDexp);CHKERRQ(ierr);
1899693365a8SJed Brown     }
1900693365a8SJed Brown   }
19014c30e9fbSJed Brown   {
19026719d8e4SJed Brown     PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE;
19036719d8e4SJed Brown     PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON;
19044c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr);
19056719d8e4SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr);
19064c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr);
19074c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr);
19086719d8e4SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr);
19096719d8e4SJed Brown     ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr);
19106719d8e4SJed Brown     ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr);
19116719d8e4SJed Brown     if (flag || flag_display || flag_draw || flag_contour || flag_threshold) {
19124c30e9fbSJed Brown       Mat Bfd;
19134c30e9fbSJed Brown       MatStructure mstruct;
19144c30e9fbSJed Brown       PetscViewer vdraw,vstdout;
19154c30e9fbSJed Brown       ISColoring iscoloring;
19164c30e9fbSJed Brown       MatFDColoring matfdcoloring;
19174c30e9fbSJed Brown       PetscErrorCode (*func)(SNES,Vec,Vec,void*);
19184c30e9fbSJed Brown       void *funcctx;
19196719d8e4SJed Brown       PetscReal norm1,norm2,normmax;
19204c30e9fbSJed Brown 
19214c30e9fbSJed Brown       ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr);
19224c30e9fbSJed Brown       ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr);
19234c30e9fbSJed Brown       ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr);
19244c30e9fbSJed Brown       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
19254c30e9fbSJed Brown 
19264c30e9fbSJed Brown       /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */
19274c30e9fbSJed Brown       ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr);
19284c30e9fbSJed Brown       ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr);
19294c30e9fbSJed Brown       ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr);
19304c30e9fbSJed Brown       ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr);
19314c30e9fbSJed Brown       ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr);
19324c30e9fbSJed Brown       ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr);
19334c30e9fbSJed Brown       ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr);
19344c30e9fbSJed Brown 
19354c30e9fbSJed Brown       ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr);
19364c30e9fbSJed Brown       if (flag_draw || flag_contour) {
19374c30e9fbSJed Brown         ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
19384c30e9fbSJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
19394c30e9fbSJed Brown       } else vdraw = PETSC_NULL;
19404c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr);
19416719d8e4SJed Brown       if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);}
19424c30e9fbSJed Brown       if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);}
19434c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr);
19446719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
19454c30e9fbSJed Brown       if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);}
19464c30e9fbSJed Brown       ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
19474c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr);
19486719d8e4SJed Brown       ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr);
19494c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr);
19506719d8e4SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr);
19516719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
19524c30e9fbSJed Brown       if (vdraw) {              /* Always use contour for the difference */
19534c30e9fbSJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
19544c30e9fbSJed Brown         ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);
19554c30e9fbSJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
19564c30e9fbSJed Brown       }
19574c30e9fbSJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
19586719d8e4SJed Brown 
19596719d8e4SJed Brown       if (flag_threshold) {
19606719d8e4SJed Brown         PetscInt bs,rstart,rend,i;
19616719d8e4SJed Brown         ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr);
19626719d8e4SJed Brown         ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr);
19636719d8e4SJed Brown         for (i=rstart; i<rend; i++) {
19646719d8e4SJed Brown           const PetscScalar *ba,*ca;
19656719d8e4SJed Brown           const PetscInt *bj,*cj;
19666719d8e4SJed Brown           PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1;
19676719d8e4SJed Brown           PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0;
19686719d8e4SJed Brown           ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr);
19696719d8e4SJed Brown           ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
19706719d8e4SJed Brown           if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold");
19716719d8e4SJed Brown           for (j=0; j<bn; j++) {
19726719d8e4SJed Brown             PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
19736719d8e4SJed Brown             if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) {
19746719d8e4SJed Brown               maxentrycol = bj[j];
19756719d8e4SJed Brown               maxentry = PetscRealPart(ba[j]);
19766719d8e4SJed Brown             }
19776719d8e4SJed Brown             if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) {
19786719d8e4SJed Brown               maxdiffcol = bj[j];
19796719d8e4SJed Brown               maxdiff = PetscRealPart(ca[j]);
19806719d8e4SJed Brown             }
19816719d8e4SJed Brown             if (rdiff > maxrdiff) {
19826719d8e4SJed Brown               maxrdiffcol = bj[j];
19836719d8e4SJed Brown               maxrdiff = rdiff;
19846719d8e4SJed Brown             }
19856719d8e4SJed Brown           }
19866719d8e4SJed Brown           if (maxrdiff > 1) {
19876719d8e4SJed Brown             ierr = PetscViewerASCIIPrintf(vstdout,"row %D (maxentry=%G at %D, maxdiff=%G at %D, maxrdiff=%G at %D):",i,maxentry,maxentrycol,maxdiff,maxdiffcol,maxrdiff,maxrdiffcol);CHKERRQ(ierr);
19886719d8e4SJed Brown             for (j=0; j<bn; j++) {
19896719d8e4SJed Brown               PetscReal rdiff;
19906719d8e4SJed Brown               rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
19916719d8e4SJed Brown               if (rdiff > 1) {
19926719d8e4SJed Brown                 ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr);
19936719d8e4SJed Brown               }
19946719d8e4SJed Brown             }
19956719d8e4SJed Brown             ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr);
19966719d8e4SJed Brown           }
19976719d8e4SJed Brown           ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr);
19986719d8e4SJed Brown           ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
19996719d8e4SJed Brown         }
20006719d8e4SJed Brown       }
20014c30e9fbSJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
20024c30e9fbSJed Brown       ierr = MatDestroy(&Bfd);CHKERRQ(ierr);
20034c30e9fbSJed Brown     }
20044c30e9fbSJed Brown   }
20053a40ed3dSBarry Smith   PetscFunctionReturn(0);
20069b94acceSBarry Smith }
20079b94acceSBarry Smith 
20084a2ae208SSatish Balay #undef __FUNCT__
20094a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian"
20109b94acceSBarry Smith /*@C
20119b94acceSBarry Smith    SNESSetJacobian - Sets the function to compute Jacobian as well as the
2012044dda88SLois Curfman McInnes    location to store the matrix.
20139b94acceSBarry Smith 
20143f9fe445SBarry Smith    Logically Collective on SNES and Mat
2015c7afd0dbSLois Curfman McInnes 
20169b94acceSBarry Smith    Input Parameters:
2017c7afd0dbSLois Curfman McInnes +  snes - the SNES context
20189b94acceSBarry Smith .  A - Jacobian matrix
20199b94acceSBarry Smith .  B - preconditioner matrix (usually same as the Jacobian)
2020efd51863SBarry Smith .  func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value)
2021c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
2022efd51863SBarry Smith          Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value)
20239b94acceSBarry Smith 
20249b94acceSBarry Smith    Calling sequence of func:
20258d76a1e5SLois Curfman McInnes $     func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx);
20269b94acceSBarry Smith 
2027c7afd0dbSLois Curfman McInnes +  x - input vector
20289b94acceSBarry Smith .  A - Jacobian matrix
20299b94acceSBarry Smith .  B - preconditioner matrix, usually the same as A
2030ac21db08SLois Curfman McInnes .  flag - flag indicating information about the preconditioner matrix
20312b668275SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
2032c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined Jacobian context
20339b94acceSBarry Smith 
20349b94acceSBarry Smith    Notes:
203594b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the flag
20362cd2dfdcSLois Curfman McInnes    output parameter in the routine func().  Be sure to read this information!
2037ac21db08SLois Curfman McInnes 
2038ac21db08SLois Curfman McInnes    The routine func() takes Mat * as the matrix arguments rather than Mat.
20399b94acceSBarry Smith    This allows the Jacobian evaluation routine to replace A and/or B with a
20409b94acceSBarry Smith    completely new new matrix structure (not just different matrix elements)
20419b94acceSBarry Smith    when appropriate, for instance, if the nonzero structure is changing
20429b94acceSBarry Smith    throughout the global iterations.
20439b94acceSBarry Smith 
204416913363SBarry Smith    If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on
204516913363SBarry Smith    each matrix.
204616913363SBarry Smith 
2047a8a26c1eSJed Brown    If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument
2048a8a26c1eSJed Brown    must be a MatFDColoring.
2049a8a26c1eSJed Brown 
2050c3cc8fd1SJed Brown    Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian.  One common
2051c3cc8fd1SJed Brown    example is to use the "Picard linearization" which only differentiates through the highest order parts of each term.
2052c3cc8fd1SJed Brown 
205336851e7fSLois Curfman McInnes    Level: beginner
205436851e7fSLois Curfman McInnes 
20559b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix
20569b94acceSBarry Smith 
20573ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure
20589b94acceSBarry Smith @*/
20597087cfbeSBarry Smith PetscErrorCode  SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
20609b94acceSBarry Smith {
2061dfbe8321SBarry Smith   PetscErrorCode ierr;
20626cab3a1bSJed Brown   DM             dm;
20633a7fca6bSBarry Smith 
20643a40ed3dSBarry Smith   PetscFunctionBegin;
20650700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
20660700a824SBarry Smith   if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2);
20670700a824SBarry Smith   if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3);
2068c9780b6fSBarry Smith   if (A) PetscCheckSameComm(snes,1,A,2);
206906975374SJed Brown   if (B) PetscCheckSameComm(snes,1,B,3);
20706cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
20716cab3a1bSJed Brown   ierr = DMSNESSetJacobian(dm,func,ctx);CHKERRQ(ierr);
20723a7fca6bSBarry Smith   if (A) {
20737dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
20746bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
20759b94acceSBarry Smith     snes->jacobian = A;
20763a7fca6bSBarry Smith   }
20773a7fca6bSBarry Smith   if (B) {
20787dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr);
20796bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
20809b94acceSBarry Smith     snes->jacobian_pre = B;
20813a7fca6bSBarry Smith   }
20823a40ed3dSBarry Smith   PetscFunctionReturn(0);
20839b94acceSBarry Smith }
208462fef451SLois Curfman McInnes 
20854a2ae208SSatish Balay #undef __FUNCT__
20864a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian"
2087c2aafc4cSSatish Balay /*@C
2088b4fd4287SBarry Smith    SNESGetJacobian - Returns the Jacobian matrix and optionally the user
2089b4fd4287SBarry Smith    provided context for evaluating the Jacobian.
2090b4fd4287SBarry Smith 
2091c7afd0dbSLois Curfman McInnes    Not Collective, but Mat object will be parallel if SNES object is
2092c7afd0dbSLois Curfman McInnes 
2093b4fd4287SBarry Smith    Input Parameter:
2094b4fd4287SBarry Smith .  snes - the nonlinear solver context
2095b4fd4287SBarry Smith 
2096b4fd4287SBarry Smith    Output Parameters:
2097c7afd0dbSLois Curfman McInnes +  A - location to stash Jacobian matrix (or PETSC_NULL)
2098b4fd4287SBarry Smith .  B - location to stash preconditioner matrix (or PETSC_NULL)
209970e92668SMatthew Knepley .  func - location to put Jacobian function (or PETSC_NULL)
210070e92668SMatthew Knepley -  ctx - location to stash Jacobian ctx (or PETSC_NULL)
2101fee21e36SBarry Smith 
210236851e7fSLois Curfman McInnes    Level: advanced
210336851e7fSLois Curfman McInnes 
2104b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian()
2105b4fd4287SBarry Smith @*/
21067087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
2107b4fd4287SBarry Smith {
21086cab3a1bSJed Brown   PetscErrorCode ierr;
21096cab3a1bSJed Brown   DM             dm;
21106cab3a1bSJed Brown   SNESDM         sdm;
21116cab3a1bSJed Brown 
21123a40ed3dSBarry Smith   PetscFunctionBegin;
21130700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2114b4fd4287SBarry Smith   if (A)    *A    = snes->jacobian;
2115b4fd4287SBarry Smith   if (B)    *B    = snes->jacobian_pre;
21166cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
21176cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
21186cab3a1bSJed Brown   if (func) *func = sdm->computejacobian;
21196cab3a1bSJed Brown   if (ctx)  *ctx  = sdm->jacobianctx;
21203a40ed3dSBarry Smith   PetscFunctionReturn(0);
2121b4fd4287SBarry Smith }
2122b4fd4287SBarry Smith 
21239b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */
21249b94acceSBarry Smith 
21254a2ae208SSatish Balay #undef __FUNCT__
21264a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp"
21279b94acceSBarry Smith /*@
21289b94acceSBarry Smith    SNESSetUp - Sets up the internal data structures for the later use
2129272ac6f2SLois Curfman McInnes    of a nonlinear solver.
21309b94acceSBarry Smith 
2131fee21e36SBarry Smith    Collective on SNES
2132fee21e36SBarry Smith 
2133c7afd0dbSLois Curfman McInnes    Input Parameters:
213470e92668SMatthew Knepley .  snes - the SNES context
2135c7afd0dbSLois Curfman McInnes 
2136272ac6f2SLois Curfman McInnes    Notes:
2137272ac6f2SLois Curfman McInnes    For basic use of the SNES solvers the user need not explicitly call
2138272ac6f2SLois Curfman McInnes    SNESSetUp(), since these actions will automatically occur during
2139272ac6f2SLois Curfman McInnes    the call to SNESSolve().  However, if one wishes to control this
2140272ac6f2SLois Curfman McInnes    phase separately, SNESSetUp() should be called after SNESCreate()
2141272ac6f2SLois Curfman McInnes    and optional routines of the form SNESSetXXX(), but before SNESSolve().
2142272ac6f2SLois Curfman McInnes 
214336851e7fSLois Curfman McInnes    Level: advanced
214436851e7fSLois Curfman McInnes 
21459b94acceSBarry Smith .keywords: SNES, nonlinear, setup
21469b94acceSBarry Smith 
21479b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
21489b94acceSBarry Smith @*/
21497087cfbeSBarry Smith PetscErrorCode  SNESSetUp(SNES snes)
21509b94acceSBarry Smith {
2151dfbe8321SBarry Smith   PetscErrorCode ierr;
21526cab3a1bSJed Brown   DM             dm;
21536cab3a1bSJed Brown   SNESDM         sdm;
21543a40ed3dSBarry Smith 
21553a40ed3dSBarry Smith   PetscFunctionBegin;
21560700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
21574dc4c822SBarry Smith   if (snes->setupcalled) PetscFunctionReturn(0);
21589b94acceSBarry Smith 
21597adad957SLisandro Dalcin   if (!((PetscObject)snes)->type_name) {
216085385478SLisandro Dalcin     ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr);
216185385478SLisandro Dalcin   }
216285385478SLisandro Dalcin 
2163a63bb30eSJed Brown   ierr = SNESGetFunction(snes,&snes->vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
216417186662SBarry Smith   if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
216558c9b817SLisandro Dalcin   if (snes->vec_rhs  == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector");
216658c9b817SLisandro Dalcin 
216758c9b817SLisandro Dalcin   if (!snes->vec_sol_update /* && snes->vec_sol */) {
216858c9b817SLisandro Dalcin     ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr);
216958c9b817SLisandro Dalcin     ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr);
217058c9b817SLisandro Dalcin   }
217158c9b817SLisandro Dalcin 
21726cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
21736cab3a1bSJed Brown   ierr = DMSNESSetUpLegacy(dm);CHKERRQ(ierr); /* To be removed when function routines are taken out of the DM package */
21746cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
21756cab3a1bSJed Brown   if (!sdm->computefunction) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction(), DMSNESSetFunction(), DMDASNESSetFunctionLocal(), etc");
21766cab3a1bSJed Brown   if (!snes->vec_func) {
21776cab3a1bSJed Brown     ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr);
2178214df951SJed Brown   }
2179efd51863SBarry Smith 
2180b710008aSBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);}
2181b710008aSBarry Smith 
2182d25893d9SBarry Smith   if (snes->ops->usercompute && !snes->user) {
2183d25893d9SBarry Smith     ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr);
2184d25893d9SBarry Smith   }
2185d25893d9SBarry Smith 
2186410397dcSLisandro Dalcin   if (snes->ops->setup) {
2187410397dcSLisandro Dalcin     ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr);
2188410397dcSLisandro Dalcin   }
218958c9b817SLisandro Dalcin 
21907aaed0d8SBarry Smith   snes->setupcalled = PETSC_TRUE;
21913a40ed3dSBarry Smith   PetscFunctionReturn(0);
21929b94acceSBarry Smith }
21939b94acceSBarry Smith 
21944a2ae208SSatish Balay #undef __FUNCT__
219537596af1SLisandro Dalcin #define __FUNCT__ "SNESReset"
219637596af1SLisandro Dalcin /*@
219737596af1SLisandro Dalcin    SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats
219837596af1SLisandro Dalcin 
219937596af1SLisandro Dalcin    Collective on SNES
220037596af1SLisandro Dalcin 
220137596af1SLisandro Dalcin    Input Parameter:
220237596af1SLisandro Dalcin .  snes - iterative context obtained from SNESCreate()
220337596af1SLisandro Dalcin 
2204d25893d9SBarry Smith    Level: intermediate
2205d25893d9SBarry Smith 
2206d25893d9SBarry Smith    Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext()
220737596af1SLisandro Dalcin 
220837596af1SLisandro Dalcin .keywords: SNES, destroy
220937596af1SLisandro Dalcin 
221037596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve()
221137596af1SLisandro Dalcin @*/
221237596af1SLisandro Dalcin PetscErrorCode  SNESReset(SNES snes)
221337596af1SLisandro Dalcin {
221437596af1SLisandro Dalcin   PetscErrorCode ierr;
221537596af1SLisandro Dalcin 
221637596af1SLisandro Dalcin   PetscFunctionBegin;
221737596af1SLisandro Dalcin   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2218d25893d9SBarry Smith   if (snes->ops->userdestroy && snes->user) {
2219d25893d9SBarry Smith     ierr       = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr);
2220d25893d9SBarry Smith     snes->user = PETSC_NULL;
2221d25893d9SBarry Smith   }
22228a23116dSBarry Smith   if (snes->pc) {
22238a23116dSBarry Smith     ierr = SNESReset(snes->pc);CHKERRQ(ierr);
22248a23116dSBarry Smith   }
22258a23116dSBarry Smith 
222637596af1SLisandro Dalcin   if (snes->ops->reset) {
222737596af1SLisandro Dalcin     ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr);
222837596af1SLisandro Dalcin   }
222937596af1SLisandro Dalcin   if (snes->ksp) {ierr = KSPReset(snes->ksp);CHKERRQ(ierr);}
22306bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
22316bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
22326bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr);
22336bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
22346bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
22356bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
2236c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);
2237c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);
223837596af1SLisandro Dalcin   snes->nwork = snes->nvwork = 0;
223937596af1SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
224037596af1SLisandro Dalcin   PetscFunctionReturn(0);
224137596af1SLisandro Dalcin }
224237596af1SLisandro Dalcin 
224337596af1SLisandro Dalcin #undef __FUNCT__
22444a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy"
224552baeb72SSatish Balay /*@
22469b94acceSBarry Smith    SNESDestroy - Destroys the nonlinear solver context that was created
22479b94acceSBarry Smith    with SNESCreate().
22489b94acceSBarry Smith 
2249c7afd0dbSLois Curfman McInnes    Collective on SNES
2250c7afd0dbSLois Curfman McInnes 
22519b94acceSBarry Smith    Input Parameter:
22529b94acceSBarry Smith .  snes - the SNES context
22539b94acceSBarry Smith 
225436851e7fSLois Curfman McInnes    Level: beginner
225536851e7fSLois Curfman McInnes 
22569b94acceSBarry Smith .keywords: SNES, nonlinear, destroy
22579b94acceSBarry Smith 
225863a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve()
22599b94acceSBarry Smith @*/
22606bf464f9SBarry Smith PetscErrorCode  SNESDestroy(SNES *snes)
22619b94acceSBarry Smith {
22626849ba73SBarry Smith   PetscErrorCode ierr;
22633a40ed3dSBarry Smith 
22643a40ed3dSBarry Smith   PetscFunctionBegin;
22656bf464f9SBarry Smith   if (!*snes) PetscFunctionReturn(0);
22666bf464f9SBarry Smith   PetscValidHeaderSpecific((*snes),SNES_CLASSID,1);
22676bf464f9SBarry Smith   if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);}
2268d4bb536fSBarry Smith 
22696bf464f9SBarry Smith   ierr = SNESReset((*snes));CHKERRQ(ierr);
22708a23116dSBarry Smith   ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr);
22716b8b9a38SLisandro Dalcin 
2272be0abb6dSBarry Smith   /* if memory was published with AMS then destroy it */
22736bf464f9SBarry Smith   ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr);
22746bf464f9SBarry Smith   if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);}
22756d4c513bSLisandro Dalcin 
22766bf464f9SBarry Smith   ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr);
22776bf464f9SBarry Smith   ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr);
22786b8b9a38SLisandro Dalcin 
22796bf464f9SBarry Smith   ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr);
22806bf464f9SBarry Smith   if ((*snes)->ops->convergeddestroy) {
22816bf464f9SBarry Smith     ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr);
22826b8b9a38SLisandro Dalcin   }
22836bf464f9SBarry Smith   if ((*snes)->conv_malloc) {
22846bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr);
22856bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr);
228658c9b817SLisandro Dalcin   }
2287ea630c6eSPeter Brune   ierr = PetscViewerDestroy(&(*snes)->ls_monitor);CHKERRQ(ierr);
22886bf464f9SBarry Smith   ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr);
2289a79aaaedSSatish Balay   ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr);
22903a40ed3dSBarry Smith  PetscFunctionReturn(0);
22919b94acceSBarry Smith }
22929b94acceSBarry Smith 
22939b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */
22949b94acceSBarry Smith 
22954a2ae208SSatish Balay #undef __FUNCT__
2296a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner"
2297a8054027SBarry Smith /*@
2298a8054027SBarry Smith    SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.
2299a8054027SBarry Smith 
23003f9fe445SBarry Smith    Logically Collective on SNES
2301a8054027SBarry Smith 
2302a8054027SBarry Smith    Input Parameters:
2303a8054027SBarry Smith +  snes - the SNES context
2304a8054027SBarry 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
23053b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2306a8054027SBarry Smith 
2307a8054027SBarry Smith    Options Database Keys:
2308a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2309a8054027SBarry Smith 
2310a8054027SBarry Smith    Notes:
2311a8054027SBarry Smith    The default is 1
2312a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2313a8054027SBarry Smith    If  -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use
2314a8054027SBarry Smith 
2315a8054027SBarry Smith    Level: intermediate
2316a8054027SBarry Smith 
2317a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2318a8054027SBarry Smith 
2319e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2320a8054027SBarry Smith 
2321a8054027SBarry Smith @*/
23227087cfbeSBarry Smith PetscErrorCode  SNESSetLagPreconditioner(SNES snes,PetscInt lag)
2323a8054027SBarry Smith {
2324a8054027SBarry Smith   PetscFunctionBegin;
23250700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2326e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2327e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2328c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2329a8054027SBarry Smith   snes->lagpreconditioner = lag;
2330a8054027SBarry Smith   PetscFunctionReturn(0);
2331a8054027SBarry Smith }
2332a8054027SBarry Smith 
2333a8054027SBarry Smith #undef __FUNCT__
2334efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence"
2335efd51863SBarry Smith /*@
2336efd51863SBarry Smith    SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does
2337efd51863SBarry Smith 
2338efd51863SBarry Smith    Logically Collective on SNES
2339efd51863SBarry Smith 
2340efd51863SBarry Smith    Input Parameters:
2341efd51863SBarry Smith +  snes - the SNES context
2342efd51863SBarry Smith -  steps - the number of refinements to do, defaults to 0
2343efd51863SBarry Smith 
2344efd51863SBarry Smith    Options Database Keys:
2345efd51863SBarry Smith .    -snes_grid_sequence <steps>
2346efd51863SBarry Smith 
2347efd51863SBarry Smith    Level: intermediate
2348efd51863SBarry Smith 
2349c0df2a02SJed Brown    Notes:
2350c0df2a02SJed Brown    Use SNESGetSolution() to extract the fine grid solution after grid sequencing.
2351c0df2a02SJed Brown 
2352efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2353efd51863SBarry Smith 
2354efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2355efd51863SBarry Smith 
2356efd51863SBarry Smith @*/
2357efd51863SBarry Smith PetscErrorCode  SNESSetGridSequence(SNES snes,PetscInt steps)
2358efd51863SBarry Smith {
2359efd51863SBarry Smith   PetscFunctionBegin;
2360efd51863SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2361efd51863SBarry Smith   PetscValidLogicalCollectiveInt(snes,steps,2);
2362efd51863SBarry Smith   snes->gridsequence = steps;
2363efd51863SBarry Smith   PetscFunctionReturn(0);
2364efd51863SBarry Smith }
2365efd51863SBarry Smith 
2366efd51863SBarry Smith #undef __FUNCT__
2367a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner"
2368a8054027SBarry Smith /*@
2369a8054027SBarry Smith    SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt
2370a8054027SBarry Smith 
23713f9fe445SBarry Smith    Not Collective
2372a8054027SBarry Smith 
2373a8054027SBarry Smith    Input Parameter:
2374a8054027SBarry Smith .  snes - the SNES context
2375a8054027SBarry Smith 
2376a8054027SBarry Smith    Output Parameter:
2377a8054027SBarry 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
23783b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2379a8054027SBarry Smith 
2380a8054027SBarry Smith    Options Database Keys:
2381a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2382a8054027SBarry Smith 
2383a8054027SBarry Smith    Notes:
2384a8054027SBarry Smith    The default is 1
2385a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2386a8054027SBarry Smith 
2387a8054027SBarry Smith    Level: intermediate
2388a8054027SBarry Smith 
2389a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2390a8054027SBarry Smith 
2391a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner()
2392a8054027SBarry Smith 
2393a8054027SBarry Smith @*/
23947087cfbeSBarry Smith PetscErrorCode  SNESGetLagPreconditioner(SNES snes,PetscInt *lag)
2395a8054027SBarry Smith {
2396a8054027SBarry Smith   PetscFunctionBegin;
23970700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2398a8054027SBarry Smith   *lag = snes->lagpreconditioner;
2399a8054027SBarry Smith   PetscFunctionReturn(0);
2400a8054027SBarry Smith }
2401a8054027SBarry Smith 
2402a8054027SBarry Smith #undef __FUNCT__
2403e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian"
2404e35cf81dSBarry Smith /*@
2405e35cf81dSBarry Smith    SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how
2406e35cf81dSBarry Smith      often the preconditioner is rebuilt.
2407e35cf81dSBarry Smith 
24083f9fe445SBarry Smith    Logically Collective on SNES
2409e35cf81dSBarry Smith 
2410e35cf81dSBarry Smith    Input Parameters:
2411e35cf81dSBarry Smith +  snes - the SNES context
2412e35cf81dSBarry 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
2413fe3ffe1eSBarry Smith          the Jacobian is built etc. -2 means rebuild at next chance but then never again
2414e35cf81dSBarry Smith 
2415e35cf81dSBarry Smith    Options Database Keys:
2416e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2417e35cf81dSBarry Smith 
2418e35cf81dSBarry Smith    Notes:
2419e35cf81dSBarry Smith    The default is 1
2420e35cf81dSBarry Smith    The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2421fe3ffe1eSBarry 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
2422fe3ffe1eSBarry Smith    at the next Newton step but never again (unless it is reset to another value)
2423e35cf81dSBarry Smith 
2424e35cf81dSBarry Smith    Level: intermediate
2425e35cf81dSBarry Smith 
2426e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2427e35cf81dSBarry Smith 
2428e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian()
2429e35cf81dSBarry Smith 
2430e35cf81dSBarry Smith @*/
24317087cfbeSBarry Smith PetscErrorCode  SNESSetLagJacobian(SNES snes,PetscInt lag)
2432e35cf81dSBarry Smith {
2433e35cf81dSBarry Smith   PetscFunctionBegin;
24340700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2435e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2436e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2437c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2438e35cf81dSBarry Smith   snes->lagjacobian = lag;
2439e35cf81dSBarry Smith   PetscFunctionReturn(0);
2440e35cf81dSBarry Smith }
2441e35cf81dSBarry Smith 
2442e35cf81dSBarry Smith #undef __FUNCT__
2443e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian"
2444e35cf81dSBarry Smith /*@
2445e35cf81dSBarry Smith    SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt
2446e35cf81dSBarry Smith 
24473f9fe445SBarry Smith    Not Collective
2448e35cf81dSBarry Smith 
2449e35cf81dSBarry Smith    Input Parameter:
2450e35cf81dSBarry Smith .  snes - the SNES context
2451e35cf81dSBarry Smith 
2452e35cf81dSBarry Smith    Output Parameter:
2453e35cf81dSBarry 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
2454e35cf81dSBarry Smith          the Jacobian is built etc.
2455e35cf81dSBarry Smith 
2456e35cf81dSBarry Smith    Options Database Keys:
2457e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2458e35cf81dSBarry Smith 
2459e35cf81dSBarry Smith    Notes:
2460e35cf81dSBarry Smith    The default is 1
2461e35cf81dSBarry Smith    The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2462e35cf81dSBarry Smith 
2463e35cf81dSBarry Smith    Level: intermediate
2464e35cf81dSBarry Smith 
2465e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2466e35cf81dSBarry Smith 
2467e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner()
2468e35cf81dSBarry Smith 
2469e35cf81dSBarry Smith @*/
24707087cfbeSBarry Smith PetscErrorCode  SNESGetLagJacobian(SNES snes,PetscInt *lag)
2471e35cf81dSBarry Smith {
2472e35cf81dSBarry Smith   PetscFunctionBegin;
24730700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2474e35cf81dSBarry Smith   *lag = snes->lagjacobian;
2475e35cf81dSBarry Smith   PetscFunctionReturn(0);
2476e35cf81dSBarry Smith }
2477e35cf81dSBarry Smith 
2478e35cf81dSBarry Smith #undef __FUNCT__
24794a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances"
24809b94acceSBarry Smith /*@
2481d7a720efSLois Curfman McInnes    SNESSetTolerances - Sets various parameters used in convergence tests.
24829b94acceSBarry Smith 
24833f9fe445SBarry Smith    Logically Collective on SNES
2484c7afd0dbSLois Curfman McInnes 
24859b94acceSBarry Smith    Input Parameters:
2486c7afd0dbSLois Curfman McInnes +  snes - the SNES context
248770441072SBarry Smith .  abstol - absolute convergence tolerance
248833174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
248933174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
249033174efeSLois Curfman McInnes            of the change in the solution between steps
249133174efeSLois Curfman McInnes .  maxit - maximum number of iterations
2492c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
2493fee21e36SBarry Smith 
249433174efeSLois Curfman McInnes    Options Database Keys:
249570441072SBarry Smith +    -snes_atol <abstol> - Sets abstol
2496c7afd0dbSLois Curfman McInnes .    -snes_rtol <rtol> - Sets rtol
2497c7afd0dbSLois Curfman McInnes .    -snes_stol <stol> - Sets stol
2498c7afd0dbSLois Curfman McInnes .    -snes_max_it <maxit> - Sets maxit
2499c7afd0dbSLois Curfman McInnes -    -snes_max_funcs <maxf> - Sets maxf
25009b94acceSBarry Smith 
2501d7a720efSLois Curfman McInnes    Notes:
25029b94acceSBarry Smith    The default maximum number of iterations is 50.
25039b94acceSBarry Smith    The default maximum number of function evaluations is 1000.
25049b94acceSBarry Smith 
250536851e7fSLois Curfman McInnes    Level: intermediate
250636851e7fSLois Curfman McInnes 
250733174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances
25089b94acceSBarry Smith 
25092492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance()
25109b94acceSBarry Smith @*/
25117087cfbeSBarry Smith PetscErrorCode  SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
25129b94acceSBarry Smith {
25133a40ed3dSBarry Smith   PetscFunctionBegin;
25140700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2515c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,abstol,2);
2516c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol,3);
2517c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,stol,4);
2518c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxit,5);
2519c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxf,6);
2520c5eb9154SBarry Smith 
2521ab54825eSJed Brown   if (abstol != PETSC_DEFAULT) {
2522ab54825eSJed Brown     if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol);
2523ab54825eSJed Brown     snes->abstol = abstol;
2524ab54825eSJed Brown   }
2525ab54825eSJed Brown   if (rtol != PETSC_DEFAULT) {
2526ab54825eSJed 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);
2527ab54825eSJed Brown     snes->rtol = rtol;
2528ab54825eSJed Brown   }
2529ab54825eSJed Brown   if (stol != PETSC_DEFAULT) {
2530ab54825eSJed Brown     if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol);
2531ab54825eSJed Brown     snes->xtol = stol;
2532ab54825eSJed Brown   }
2533ab54825eSJed Brown   if (maxit != PETSC_DEFAULT) {
2534ab54825eSJed Brown     if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit);
2535ab54825eSJed Brown     snes->max_its = maxit;
2536ab54825eSJed Brown   }
2537ab54825eSJed Brown   if (maxf != PETSC_DEFAULT) {
2538ab54825eSJed Brown     if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf);
2539ab54825eSJed Brown     snes->max_funcs = maxf;
2540ab54825eSJed Brown   }
25413a40ed3dSBarry Smith   PetscFunctionReturn(0);
25429b94acceSBarry Smith }
25439b94acceSBarry Smith 
25444a2ae208SSatish Balay #undef __FUNCT__
25454a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances"
25469b94acceSBarry Smith /*@
254733174efeSLois Curfman McInnes    SNESGetTolerances - Gets various parameters used in convergence tests.
254833174efeSLois Curfman McInnes 
2549c7afd0dbSLois Curfman McInnes    Not Collective
2550c7afd0dbSLois Curfman McInnes 
255133174efeSLois Curfman McInnes    Input Parameters:
2552c7afd0dbSLois Curfman McInnes +  snes - the SNES context
255385385478SLisandro Dalcin .  atol - absolute convergence tolerance
255433174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
255533174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
255633174efeSLois Curfman McInnes            of the change in the solution between steps
255733174efeSLois Curfman McInnes .  maxit - maximum number of iterations
2558c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
2559fee21e36SBarry Smith 
256033174efeSLois Curfman McInnes    Notes:
256133174efeSLois Curfman McInnes    The user can specify PETSC_NULL for any parameter that is not needed.
256233174efeSLois Curfman McInnes 
256336851e7fSLois Curfman McInnes    Level: intermediate
256436851e7fSLois Curfman McInnes 
256533174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances
256633174efeSLois Curfman McInnes 
256733174efeSLois Curfman McInnes .seealso: SNESSetTolerances()
256833174efeSLois Curfman McInnes @*/
25697087cfbeSBarry Smith PetscErrorCode  SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
257033174efeSLois Curfman McInnes {
25713a40ed3dSBarry Smith   PetscFunctionBegin;
25720700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
257385385478SLisandro Dalcin   if (atol)  *atol  = snes->abstol;
257433174efeSLois Curfman McInnes   if (rtol)  *rtol  = snes->rtol;
257533174efeSLois Curfman McInnes   if (stol)  *stol  = snes->xtol;
257633174efeSLois Curfman McInnes   if (maxit) *maxit = snes->max_its;
257733174efeSLois Curfman McInnes   if (maxf)  *maxf  = snes->max_funcs;
25783a40ed3dSBarry Smith   PetscFunctionReturn(0);
257933174efeSLois Curfman McInnes }
258033174efeSLois Curfman McInnes 
25814a2ae208SSatish Balay #undef __FUNCT__
25824a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance"
258333174efeSLois Curfman McInnes /*@
25849b94acceSBarry Smith    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
25859b94acceSBarry Smith 
25863f9fe445SBarry Smith    Logically Collective on SNES
2587fee21e36SBarry Smith 
2588c7afd0dbSLois Curfman McInnes    Input Parameters:
2589c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2590c7afd0dbSLois Curfman McInnes -  tol - tolerance
2591c7afd0dbSLois Curfman McInnes 
25929b94acceSBarry Smith    Options Database Key:
2593c7afd0dbSLois Curfman McInnes .  -snes_trtol <tol> - Sets tol
25949b94acceSBarry Smith 
259536851e7fSLois Curfman McInnes    Level: intermediate
259636851e7fSLois Curfman McInnes 
25979b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance
25989b94acceSBarry Smith 
25992492ecdbSBarry Smith .seealso: SNESSetTolerances()
26009b94acceSBarry Smith @*/
26017087cfbeSBarry Smith PetscErrorCode  SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
26029b94acceSBarry Smith {
26033a40ed3dSBarry Smith   PetscFunctionBegin;
26040700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2605c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,tol,2);
26069b94acceSBarry Smith   snes->deltatol = tol;
26073a40ed3dSBarry Smith   PetscFunctionReturn(0);
26089b94acceSBarry Smith }
26099b94acceSBarry Smith 
2610df9fa365SBarry Smith /*
2611df9fa365SBarry Smith    Duplicate the lg monitors for SNES from KSP; for some reason with
2612df9fa365SBarry Smith    dynamic libraries things don't work under Sun4 if we just use
2613df9fa365SBarry Smith    macros instead of functions
2614df9fa365SBarry Smith */
26154a2ae208SSatish Balay #undef __FUNCT__
2616a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG"
26177087cfbeSBarry Smith PetscErrorCode  SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx)
2618ce1608b8SBarry Smith {
2619dfbe8321SBarry Smith   PetscErrorCode ierr;
2620ce1608b8SBarry Smith 
2621ce1608b8SBarry Smith   PetscFunctionBegin;
26220700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2623a6570f20SBarry Smith   ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr);
2624ce1608b8SBarry Smith   PetscFunctionReturn(0);
2625ce1608b8SBarry Smith }
2626ce1608b8SBarry Smith 
26274a2ae208SSatish Balay #undef __FUNCT__
2628a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate"
26297087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2630df9fa365SBarry Smith {
2631dfbe8321SBarry Smith   PetscErrorCode ierr;
2632df9fa365SBarry Smith 
2633df9fa365SBarry Smith   PetscFunctionBegin;
2634a6570f20SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2635df9fa365SBarry Smith   PetscFunctionReturn(0);
2636df9fa365SBarry Smith }
2637df9fa365SBarry Smith 
26384a2ae208SSatish Balay #undef __FUNCT__
2639a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy"
26406bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGDestroy(PetscDrawLG *draw)
2641df9fa365SBarry Smith {
2642dfbe8321SBarry Smith   PetscErrorCode ierr;
2643df9fa365SBarry Smith 
2644df9fa365SBarry Smith   PetscFunctionBegin;
2645a6570f20SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2646df9fa365SBarry Smith   PetscFunctionReturn(0);
2647df9fa365SBarry Smith }
2648df9fa365SBarry Smith 
26497087cfbeSBarry Smith extern PetscErrorCode  SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
2650b271bb04SBarry Smith #undef __FUNCT__
2651b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange"
26527087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx)
2653b271bb04SBarry Smith {
2654b271bb04SBarry Smith   PetscDrawLG      lg;
2655b271bb04SBarry Smith   PetscErrorCode   ierr;
2656b271bb04SBarry Smith   PetscReal        x,y,per;
2657b271bb04SBarry Smith   PetscViewer      v = (PetscViewer)monctx;
2658b271bb04SBarry Smith   static PetscReal prev; /* should be in the context */
2659b271bb04SBarry Smith   PetscDraw        draw;
2660b271bb04SBarry Smith   PetscFunctionBegin;
2661b271bb04SBarry Smith   if (!monctx) {
2662b271bb04SBarry Smith     MPI_Comm    comm;
2663b271bb04SBarry Smith 
2664b271bb04SBarry Smith     ierr   = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
2665b271bb04SBarry Smith     v      = PETSC_VIEWER_DRAW_(comm);
2666b271bb04SBarry Smith   }
2667b271bb04SBarry Smith   ierr   = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr);
2668b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2669b271bb04SBarry Smith   ierr   = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2670b271bb04SBarry Smith   ierr   = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr);
2671b271bb04SBarry Smith   x = (PetscReal) n;
2672b271bb04SBarry Smith   if (rnorm > 0.0) y = log10(rnorm); else y = -15.0;
2673b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2674b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2675b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2676b271bb04SBarry Smith   }
2677b271bb04SBarry Smith 
2678b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr);
2679b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2680b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2681b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr);
2682b271bb04SBarry Smith   ierr =  SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr);
2683b271bb04SBarry Smith   x = (PetscReal) n;
2684b271bb04SBarry Smith   y = 100.0*per;
2685b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2686b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2687b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2688b271bb04SBarry Smith   }
2689b271bb04SBarry Smith 
2690b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr);
2691b271bb04SBarry Smith   if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2692b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2693b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr);
2694b271bb04SBarry Smith   x = (PetscReal) n;
2695b271bb04SBarry Smith   y = (prev - rnorm)/prev;
2696b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2697b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2698b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2699b271bb04SBarry Smith   }
2700b271bb04SBarry Smith 
2701b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr);
2702b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2703b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2704b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr);
2705b271bb04SBarry Smith   x = (PetscReal) n;
2706b271bb04SBarry Smith   y = (prev - rnorm)/(prev*per);
2707b271bb04SBarry Smith   if (n > 2) { /*skip initial crazy value */
2708b271bb04SBarry Smith     ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2709b271bb04SBarry Smith   }
2710b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2711b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2712b271bb04SBarry Smith   }
2713b271bb04SBarry Smith   prev = rnorm;
2714b271bb04SBarry Smith   PetscFunctionReturn(0);
2715b271bb04SBarry Smith }
2716b271bb04SBarry Smith 
2717b271bb04SBarry Smith #undef __FUNCT__
2718b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate"
27197087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2720b271bb04SBarry Smith {
2721b271bb04SBarry Smith   PetscErrorCode ierr;
2722b271bb04SBarry Smith 
2723b271bb04SBarry Smith   PetscFunctionBegin;
2724b271bb04SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2725b271bb04SBarry Smith   PetscFunctionReturn(0);
2726b271bb04SBarry Smith }
2727b271bb04SBarry Smith 
2728b271bb04SBarry Smith #undef __FUNCT__
2729b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy"
27306bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGRangeDestroy(PetscDrawLG *draw)
2731b271bb04SBarry Smith {
2732b271bb04SBarry Smith   PetscErrorCode ierr;
2733b271bb04SBarry Smith 
2734b271bb04SBarry Smith   PetscFunctionBegin;
2735b271bb04SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2736b271bb04SBarry Smith   PetscFunctionReturn(0);
2737b271bb04SBarry Smith }
2738b271bb04SBarry Smith 
27397a03ce2fSLisandro Dalcin #undef __FUNCT__
27407a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor"
2741228d79bcSJed Brown /*@
2742228d79bcSJed Brown    SNESMonitor - runs the user provided monitor routines, if they exist
2743228d79bcSJed Brown 
2744228d79bcSJed Brown    Collective on SNES
2745228d79bcSJed Brown 
2746228d79bcSJed Brown    Input Parameters:
2747228d79bcSJed Brown +  snes - nonlinear solver context obtained from SNESCreate()
2748228d79bcSJed Brown .  iter - iteration number
2749228d79bcSJed Brown -  rnorm - relative norm of the residual
2750228d79bcSJed Brown 
2751228d79bcSJed Brown    Notes:
2752228d79bcSJed Brown    This routine is called by the SNES implementations.
2753228d79bcSJed Brown    It does not typically need to be called by the user.
2754228d79bcSJed Brown 
2755228d79bcSJed Brown    Level: developer
2756228d79bcSJed Brown 
2757228d79bcSJed Brown .seealso: SNESMonitorSet()
2758228d79bcSJed Brown @*/
27597a03ce2fSLisandro Dalcin PetscErrorCode  SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm)
27607a03ce2fSLisandro Dalcin {
27617a03ce2fSLisandro Dalcin   PetscErrorCode ierr;
27627a03ce2fSLisandro Dalcin   PetscInt       i,n = snes->numbermonitors;
27637a03ce2fSLisandro Dalcin 
27647a03ce2fSLisandro Dalcin   PetscFunctionBegin;
27657a03ce2fSLisandro Dalcin   for (i=0; i<n; i++) {
27667a03ce2fSLisandro Dalcin     ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr);
27677a03ce2fSLisandro Dalcin   }
27687a03ce2fSLisandro Dalcin   PetscFunctionReturn(0);
27697a03ce2fSLisandro Dalcin }
27707a03ce2fSLisandro Dalcin 
27719b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */
27729b94acceSBarry Smith 
27734a2ae208SSatish Balay #undef __FUNCT__
2774a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet"
27759b94acceSBarry Smith /*@C
2776a6570f20SBarry Smith    SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
27779b94acceSBarry Smith    iteration of the nonlinear solver to display the iteration's
27789b94acceSBarry Smith    progress.
27799b94acceSBarry Smith 
27803f9fe445SBarry Smith    Logically Collective on SNES
2781fee21e36SBarry Smith 
2782c7afd0dbSLois Curfman McInnes    Input Parameters:
2783c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2784c7afd0dbSLois Curfman McInnes .  func - monitoring routine
2785b8a78c4aSBarry Smith .  mctx - [optional] user-defined context for private data for the
2786e8105e01SRichard Katz           monitor routine (use PETSC_NULL if no context is desired)
2787b3006f0bSLois Curfman McInnes -  monitordestroy - [optional] routine that frees monitor context
2788b3006f0bSLois Curfman McInnes           (may be PETSC_NULL)
27899b94acceSBarry Smith 
2790c7afd0dbSLois Curfman McInnes    Calling sequence of func:
2791a7cc72afSBarry Smith $     int func(SNES snes,PetscInt its, PetscReal norm,void *mctx)
2792c7afd0dbSLois Curfman McInnes 
2793c7afd0dbSLois Curfman McInnes +    snes - the SNES context
2794c7afd0dbSLois Curfman McInnes .    its - iteration number
2795c7afd0dbSLois Curfman McInnes .    norm - 2-norm function value (may be estimated)
279640a0c1c6SLois Curfman McInnes -    mctx - [optional] monitoring context
27979b94acceSBarry Smith 
27989665c990SLois Curfman McInnes    Options Database Keys:
2799a6570f20SBarry Smith +    -snes_monitor        - sets SNESMonitorDefault()
2800a6570f20SBarry Smith .    -snes_monitor_draw    - sets line graph monitor,
2801a6570f20SBarry Smith                             uses SNESMonitorLGCreate()
2802cca6129bSJed Brown -    -snes_monitor_cancel - cancels all monitors that have
2803c7afd0dbSLois Curfman McInnes                             been hardwired into a code by
2804a6570f20SBarry Smith                             calls to SNESMonitorSet(), but
2805c7afd0dbSLois Curfman McInnes                             does not cancel those set via
2806c7afd0dbSLois Curfman McInnes                             the options database.
28079665c990SLois Curfman McInnes 
2808639f9d9dSBarry Smith    Notes:
28096bc08f3fSLois Curfman McInnes    Several different monitoring routines may be set by calling
2810a6570f20SBarry Smith    SNESMonitorSet() multiple times; all will be called in the
28116bc08f3fSLois Curfman McInnes    order in which they were set.
2812639f9d9dSBarry Smith 
2813025f1a04SBarry Smith    Fortran notes: Only a single monitor function can be set for each SNES object
2814025f1a04SBarry Smith 
281536851e7fSLois Curfman McInnes    Level: intermediate
281636851e7fSLois Curfman McInnes 
28179b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor
28189b94acceSBarry Smith 
2819a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel()
28209b94acceSBarry Smith @*/
2821c2efdce3SBarry Smith PetscErrorCode  SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
28229b94acceSBarry Smith {
2823b90d0a6eSBarry Smith   PetscInt       i;
2824649052a6SBarry Smith   PetscErrorCode ierr;
2825b90d0a6eSBarry Smith 
28263a40ed3dSBarry Smith   PetscFunctionBegin;
28270700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
282817186662SBarry Smith   if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
2829b90d0a6eSBarry Smith   for (i=0; i<snes->numbermonitors;i++) {
2830649052a6SBarry Smith     if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) {
2831649052a6SBarry Smith       if (monitordestroy) {
2832c2efdce3SBarry Smith         ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr);
2833649052a6SBarry Smith       }
2834b90d0a6eSBarry Smith       PetscFunctionReturn(0);
2835b90d0a6eSBarry Smith     }
2836b90d0a6eSBarry Smith   }
2837b90d0a6eSBarry Smith   snes->monitor[snes->numbermonitors]           = monitor;
2838b8a78c4aSBarry Smith   snes->monitordestroy[snes->numbermonitors]    = monitordestroy;
2839639f9d9dSBarry Smith   snes->monitorcontext[snes->numbermonitors++]  = (void*)mctx;
28403a40ed3dSBarry Smith   PetscFunctionReturn(0);
28419b94acceSBarry Smith }
28429b94acceSBarry Smith 
28434a2ae208SSatish Balay #undef __FUNCT__
2844a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel"
28455cd90555SBarry Smith /*@C
2846a6570f20SBarry Smith    SNESMonitorCancel - Clears all the monitor functions for a SNES object.
28475cd90555SBarry Smith 
28483f9fe445SBarry Smith    Logically Collective on SNES
2849c7afd0dbSLois Curfman McInnes 
28505cd90555SBarry Smith    Input Parameters:
28515cd90555SBarry Smith .  snes - the SNES context
28525cd90555SBarry Smith 
28531a480d89SAdministrator    Options Database Key:
2854a6570f20SBarry Smith .  -snes_monitor_cancel - cancels all monitors that have been hardwired
2855a6570f20SBarry Smith     into a code by calls to SNESMonitorSet(), but does not cancel those
2856c7afd0dbSLois Curfman McInnes     set via the options database
28575cd90555SBarry Smith 
28585cd90555SBarry Smith    Notes:
28595cd90555SBarry Smith    There is no way to clear one specific monitor from a SNES object.
28605cd90555SBarry Smith 
286136851e7fSLois Curfman McInnes    Level: intermediate
286236851e7fSLois Curfman McInnes 
28635cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor
28645cd90555SBarry Smith 
2865a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet()
28665cd90555SBarry Smith @*/
28677087cfbeSBarry Smith PetscErrorCode  SNESMonitorCancel(SNES snes)
28685cd90555SBarry Smith {
2869d952e501SBarry Smith   PetscErrorCode ierr;
2870d952e501SBarry Smith   PetscInt       i;
2871d952e501SBarry Smith 
28725cd90555SBarry Smith   PetscFunctionBegin;
28730700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2874d952e501SBarry Smith   for (i=0; i<snes->numbermonitors; i++) {
2875d952e501SBarry Smith     if (snes->monitordestroy[i]) {
28763c4aec1bSBarry Smith       ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr);
2877d952e501SBarry Smith     }
2878d952e501SBarry Smith   }
28795cd90555SBarry Smith   snes->numbermonitors = 0;
28805cd90555SBarry Smith   PetscFunctionReturn(0);
28815cd90555SBarry Smith }
28825cd90555SBarry Smith 
28834a2ae208SSatish Balay #undef __FUNCT__
28844a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest"
28859b94acceSBarry Smith /*@C
28869b94acceSBarry Smith    SNESSetConvergenceTest - Sets the function that is to be used
28879b94acceSBarry Smith    to test for convergence of the nonlinear iterative solution.
28889b94acceSBarry Smith 
28893f9fe445SBarry Smith    Logically Collective on SNES
2890fee21e36SBarry Smith 
2891c7afd0dbSLois Curfman McInnes    Input Parameters:
2892c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2893c7afd0dbSLois Curfman McInnes .  func - routine to test for convergence
28947f7931b9SBarry Smith .  cctx - [optional] context for private data for the convergence routine  (may be PETSC_NULL)
28957f7931b9SBarry Smith -  destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran)
28969b94acceSBarry Smith 
2897c7afd0dbSLois Curfman McInnes    Calling sequence of func:
289806ee9f85SBarry Smith $     PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
2899c7afd0dbSLois Curfman McInnes 
2900c7afd0dbSLois Curfman McInnes +    snes - the SNES context
290106ee9f85SBarry Smith .    it - current iteration (0 is the first and is before any Newton step)
2902c7afd0dbSLois Curfman McInnes .    cctx - [optional] convergence context
2903184914b5SBarry Smith .    reason - reason for convergence/divergence
2904c7afd0dbSLois Curfman McInnes .    xnorm - 2-norm of current iterate
29054b27c08aSLois Curfman McInnes .    gnorm - 2-norm of current step
29064b27c08aSLois Curfman McInnes -    f - 2-norm of function
29079b94acceSBarry Smith 
290836851e7fSLois Curfman McInnes    Level: advanced
290936851e7fSLois Curfman McInnes 
29109b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test
29119b94acceSBarry Smith 
291285385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged()
29139b94acceSBarry Smith @*/
29147087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
29159b94acceSBarry Smith {
29167f7931b9SBarry Smith   PetscErrorCode ierr;
29177f7931b9SBarry Smith 
29183a40ed3dSBarry Smith   PetscFunctionBegin;
29190700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
292085385478SLisandro Dalcin   if (!func) func = SNESSkipConverged;
29217f7931b9SBarry Smith   if (snes->ops->convergeddestroy) {
29227f7931b9SBarry Smith     ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr);
29237f7931b9SBarry Smith   }
292485385478SLisandro Dalcin   snes->ops->converged        = func;
29257f7931b9SBarry Smith   snes->ops->convergeddestroy = destroy;
292685385478SLisandro Dalcin   snes->cnvP                  = cctx;
29273a40ed3dSBarry Smith   PetscFunctionReturn(0);
29289b94acceSBarry Smith }
29299b94acceSBarry Smith 
29304a2ae208SSatish Balay #undef __FUNCT__
29314a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason"
293252baeb72SSatish Balay /*@
2933184914b5SBarry Smith    SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
2934184914b5SBarry Smith 
2935184914b5SBarry Smith    Not Collective
2936184914b5SBarry Smith 
2937184914b5SBarry Smith    Input Parameter:
2938184914b5SBarry Smith .  snes - the SNES context
2939184914b5SBarry Smith 
2940184914b5SBarry Smith    Output Parameter:
29414d0a8057SBarry Smith .  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
2942184914b5SBarry Smith             manual pages for the individual convergence tests for complete lists
2943184914b5SBarry Smith 
2944184914b5SBarry Smith    Level: intermediate
2945184914b5SBarry Smith 
2946184914b5SBarry Smith    Notes: Can only be called after the call the SNESSolve() is complete.
2947184914b5SBarry Smith 
2948184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test
2949184914b5SBarry Smith 
295085385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason
2951184914b5SBarry Smith @*/
29527087cfbeSBarry Smith PetscErrorCode  SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
2953184914b5SBarry Smith {
2954184914b5SBarry Smith   PetscFunctionBegin;
29550700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
29564482741eSBarry Smith   PetscValidPointer(reason,2);
2957184914b5SBarry Smith   *reason = snes->reason;
2958184914b5SBarry Smith   PetscFunctionReturn(0);
2959184914b5SBarry Smith }
2960184914b5SBarry Smith 
29614a2ae208SSatish Balay #undef __FUNCT__
29624a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory"
2963c9005455SLois Curfman McInnes /*@
2964c9005455SLois Curfman McInnes    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
2965c9005455SLois Curfman McInnes 
29663f9fe445SBarry Smith    Logically Collective on SNES
2967fee21e36SBarry Smith 
2968c7afd0dbSLois Curfman McInnes    Input Parameters:
2969c7afd0dbSLois Curfman McInnes +  snes - iterative context obtained from SNESCreate()
29708c7482ecSBarry Smith .  a   - array to hold history, this array will contain the function norms computed at each step
2971cd5578b5SBarry Smith .  its - integer array holds the number of linear iterations for each solve.
2972758f92a0SBarry Smith .  na  - size of a and its
297364731454SLois Curfman McInnes -  reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
2974758f92a0SBarry Smith            else it continues storing new values for new nonlinear solves after the old ones
2975c7afd0dbSLois Curfman McInnes 
2976308dcc3eSBarry Smith    Notes:
2977308dcc3eSBarry Smith    If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a
2978308dcc3eSBarry Smith    default array of length 10000 is allocated.
2979308dcc3eSBarry Smith 
2980c9005455SLois Curfman McInnes    This routine is useful, e.g., when running a code for purposes
2981c9005455SLois Curfman McInnes    of accurate performance monitoring, when no I/O should be done
2982c9005455SLois Curfman McInnes    during the section of code that is being timed.
2983c9005455SLois Curfman McInnes 
298436851e7fSLois Curfman McInnes    Level: intermediate
298536851e7fSLois Curfman McInnes 
2986c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history
2987758f92a0SBarry Smith 
298808405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory()
2989758f92a0SBarry Smith 
2990c9005455SLois Curfman McInnes @*/
29917087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool  reset)
2992c9005455SLois Curfman McInnes {
2993308dcc3eSBarry Smith   PetscErrorCode ierr;
2994308dcc3eSBarry Smith 
29953a40ed3dSBarry Smith   PetscFunctionBegin;
29960700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
29974482741eSBarry Smith   if (na)  PetscValidScalarPointer(a,2);
2998a562a398SLisandro Dalcin   if (its) PetscValidIntPointer(its,3);
2999308dcc3eSBarry Smith   if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) {
3000308dcc3eSBarry Smith     if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
3001308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr);
3002308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr);
3003308dcc3eSBarry Smith     snes->conv_malloc   = PETSC_TRUE;
3004308dcc3eSBarry Smith   }
3005c9005455SLois Curfman McInnes   snes->conv_hist       = a;
3006758f92a0SBarry Smith   snes->conv_hist_its   = its;
3007758f92a0SBarry Smith   snes->conv_hist_max   = na;
3008a12bc48fSLisandro Dalcin   snes->conv_hist_len   = 0;
3009758f92a0SBarry Smith   snes->conv_hist_reset = reset;
3010758f92a0SBarry Smith   PetscFunctionReturn(0);
3011758f92a0SBarry Smith }
3012758f92a0SBarry Smith 
3013308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3014c6db04a5SJed Brown #include <engine.h>   /* MATLAB include file */
3015c6db04a5SJed Brown #include <mex.h>      /* MATLAB include file */
3016308dcc3eSBarry Smith EXTERN_C_BEGIN
3017308dcc3eSBarry Smith #undef __FUNCT__
3018308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab"
3019308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes)
3020308dcc3eSBarry Smith {
3021308dcc3eSBarry Smith   mxArray        *mat;
3022308dcc3eSBarry Smith   PetscInt       i;
3023308dcc3eSBarry Smith   PetscReal      *ar;
3024308dcc3eSBarry Smith 
3025308dcc3eSBarry Smith   PetscFunctionBegin;
3026308dcc3eSBarry Smith   mat  = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL);
3027308dcc3eSBarry Smith   ar   = (PetscReal*) mxGetData(mat);
3028308dcc3eSBarry Smith   for (i=0; i<snes->conv_hist_len; i++) {
3029308dcc3eSBarry Smith     ar[i] = snes->conv_hist[i];
3030308dcc3eSBarry Smith   }
3031308dcc3eSBarry Smith   PetscFunctionReturn(mat);
3032308dcc3eSBarry Smith }
3033308dcc3eSBarry Smith EXTERN_C_END
3034308dcc3eSBarry Smith #endif
3035308dcc3eSBarry Smith 
3036308dcc3eSBarry Smith 
30374a2ae208SSatish Balay #undef __FUNCT__
30384a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory"
30390c4c9dddSBarry Smith /*@C
3040758f92a0SBarry Smith    SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
3041758f92a0SBarry Smith 
30423f9fe445SBarry Smith    Not Collective
3043758f92a0SBarry Smith 
3044758f92a0SBarry Smith    Input Parameter:
3045758f92a0SBarry Smith .  snes - iterative context obtained from SNESCreate()
3046758f92a0SBarry Smith 
3047758f92a0SBarry Smith    Output Parameters:
3048758f92a0SBarry Smith .  a   - array to hold history
3049758f92a0SBarry Smith .  its - integer array holds the number of linear iterations (or
3050758f92a0SBarry Smith          negative if not converged) for each solve.
3051758f92a0SBarry Smith -  na  - size of a and its
3052758f92a0SBarry Smith 
3053758f92a0SBarry Smith    Notes:
3054758f92a0SBarry Smith     The calling sequence for this routine in Fortran is
3055758f92a0SBarry Smith $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
3056758f92a0SBarry Smith 
3057758f92a0SBarry Smith    This routine is useful, e.g., when running a code for purposes
3058758f92a0SBarry Smith    of accurate performance monitoring, when no I/O should be done
3059758f92a0SBarry Smith    during the section of code that is being timed.
3060758f92a0SBarry Smith 
3061758f92a0SBarry Smith    Level: intermediate
3062758f92a0SBarry Smith 
3063758f92a0SBarry Smith .keywords: SNES, get, convergence, history
3064758f92a0SBarry Smith 
3065758f92a0SBarry Smith .seealso: SNESSetConvergencHistory()
3066758f92a0SBarry Smith 
3067758f92a0SBarry Smith @*/
30687087cfbeSBarry Smith PetscErrorCode  SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
3069758f92a0SBarry Smith {
3070758f92a0SBarry Smith   PetscFunctionBegin;
30710700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3072758f92a0SBarry Smith   if (a)   *a   = snes->conv_hist;
3073758f92a0SBarry Smith   if (its) *its = snes->conv_hist_its;
3074758f92a0SBarry Smith   if (na)  *na  = snes->conv_hist_len;
30753a40ed3dSBarry Smith   PetscFunctionReturn(0);
3076c9005455SLois Curfman McInnes }
3077c9005455SLois Curfman McInnes 
3078e74ef692SMatthew Knepley #undef __FUNCT__
3079e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate"
3080ac226902SBarry Smith /*@C
308176b2cf59SMatthew Knepley   SNESSetUpdate - Sets the general-purpose update function called
3082eec8f646SJed Brown   at the beginning of every iteration of the nonlinear solve. Specifically
30837e4bb74cSBarry Smith   it is called just before the Jacobian is "evaluated".
308476b2cf59SMatthew Knepley 
30853f9fe445SBarry Smith   Logically Collective on SNES
308676b2cf59SMatthew Knepley 
308776b2cf59SMatthew Knepley   Input Parameters:
308876b2cf59SMatthew Knepley . snes - The nonlinear solver context
308976b2cf59SMatthew Knepley . func - The function
309076b2cf59SMatthew Knepley 
309176b2cf59SMatthew Knepley   Calling sequence of func:
3092b5d30489SBarry Smith . func (SNES snes, PetscInt step);
309376b2cf59SMatthew Knepley 
309476b2cf59SMatthew Knepley . step - The current step of the iteration
309576b2cf59SMatthew Knepley 
3096fe97e370SBarry Smith   Level: advanced
3097fe97e370SBarry Smith 
3098fe97e370SBarry 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()
3099fe97e370SBarry Smith         This is not used by most users.
310076b2cf59SMatthew Knepley 
310176b2cf59SMatthew Knepley .keywords: SNES, update
3102b5d30489SBarry Smith 
310385385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve()
310476b2cf59SMatthew Knepley @*/
31057087cfbeSBarry Smith PetscErrorCode  SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
310676b2cf59SMatthew Knepley {
310776b2cf59SMatthew Knepley   PetscFunctionBegin;
31080700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID,1);
3109e7788613SBarry Smith   snes->ops->update = func;
311076b2cf59SMatthew Knepley   PetscFunctionReturn(0);
311176b2cf59SMatthew Knepley }
311276b2cf59SMatthew Knepley 
3113e74ef692SMatthew Knepley #undef __FUNCT__
3114e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate"
311576b2cf59SMatthew Knepley /*@
311676b2cf59SMatthew Knepley   SNESDefaultUpdate - The default update function which does nothing.
311776b2cf59SMatthew Knepley 
311876b2cf59SMatthew Knepley   Not collective
311976b2cf59SMatthew Knepley 
312076b2cf59SMatthew Knepley   Input Parameters:
312176b2cf59SMatthew Knepley . snes - The nonlinear solver context
312276b2cf59SMatthew Knepley . step - The current step of the iteration
312376b2cf59SMatthew Knepley 
3124205452f4SMatthew Knepley   Level: intermediate
3125205452f4SMatthew Knepley 
312676b2cf59SMatthew Knepley .keywords: SNES, update
3127a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC()
312876b2cf59SMatthew Knepley @*/
31297087cfbeSBarry Smith PetscErrorCode  SNESDefaultUpdate(SNES snes, PetscInt step)
313076b2cf59SMatthew Knepley {
313176b2cf59SMatthew Knepley   PetscFunctionBegin;
313276b2cf59SMatthew Knepley   PetscFunctionReturn(0);
313376b2cf59SMatthew Knepley }
313476b2cf59SMatthew Knepley 
31354a2ae208SSatish Balay #undef __FUNCT__
31364a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private"
31379b94acceSBarry Smith /*
31389b94acceSBarry Smith    SNESScaleStep_Private - Scales a step so that its length is less than the
31399b94acceSBarry Smith    positive parameter delta.
31409b94acceSBarry Smith 
31419b94acceSBarry Smith     Input Parameters:
3142c7afd0dbSLois Curfman McInnes +   snes - the SNES context
31439b94acceSBarry Smith .   y - approximate solution of linear system
31449b94acceSBarry Smith .   fnorm - 2-norm of current function
3145c7afd0dbSLois Curfman McInnes -   delta - trust region size
31469b94acceSBarry Smith 
31479b94acceSBarry Smith     Output Parameters:
3148c7afd0dbSLois Curfman McInnes +   gpnorm - predicted function norm at the new point, assuming local
31499b94acceSBarry Smith     linearization.  The value is zero if the step lies within the trust
31509b94acceSBarry Smith     region, and exceeds zero otherwise.
3151c7afd0dbSLois Curfman McInnes -   ynorm - 2-norm of the step
31529b94acceSBarry Smith 
31539b94acceSBarry Smith     Note:
31544b27c08aSLois Curfman McInnes     For non-trust region methods such as SNESLS, the parameter delta
31559b94acceSBarry Smith     is set to be the maximum allowable step size.
31569b94acceSBarry Smith 
31579b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step
31589b94acceSBarry Smith */
3159dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
31609b94acceSBarry Smith {
3161064f8208SBarry Smith   PetscReal      nrm;
3162ea709b57SSatish Balay   PetscScalar    cnorm;
3163dfbe8321SBarry Smith   PetscErrorCode ierr;
31643a40ed3dSBarry Smith 
31653a40ed3dSBarry Smith   PetscFunctionBegin;
31660700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
31670700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3168c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,2);
3169184914b5SBarry Smith 
3170064f8208SBarry Smith   ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr);
3171064f8208SBarry Smith   if (nrm > *delta) {
3172064f8208SBarry Smith      nrm = *delta/nrm;
3173064f8208SBarry Smith      *gpnorm = (1.0 - nrm)*(*fnorm);
3174064f8208SBarry Smith      cnorm = nrm;
31752dcb1b2aSMatthew Knepley      ierr = VecScale(y,cnorm);CHKERRQ(ierr);
31769b94acceSBarry Smith      *ynorm = *delta;
31779b94acceSBarry Smith   } else {
31789b94acceSBarry Smith      *gpnorm = 0.0;
3179064f8208SBarry Smith      *ynorm = nrm;
31809b94acceSBarry Smith   }
31813a40ed3dSBarry Smith   PetscFunctionReturn(0);
31829b94acceSBarry Smith }
31839b94acceSBarry Smith 
31844a2ae208SSatish Balay #undef __FUNCT__
31854a2ae208SSatish Balay #define __FUNCT__ "SNESSolve"
31866ce558aeSBarry Smith /*@C
3187f69a0ea3SMatthew Knepley    SNESSolve - Solves a nonlinear system F(x) = b.
3188f69a0ea3SMatthew Knepley    Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
31899b94acceSBarry Smith 
3190c7afd0dbSLois Curfman McInnes    Collective on SNES
3191c7afd0dbSLois Curfman McInnes 
3192b2002411SLois Curfman McInnes    Input Parameters:
3193c7afd0dbSLois Curfman McInnes +  snes - the SNES context
31943cebf274SJed Brown .  b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero.
319585385478SLisandro Dalcin -  x - the solution vector.
31969b94acceSBarry Smith 
3197b2002411SLois Curfman McInnes    Notes:
31988ddd3da0SLois Curfman McInnes    The user should initialize the vector,x, with the initial guess
31998ddd3da0SLois Curfman McInnes    for the nonlinear solve prior to calling SNESSolve.  In particular,
32008ddd3da0SLois Curfman McInnes    to employ an initial guess of zero, the user should explicitly set
32018ddd3da0SLois Curfman McInnes    this vector to zero by calling VecSet().
32028ddd3da0SLois Curfman McInnes 
320336851e7fSLois Curfman McInnes    Level: beginner
320436851e7fSLois Curfman McInnes 
32059b94acceSBarry Smith .keywords: SNES, nonlinear, solve
32069b94acceSBarry Smith 
3207c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution()
32089b94acceSBarry Smith @*/
32097087cfbeSBarry Smith PetscErrorCode  SNESSolve(SNES snes,Vec b,Vec x)
32109b94acceSBarry Smith {
3211dfbe8321SBarry Smith   PetscErrorCode ierr;
3212ace3abfcSBarry Smith   PetscBool      flg;
3213eabae89aSBarry Smith   char           filename[PETSC_MAX_PATH_LEN];
3214eabae89aSBarry Smith   PetscViewer    viewer;
3215efd51863SBarry Smith   PetscInt       grid;
3216a69afd8bSBarry Smith   Vec            xcreated = PETSC_NULL;
3217052efed2SBarry Smith 
32183a40ed3dSBarry Smith   PetscFunctionBegin;
32190700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3220a69afd8bSBarry Smith   if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3221a69afd8bSBarry Smith   if (x) PetscCheckSameComm(snes,1,x,3);
32220700a824SBarry Smith   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2);
322385385478SLisandro Dalcin   if (b) PetscCheckSameComm(snes,1,b,2);
322485385478SLisandro Dalcin 
3225a69afd8bSBarry Smith   if (!x && snes->dm) {
3226a69afd8bSBarry Smith     ierr = DMCreateGlobalVector(snes->dm,&xcreated);CHKERRQ(ierr);
3227a69afd8bSBarry Smith     x    = xcreated;
3228a69afd8bSBarry Smith   }
3229a69afd8bSBarry Smith 
3230a8248277SBarry Smith   for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);}
3231efd51863SBarry Smith   for (grid=0; grid<snes->gridsequence+1; grid++) {
3232efd51863SBarry Smith 
323385385478SLisandro Dalcin     /* set solution vector */
3234efd51863SBarry Smith     if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);}
32356bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
323685385478SLisandro Dalcin     snes->vec_sol = x;
323785385478SLisandro Dalcin     /* set afine vector if provided */
323885385478SLisandro Dalcin     if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); }
32396bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
324085385478SLisandro Dalcin     snes->vec_rhs = b;
324185385478SLisandro Dalcin 
324270e92668SMatthew Knepley     ierr = SNESSetUp(snes);CHKERRQ(ierr);
32433f149594SLisandro Dalcin 
32447eee914bSBarry Smith     if (!grid) {
32457eee914bSBarry Smith       if (snes->ops->computeinitialguess) {
3246d25893d9SBarry Smith         ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr);
3247dd568438SSatish Balay       } else if (snes->dm) {
3248dd568438SSatish Balay         PetscBool ig;
3249dd568438SSatish Balay         ierr = DMHasInitialGuess(snes->dm,&ig);CHKERRQ(ierr);
3250dd568438SSatish Balay         if (ig) {
32517eee914bSBarry Smith           ierr = DMComputeInitialGuess(snes->dm,snes->vec_sol);CHKERRQ(ierr);
32527eee914bSBarry Smith         }
3253d25893d9SBarry Smith       }
3254dd568438SSatish Balay     }
3255d25893d9SBarry Smith 
3256abc0a331SBarry Smith     if (snes->conv_hist_reset) snes->conv_hist_len = 0;
325750ffb88aSMatthew Knepley     snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;
3258d5e45103SBarry Smith 
32593f149594SLisandro Dalcin     ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
32604936397dSBarry Smith     ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr);
326185385478SLisandro Dalcin     ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
32624936397dSBarry Smith     if (snes->domainerror){
32634936397dSBarry Smith       snes->reason      = SNES_DIVERGED_FUNCTION_DOMAIN;
32644936397dSBarry Smith       snes->domainerror = PETSC_FALSE;
32654936397dSBarry Smith     }
326617186662SBarry Smith     if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
32673f149594SLisandro Dalcin 
32687adad957SLisandro Dalcin     ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
3269eabae89aSBarry Smith     if (flg && !PetscPreLoadingOn) {
32707adad957SLisandro Dalcin       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr);
3271eabae89aSBarry Smith       ierr = SNESView(snes,viewer);CHKERRQ(ierr);
32726bf464f9SBarry Smith       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
3273eabae89aSBarry Smith     }
3274eabae89aSBarry Smith 
327590d69ab7SBarry Smith     flg  = PETSC_FALSE;
3276acfcf0e5SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr);
3277da9b6338SBarry Smith     if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); }
32785968eb51SBarry Smith     if (snes->printreason) {
3279a8248277SBarry Smith       ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
32805968eb51SBarry Smith       if (snes->reason > 0) {
3281*c7e7b494SJed 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);
32825968eb51SBarry Smith       } else {
3283*c7e7b494SJed 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);
32845968eb51SBarry Smith       }
3285a8248277SBarry Smith       ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
32865968eb51SBarry Smith     }
32875968eb51SBarry Smith 
32888501fc72SJed Brown     flg = PETSC_FALSE;
32898501fc72SJed Brown     ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
32908501fc72SJed Brown     if (flg) {
32918501fc72SJed Brown       PetscViewer viewer;
32928501fc72SJed Brown       ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr);
32938501fc72SJed Brown       ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr);
32948501fc72SJed Brown       ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr);
32958501fc72SJed Brown       ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr);
32968501fc72SJed Brown       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
32978501fc72SJed Brown     }
32988501fc72SJed Brown 
3299e113a28aSBarry Smith     if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged");
3300efd51863SBarry Smith     if (grid <  snes->gridsequence) {
3301efd51863SBarry Smith       DM  fine;
3302efd51863SBarry Smith       Vec xnew;
3303efd51863SBarry Smith       Mat interp;
3304efd51863SBarry Smith 
3305efd51863SBarry Smith       ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr);
3306e727c939SJed Brown       ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr);
3307efd51863SBarry Smith       ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr);
3308efd51863SBarry Smith       ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr);
3309efd51863SBarry Smith       ierr = MatDestroy(&interp);CHKERRQ(ierr);
3310efd51863SBarry Smith       x    = xnew;
3311efd51863SBarry Smith 
3312efd51863SBarry Smith       ierr = SNESReset(snes);CHKERRQ(ierr);
3313efd51863SBarry Smith       ierr = SNESSetDM(snes,fine);CHKERRQ(ierr);
3314efd51863SBarry Smith       ierr = DMDestroy(&fine);CHKERRQ(ierr);
3315a8248277SBarry Smith       ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);
3316efd51863SBarry Smith     }
3317efd51863SBarry Smith   }
3318a69afd8bSBarry Smith   ierr = VecDestroy(&xcreated);CHKERRQ(ierr);
33193a40ed3dSBarry Smith   PetscFunctionReturn(0);
33209b94acceSBarry Smith }
33219b94acceSBarry Smith 
33229b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */
33239b94acceSBarry Smith 
33244a2ae208SSatish Balay #undef __FUNCT__
33254a2ae208SSatish Balay #define __FUNCT__ "SNESSetType"
332682bf6240SBarry Smith /*@C
33274b0e389bSBarry Smith    SNESSetType - Sets the method for the nonlinear solver.
33289b94acceSBarry Smith 
3329fee21e36SBarry Smith    Collective on SNES
3330fee21e36SBarry Smith 
3331c7afd0dbSLois Curfman McInnes    Input Parameters:
3332c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3333454a90a3SBarry Smith -  type - a known method
3334c7afd0dbSLois Curfman McInnes 
3335c7afd0dbSLois Curfman McInnes    Options Database Key:
3336454a90a3SBarry Smith .  -snes_type <type> - Sets the method; use -help for a list
3337c7afd0dbSLois Curfman McInnes    of available methods (for instance, ls or tr)
3338ae12b187SLois Curfman McInnes 
33399b94acceSBarry Smith    Notes:
3340e090d566SSatish Balay    See "petsc/include/petscsnes.h" for available methods (for instance)
33414b27c08aSLois Curfman McInnes +    SNESLS - Newton's method with line search
3342c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
33434b27c08aSLois Curfman McInnes .    SNESTR - Newton's method with trust region
3344c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
33459b94acceSBarry Smith 
3346ae12b187SLois Curfman McInnes   Normally, it is best to use the SNESSetFromOptions() command and then
3347ae12b187SLois Curfman McInnes   set the SNES solver type from the options database rather than by using
3348ae12b187SLois Curfman McInnes   this routine.  Using the options database provides the user with
3349ae12b187SLois Curfman McInnes   maximum flexibility in evaluating the many nonlinear solvers.
3350ae12b187SLois Curfman McInnes   The SNESSetType() routine is provided for those situations where it
3351ae12b187SLois Curfman McInnes   is necessary to set the nonlinear solver independently of the command
3352ae12b187SLois Curfman McInnes   line or options database.  This might be the case, for example, when
3353ae12b187SLois Curfman McInnes   the choice of solver changes during the execution of the program,
3354ae12b187SLois Curfman McInnes   and the user's application is taking responsibility for choosing the
3355b0a32e0cSBarry Smith   appropriate method.
335636851e7fSLois Curfman McInnes 
335736851e7fSLois Curfman McInnes   Level: intermediate
3358a703fe33SLois Curfman McInnes 
3359454a90a3SBarry Smith .keywords: SNES, set, type
3360435da068SBarry Smith 
3361435da068SBarry Smith .seealso: SNESType, SNESCreate()
3362435da068SBarry Smith 
33639b94acceSBarry Smith @*/
33647087cfbeSBarry Smith PetscErrorCode  SNESSetType(SNES snes,const SNESType type)
33659b94acceSBarry Smith {
3366dfbe8321SBarry Smith   PetscErrorCode ierr,(*r)(SNES);
3367ace3abfcSBarry Smith   PetscBool      match;
33683a40ed3dSBarry Smith 
33693a40ed3dSBarry Smith   PetscFunctionBegin;
33700700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
33714482741eSBarry Smith   PetscValidCharPointer(type,2);
337282bf6240SBarry Smith 
33736831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr);
33740f5bd95cSBarry Smith   if (match) PetscFunctionReturn(0);
337592ff6ae8SBarry Smith 
33764b91b6eaSBarry Smith   ierr =  PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr);
3377e32f2f54SBarry Smith   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
337875396ef9SLisandro Dalcin   /* Destroy the previous private SNES context */
3379b5c23020SJed Brown   if (snes->ops->destroy) {
3380b5c23020SJed Brown     ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr);
3381b5c23020SJed Brown     snes->ops->destroy = PETSC_NULL;
3382b5c23020SJed Brown   }
338375396ef9SLisandro Dalcin   /* Reinitialize function pointers in SNESOps structure */
338475396ef9SLisandro Dalcin   snes->ops->setup          = 0;
338575396ef9SLisandro Dalcin   snes->ops->solve          = 0;
338675396ef9SLisandro Dalcin   snes->ops->view           = 0;
338775396ef9SLisandro Dalcin   snes->ops->setfromoptions = 0;
338875396ef9SLisandro Dalcin   snes->ops->destroy        = 0;
338975396ef9SLisandro Dalcin   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
339075396ef9SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
3391454a90a3SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr);
339203bfa161SLisandro Dalcin   ierr = (*r)(snes);CHKERRQ(ierr);
33939fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS)
33949fb22e1aSBarry Smith   if (PetscAMSPublishAll) {
33959fb22e1aSBarry Smith     ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr);
33969fb22e1aSBarry Smith   }
33979fb22e1aSBarry Smith #endif
33983a40ed3dSBarry Smith   PetscFunctionReturn(0);
33999b94acceSBarry Smith }
34009b94acceSBarry Smith 
3401a847f771SSatish Balay 
34029b94acceSBarry Smith /* --------------------------------------------------------------------- */
34034a2ae208SSatish Balay #undef __FUNCT__
34044a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy"
340552baeb72SSatish Balay /*@
34069b94acceSBarry Smith    SNESRegisterDestroy - Frees the list of nonlinear solvers that were
3407f1af5d2fSBarry Smith    registered by SNESRegisterDynamic().
34089b94acceSBarry Smith 
3409fee21e36SBarry Smith    Not Collective
3410fee21e36SBarry Smith 
341136851e7fSLois Curfman McInnes    Level: advanced
341236851e7fSLois Curfman McInnes 
34139b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy
34149b94acceSBarry Smith 
34159b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll()
34169b94acceSBarry Smith @*/
34177087cfbeSBarry Smith PetscErrorCode  SNESRegisterDestroy(void)
34189b94acceSBarry Smith {
3419dfbe8321SBarry Smith   PetscErrorCode ierr;
342082bf6240SBarry Smith 
34213a40ed3dSBarry Smith   PetscFunctionBegin;
34221441b1d3SBarry Smith   ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr);
34234c49b128SBarry Smith   SNESRegisterAllCalled = PETSC_FALSE;
34243a40ed3dSBarry Smith   PetscFunctionReturn(0);
34259b94acceSBarry Smith }
34269b94acceSBarry Smith 
34274a2ae208SSatish Balay #undef __FUNCT__
34284a2ae208SSatish Balay #define __FUNCT__ "SNESGetType"
34299b94acceSBarry Smith /*@C
34309a28b0a6SLois Curfman McInnes    SNESGetType - Gets the SNES method type and name (as a string).
34319b94acceSBarry Smith 
3432c7afd0dbSLois Curfman McInnes    Not Collective
3433c7afd0dbSLois Curfman McInnes 
34349b94acceSBarry Smith    Input Parameter:
34354b0e389bSBarry Smith .  snes - nonlinear solver context
34369b94acceSBarry Smith 
34379b94acceSBarry Smith    Output Parameter:
34383a7fca6bSBarry Smith .  type - SNES method (a character string)
34399b94acceSBarry Smith 
344036851e7fSLois Curfman McInnes    Level: intermediate
344136851e7fSLois Curfman McInnes 
3442454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name
34439b94acceSBarry Smith @*/
34447087cfbeSBarry Smith PetscErrorCode  SNESGetType(SNES snes,const SNESType *type)
34459b94acceSBarry Smith {
34463a40ed3dSBarry Smith   PetscFunctionBegin;
34470700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
34484482741eSBarry Smith   PetscValidPointer(type,2);
34497adad957SLisandro Dalcin   *type = ((PetscObject)snes)->type_name;
34503a40ed3dSBarry Smith   PetscFunctionReturn(0);
34519b94acceSBarry Smith }
34529b94acceSBarry Smith 
34534a2ae208SSatish Balay #undef __FUNCT__
34544a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution"
345552baeb72SSatish Balay /*@
34569b94acceSBarry Smith    SNESGetSolution - Returns the vector where the approximate solution is
3457c0df2a02SJed Brown    stored. This is the fine grid solution when using SNESSetGridSequence().
34589b94acceSBarry Smith 
3459c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3460c7afd0dbSLois Curfman McInnes 
34619b94acceSBarry Smith    Input Parameter:
34629b94acceSBarry Smith .  snes - the SNES context
34639b94acceSBarry Smith 
34649b94acceSBarry Smith    Output Parameter:
34659b94acceSBarry Smith .  x - the solution
34669b94acceSBarry Smith 
346770e92668SMatthew Knepley    Level: intermediate
346836851e7fSLois Curfman McInnes 
34699b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution
34709b94acceSBarry Smith 
347185385478SLisandro Dalcin .seealso:  SNESGetSolutionUpdate(), SNESGetFunction()
34729b94acceSBarry Smith @*/
34737087cfbeSBarry Smith PetscErrorCode  SNESGetSolution(SNES snes,Vec *x)
34749b94acceSBarry Smith {
34753a40ed3dSBarry Smith   PetscFunctionBegin;
34760700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
34774482741eSBarry Smith   PetscValidPointer(x,2);
347885385478SLisandro Dalcin   *x = snes->vec_sol;
347970e92668SMatthew Knepley   PetscFunctionReturn(0);
348070e92668SMatthew Knepley }
348170e92668SMatthew Knepley 
348270e92668SMatthew Knepley #undef __FUNCT__
34834a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate"
348452baeb72SSatish Balay /*@
34859b94acceSBarry Smith    SNESGetSolutionUpdate - Returns the vector where the solution update is
34869b94acceSBarry Smith    stored.
34879b94acceSBarry Smith 
3488c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3489c7afd0dbSLois Curfman McInnes 
34909b94acceSBarry Smith    Input Parameter:
34919b94acceSBarry Smith .  snes - the SNES context
34929b94acceSBarry Smith 
34939b94acceSBarry Smith    Output Parameter:
34949b94acceSBarry Smith .  x - the solution update
34959b94acceSBarry Smith 
349636851e7fSLois Curfman McInnes    Level: advanced
349736851e7fSLois Curfman McInnes 
34989b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update
34999b94acceSBarry Smith 
350085385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction()
35019b94acceSBarry Smith @*/
35027087cfbeSBarry Smith PetscErrorCode  SNESGetSolutionUpdate(SNES snes,Vec *x)
35039b94acceSBarry Smith {
35043a40ed3dSBarry Smith   PetscFunctionBegin;
35050700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
35064482741eSBarry Smith   PetscValidPointer(x,2);
350785385478SLisandro Dalcin   *x = snes->vec_sol_update;
35083a40ed3dSBarry Smith   PetscFunctionReturn(0);
35099b94acceSBarry Smith }
35109b94acceSBarry Smith 
35114a2ae208SSatish Balay #undef __FUNCT__
35124a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction"
35139b94acceSBarry Smith /*@C
35143638b69dSLois Curfman McInnes    SNESGetFunction - Returns the vector where the function is stored.
35159b94acceSBarry Smith 
3516a63bb30eSJed Brown    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
3517c7afd0dbSLois Curfman McInnes 
35189b94acceSBarry Smith    Input Parameter:
35199b94acceSBarry Smith .  snes - the SNES context
35209b94acceSBarry Smith 
35219b94acceSBarry Smith    Output Parameter:
35227bf4e008SBarry Smith +  r - the function (or PETSC_NULL)
352370e92668SMatthew Knepley .  func - the function (or PETSC_NULL)
352470e92668SMatthew Knepley -  ctx - the function context (or PETSC_NULL)
35259b94acceSBarry Smith 
352636851e7fSLois Curfman McInnes    Level: advanced
352736851e7fSLois Curfman McInnes 
3528a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function
35299b94acceSBarry Smith 
35304b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution()
35319b94acceSBarry Smith @*/
35327087cfbeSBarry Smith PetscErrorCode  SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
35339b94acceSBarry Smith {
3534a63bb30eSJed Brown   PetscErrorCode ierr;
35356cab3a1bSJed Brown   DM             dm;
3536a63bb30eSJed Brown 
35373a40ed3dSBarry Smith   PetscFunctionBegin;
35380700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3539a63bb30eSJed Brown   if (r) {
3540a63bb30eSJed Brown     if (!snes->vec_func) {
3541a63bb30eSJed Brown       if (snes->vec_rhs) {
3542a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr);
3543a63bb30eSJed Brown       } else if (snes->vec_sol) {
3544a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr);
3545a63bb30eSJed Brown       } else if (snes->dm) {
3546a63bb30eSJed Brown         ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr);
3547a63bb30eSJed Brown       }
3548a63bb30eSJed Brown     }
3549a63bb30eSJed Brown     *r = snes->vec_func;
3550a63bb30eSJed Brown   }
35516cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
35526cab3a1bSJed Brown   ierr = DMSNESGetFunction(dm,func,ctx);CHKERRQ(ierr);
35533a40ed3dSBarry Smith   PetscFunctionReturn(0);
35549b94acceSBarry Smith }
35559b94acceSBarry Smith 
3556c79ef259SPeter Brune /*@C
3557c79ef259SPeter Brune    SNESGetGS - Returns the GS function and context.
3558c79ef259SPeter Brune 
3559c79ef259SPeter Brune    Input Parameter:
3560c79ef259SPeter Brune .  snes - the SNES context
3561c79ef259SPeter Brune 
3562c79ef259SPeter Brune    Output Parameter:
3563c79ef259SPeter Brune +  gsfunc - the function (or PETSC_NULL)
3564c79ef259SPeter Brune -  ctx    - the function context (or PETSC_NULL)
3565c79ef259SPeter Brune 
3566c79ef259SPeter Brune    Level: advanced
3567c79ef259SPeter Brune 
3568c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function
3569c79ef259SPeter Brune 
3570c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction()
3571c79ef259SPeter Brune @*/
3572c79ef259SPeter Brune 
35734a2ae208SSatish Balay #undef __FUNCT__
3574646217ecSPeter Brune #define __FUNCT__ "SNESGetGS"
3575646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx)
3576646217ecSPeter Brune {
35776cab3a1bSJed Brown   PetscErrorCode ierr;
35786cab3a1bSJed Brown   DM             dm;
35796cab3a1bSJed Brown 
3580646217ecSPeter Brune   PetscFunctionBegin;
3581646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
35826cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
35836cab3a1bSJed Brown   ierr = DMSNESGetGS(dm,func,ctx);CHKERRQ(ierr);
3584646217ecSPeter Brune   PetscFunctionReturn(0);
3585646217ecSPeter Brune }
3586646217ecSPeter Brune 
35874a2ae208SSatish Balay #undef __FUNCT__
35884a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix"
35893c7409f5SSatish Balay /*@C
35903c7409f5SSatish Balay    SNESSetOptionsPrefix - Sets the prefix used for searching for all
3591d850072dSLois Curfman McInnes    SNES options in the database.
35923c7409f5SSatish Balay 
35933f9fe445SBarry Smith    Logically Collective on SNES
3594fee21e36SBarry Smith 
3595c7afd0dbSLois Curfman McInnes    Input Parameter:
3596c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3597c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3598c7afd0dbSLois Curfman McInnes 
3599d850072dSLois Curfman McInnes    Notes:
3600a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
3601c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
3602d850072dSLois Curfman McInnes 
360336851e7fSLois Curfman McInnes    Level: advanced
360436851e7fSLois Curfman McInnes 
36053c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database
3606a86d99e1SLois Curfman McInnes 
3607a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions()
36083c7409f5SSatish Balay @*/
36097087cfbeSBarry Smith PetscErrorCode  SNESSetOptionsPrefix(SNES snes,const char prefix[])
36103c7409f5SSatish Balay {
3611dfbe8321SBarry Smith   PetscErrorCode ierr;
36123c7409f5SSatish Balay 
36133a40ed3dSBarry Smith   PetscFunctionBegin;
36140700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3615639f9d9dSBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
36161cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
361794b7f48cSBarry Smith   ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
36183a40ed3dSBarry Smith   PetscFunctionReturn(0);
36193c7409f5SSatish Balay }
36203c7409f5SSatish Balay 
36214a2ae208SSatish Balay #undef __FUNCT__
36224a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix"
36233c7409f5SSatish Balay /*@C
3624f525115eSLois Curfman McInnes    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
3625d850072dSLois Curfman McInnes    SNES options in the database.
36263c7409f5SSatish Balay 
36273f9fe445SBarry Smith    Logically Collective on SNES
3628fee21e36SBarry Smith 
3629c7afd0dbSLois Curfman McInnes    Input Parameters:
3630c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3631c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3632c7afd0dbSLois Curfman McInnes 
3633d850072dSLois Curfman McInnes    Notes:
3634a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
3635c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
3636d850072dSLois Curfman McInnes 
363736851e7fSLois Curfman McInnes    Level: advanced
363836851e7fSLois Curfman McInnes 
36393c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database
3640a86d99e1SLois Curfman McInnes 
3641a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix()
36423c7409f5SSatish Balay @*/
36437087cfbeSBarry Smith PetscErrorCode  SNESAppendOptionsPrefix(SNES snes,const char prefix[])
36443c7409f5SSatish Balay {
3645dfbe8321SBarry Smith   PetscErrorCode ierr;
36463c7409f5SSatish Balay 
36473a40ed3dSBarry Smith   PetscFunctionBegin;
36480700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3649639f9d9dSBarry Smith   ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
36501cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
365194b7f48cSBarry Smith   ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
36523a40ed3dSBarry Smith   PetscFunctionReturn(0);
36533c7409f5SSatish Balay }
36543c7409f5SSatish Balay 
36554a2ae208SSatish Balay #undef __FUNCT__
36564a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix"
36579ab63eb5SSatish Balay /*@C
36583c7409f5SSatish Balay    SNESGetOptionsPrefix - Sets the prefix used for searching for all
36593c7409f5SSatish Balay    SNES options in the database.
36603c7409f5SSatish Balay 
3661c7afd0dbSLois Curfman McInnes    Not Collective
3662c7afd0dbSLois Curfman McInnes 
36633c7409f5SSatish Balay    Input Parameter:
36643c7409f5SSatish Balay .  snes - the SNES context
36653c7409f5SSatish Balay 
36663c7409f5SSatish Balay    Output Parameter:
36673c7409f5SSatish Balay .  prefix - pointer to the prefix string used
36683c7409f5SSatish Balay 
36694ef407dbSRichard Tran Mills    Notes: On the fortran side, the user should pass in a string 'prefix' of
36709ab63eb5SSatish Balay    sufficient length to hold the prefix.
36719ab63eb5SSatish Balay 
367236851e7fSLois Curfman McInnes    Level: advanced
367336851e7fSLois Curfman McInnes 
36743c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database
3675a86d99e1SLois Curfman McInnes 
3676a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix()
36773c7409f5SSatish Balay @*/
36787087cfbeSBarry Smith PetscErrorCode  SNESGetOptionsPrefix(SNES snes,const char *prefix[])
36793c7409f5SSatish Balay {
3680dfbe8321SBarry Smith   PetscErrorCode ierr;
36813c7409f5SSatish Balay 
36823a40ed3dSBarry Smith   PetscFunctionBegin;
36830700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3684639f9d9dSBarry Smith   ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
36853a40ed3dSBarry Smith   PetscFunctionReturn(0);
36863c7409f5SSatish Balay }
36873c7409f5SSatish Balay 
3688b2002411SLois Curfman McInnes 
36894a2ae208SSatish Balay #undef __FUNCT__
36904a2ae208SSatish Balay #define __FUNCT__ "SNESRegister"
36913cea93caSBarry Smith /*@C
36923cea93caSBarry Smith   SNESRegister - See SNESRegisterDynamic()
36933cea93caSBarry Smith 
36947f6c08e0SMatthew Knepley   Level: advanced
36953cea93caSBarry Smith @*/
36967087cfbeSBarry Smith PetscErrorCode  SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES))
3697b2002411SLois Curfman McInnes {
3698e2d1d2b7SBarry Smith   char           fullname[PETSC_MAX_PATH_LEN];
3699dfbe8321SBarry Smith   PetscErrorCode ierr;
3700b2002411SLois Curfman McInnes 
3701b2002411SLois Curfman McInnes   PetscFunctionBegin;
3702b0a32e0cSBarry Smith   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
3703c134de8dSSatish Balay   ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
3704b2002411SLois Curfman McInnes   PetscFunctionReturn(0);
3705b2002411SLois Curfman McInnes }
3706da9b6338SBarry Smith 
3707da9b6338SBarry Smith #undef __FUNCT__
3708da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin"
37097087cfbeSBarry Smith PetscErrorCode  SNESTestLocalMin(SNES snes)
3710da9b6338SBarry Smith {
3711dfbe8321SBarry Smith   PetscErrorCode ierr;
371277431f27SBarry Smith   PetscInt       N,i,j;
3713da9b6338SBarry Smith   Vec            u,uh,fh;
3714da9b6338SBarry Smith   PetscScalar    value;
3715da9b6338SBarry Smith   PetscReal      norm;
3716da9b6338SBarry Smith 
3717da9b6338SBarry Smith   PetscFunctionBegin;
3718da9b6338SBarry Smith   ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr);
3719da9b6338SBarry Smith   ierr = VecDuplicate(u,&uh);CHKERRQ(ierr);
3720da9b6338SBarry Smith   ierr = VecDuplicate(u,&fh);CHKERRQ(ierr);
3721da9b6338SBarry Smith 
3722da9b6338SBarry Smith   /* currently only works for sequential */
3723da9b6338SBarry Smith   ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");
3724da9b6338SBarry Smith   ierr = VecGetSize(u,&N);CHKERRQ(ierr);
3725da9b6338SBarry Smith   for (i=0; i<N; i++) {
3726da9b6338SBarry Smith     ierr = VecCopy(u,uh);CHKERRQ(ierr);
372777431f27SBarry Smith     ierr  = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr);
3728da9b6338SBarry Smith     for (j=-10; j<11; j++) {
3729ccae9161SBarry Smith       value = PetscSign(j)*exp(PetscAbs(j)-10.0);
3730da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
37313ab0aad5SBarry Smith       ierr  = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr);
3732da9b6338SBarry Smith       ierr  = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr);
373377431f27SBarry Smith       ierr  = PetscPrintf(PETSC_COMM_WORLD,"       j norm %D %18.16e\n",j,norm);CHKERRQ(ierr);
3734da9b6338SBarry Smith       value = -value;
3735da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
3736da9b6338SBarry Smith     }
3737da9b6338SBarry Smith   }
37386bf464f9SBarry Smith   ierr = VecDestroy(&uh);CHKERRQ(ierr);
37396bf464f9SBarry Smith   ierr = VecDestroy(&fh);CHKERRQ(ierr);
3740da9b6338SBarry Smith   PetscFunctionReturn(0);
3741da9b6338SBarry Smith }
374271f87433Sdalcinl 
374371f87433Sdalcinl #undef __FUNCT__
3744fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW"
374571f87433Sdalcinl /*@
3746fa9f3622SBarry Smith    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
374771f87433Sdalcinl    computing relative tolerance for linear solvers within an inexact
374871f87433Sdalcinl    Newton method.
374971f87433Sdalcinl 
37503f9fe445SBarry Smith    Logically Collective on SNES
375171f87433Sdalcinl 
375271f87433Sdalcinl    Input Parameters:
375371f87433Sdalcinl +  snes - SNES context
375471f87433Sdalcinl -  flag - PETSC_TRUE or PETSC_FALSE
375571f87433Sdalcinl 
375664ba62caSBarry Smith     Options Database:
375764ba62caSBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
375864ba62caSBarry Smith .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
375964ba62caSBarry Smith .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
376064ba62caSBarry Smith .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
376164ba62caSBarry Smith .  -snes_ksp_ew_gamma <gamma> - Sets gamma
376264ba62caSBarry Smith .  -snes_ksp_ew_alpha <alpha> - Sets alpha
376364ba62caSBarry Smith .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
376464ba62caSBarry Smith -  -snes_ksp_ew_threshold <threshold> - Sets threshold
376564ba62caSBarry Smith 
376671f87433Sdalcinl    Notes:
376771f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
376871f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
376971f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
377071f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
377171f87433Sdalcinl    solver.
377271f87433Sdalcinl 
377371f87433Sdalcinl    Level: advanced
377471f87433Sdalcinl 
377571f87433Sdalcinl    Reference:
377671f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
377771f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
377871f87433Sdalcinl 
377971f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
378071f87433Sdalcinl 
3781fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
378271f87433Sdalcinl @*/
37837087cfbeSBarry Smith PetscErrorCode  SNESKSPSetUseEW(SNES snes,PetscBool  flag)
378471f87433Sdalcinl {
378571f87433Sdalcinl   PetscFunctionBegin;
37860700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3787acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flag,2);
378871f87433Sdalcinl   snes->ksp_ewconv = flag;
378971f87433Sdalcinl   PetscFunctionReturn(0);
379071f87433Sdalcinl }
379171f87433Sdalcinl 
379271f87433Sdalcinl #undef __FUNCT__
3793fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW"
379471f87433Sdalcinl /*@
3795fa9f3622SBarry Smith    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
379671f87433Sdalcinl    for computing relative tolerance for linear solvers within an
379771f87433Sdalcinl    inexact Newton method.
379871f87433Sdalcinl 
379971f87433Sdalcinl    Not Collective
380071f87433Sdalcinl 
380171f87433Sdalcinl    Input Parameter:
380271f87433Sdalcinl .  snes - SNES context
380371f87433Sdalcinl 
380471f87433Sdalcinl    Output Parameter:
380571f87433Sdalcinl .  flag - PETSC_TRUE or PETSC_FALSE
380671f87433Sdalcinl 
380771f87433Sdalcinl    Notes:
380871f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
380971f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
381071f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
381171f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
381271f87433Sdalcinl    solver.
381371f87433Sdalcinl 
381471f87433Sdalcinl    Level: advanced
381571f87433Sdalcinl 
381671f87433Sdalcinl    Reference:
381771f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
381871f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
381971f87433Sdalcinl 
382071f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
382171f87433Sdalcinl 
3822fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
382371f87433Sdalcinl @*/
38247087cfbeSBarry Smith PetscErrorCode  SNESKSPGetUseEW(SNES snes, PetscBool  *flag)
382571f87433Sdalcinl {
382671f87433Sdalcinl   PetscFunctionBegin;
38270700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
382871f87433Sdalcinl   PetscValidPointer(flag,2);
382971f87433Sdalcinl   *flag = snes->ksp_ewconv;
383071f87433Sdalcinl   PetscFunctionReturn(0);
383171f87433Sdalcinl }
383271f87433Sdalcinl 
383371f87433Sdalcinl #undef __FUNCT__
3834fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW"
383571f87433Sdalcinl /*@
3836fa9f3622SBarry Smith    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
383771f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
383871f87433Sdalcinl    Newton method.
383971f87433Sdalcinl 
38403f9fe445SBarry Smith    Logically Collective on SNES
384171f87433Sdalcinl 
384271f87433Sdalcinl    Input Parameters:
384371f87433Sdalcinl +    snes - SNES context
384471f87433Sdalcinl .    version - version 1, 2 (default is 2) or 3
384571f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
384671f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
384771f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
384871f87433Sdalcinl              (0 <= gamma2 <= 1)
384971f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
385071f87433Sdalcinl .    alpha2 - power for safeguard
385171f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
385271f87433Sdalcinl 
385371f87433Sdalcinl    Note:
385471f87433Sdalcinl    Version 3 was contributed by Luis Chacon, June 2006.
385571f87433Sdalcinl 
385671f87433Sdalcinl    Use PETSC_DEFAULT to retain the default for any of the parameters.
385771f87433Sdalcinl 
385871f87433Sdalcinl    Level: advanced
385971f87433Sdalcinl 
386071f87433Sdalcinl    Reference:
386171f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
386271f87433Sdalcinl    inexact Newton method", Utah State University Math. Stat. Dept. Res.
386371f87433Sdalcinl    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
386471f87433Sdalcinl 
386571f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
386671f87433Sdalcinl 
3867fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
386871f87433Sdalcinl @*/
38697087cfbeSBarry Smith PetscErrorCode  SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,
387071f87433Sdalcinl 							    PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
387171f87433Sdalcinl {
3872fa9f3622SBarry Smith   SNESKSPEW *kctx;
387371f87433Sdalcinl   PetscFunctionBegin;
38740700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3875fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
3876e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
3877c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,version,2);
3878c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_0,3);
3879c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_max,4);
3880c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,gamma,5);
3881c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha,6);
3882c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha2,7);
3883c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,threshold,8);
388471f87433Sdalcinl 
388571f87433Sdalcinl   if (version != PETSC_DEFAULT)   kctx->version   = version;
388671f87433Sdalcinl   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
388771f87433Sdalcinl   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
388871f87433Sdalcinl   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
388971f87433Sdalcinl   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
389071f87433Sdalcinl   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
389171f87433Sdalcinl   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
389271f87433Sdalcinl 
389371f87433Sdalcinl   if (kctx->version < 1 || kctx->version > 3) {
3894e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version);
389571f87433Sdalcinl   }
389671f87433Sdalcinl   if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
3897e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0);
389871f87433Sdalcinl   }
389971f87433Sdalcinl   if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
3900e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max);
390171f87433Sdalcinl   }
390271f87433Sdalcinl   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
3903e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma);
390471f87433Sdalcinl   }
390571f87433Sdalcinl   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
3906e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha);
390771f87433Sdalcinl   }
390871f87433Sdalcinl   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
3909e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold);
391071f87433Sdalcinl   }
391171f87433Sdalcinl   PetscFunctionReturn(0);
391271f87433Sdalcinl }
391371f87433Sdalcinl 
391471f87433Sdalcinl #undef __FUNCT__
3915fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW"
391671f87433Sdalcinl /*@
3917fa9f3622SBarry Smith    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
391871f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
391971f87433Sdalcinl    Newton method.
392071f87433Sdalcinl 
392171f87433Sdalcinl    Not Collective
392271f87433Sdalcinl 
392371f87433Sdalcinl    Input Parameters:
392471f87433Sdalcinl      snes - SNES context
392571f87433Sdalcinl 
392671f87433Sdalcinl    Output Parameters:
392771f87433Sdalcinl +    version - version 1, 2 (default is 2) or 3
392871f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
392971f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
393071f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
393171f87433Sdalcinl              (0 <= gamma2 <= 1)
393271f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
393371f87433Sdalcinl .    alpha2 - power for safeguard
393471f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
393571f87433Sdalcinl 
393671f87433Sdalcinl    Level: advanced
393771f87433Sdalcinl 
393871f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters
393971f87433Sdalcinl 
3940fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
394171f87433Sdalcinl @*/
39427087cfbeSBarry Smith PetscErrorCode  SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,
394371f87433Sdalcinl 							    PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
394471f87433Sdalcinl {
3945fa9f3622SBarry Smith   SNESKSPEW *kctx;
394671f87433Sdalcinl   PetscFunctionBegin;
39470700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3948fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
3949e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
395071f87433Sdalcinl   if(version)   *version   = kctx->version;
395171f87433Sdalcinl   if(rtol_0)    *rtol_0    = kctx->rtol_0;
395271f87433Sdalcinl   if(rtol_max)  *rtol_max  = kctx->rtol_max;
395371f87433Sdalcinl   if(gamma)     *gamma     = kctx->gamma;
395471f87433Sdalcinl   if(alpha)     *alpha     = kctx->alpha;
395571f87433Sdalcinl   if(alpha2)    *alpha2    = kctx->alpha2;
395671f87433Sdalcinl   if(threshold) *threshold = kctx->threshold;
395771f87433Sdalcinl   PetscFunctionReturn(0);
395871f87433Sdalcinl }
395971f87433Sdalcinl 
396071f87433Sdalcinl #undef __FUNCT__
3961fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve"
3962fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x)
396371f87433Sdalcinl {
396471f87433Sdalcinl   PetscErrorCode ierr;
3965fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
396671f87433Sdalcinl   PetscReal      rtol=PETSC_DEFAULT,stol;
396771f87433Sdalcinl 
396871f87433Sdalcinl   PetscFunctionBegin;
3969e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
397071f87433Sdalcinl   if (!snes->iter) { /* first time in, so use the original user rtol */
397171f87433Sdalcinl     rtol = kctx->rtol_0;
397271f87433Sdalcinl   } else {
397371f87433Sdalcinl     if (kctx->version == 1) {
397471f87433Sdalcinl       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
397571f87433Sdalcinl       if (rtol < 0.0) rtol = -rtol;
397671f87433Sdalcinl       stol = pow(kctx->rtol_last,kctx->alpha2);
397771f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
397871f87433Sdalcinl     } else if (kctx->version == 2) {
397971f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
398071f87433Sdalcinl       stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
398171f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
398271f87433Sdalcinl     } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */
398371f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
398471f87433Sdalcinl       /* safeguard: avoid sharp decrease of rtol */
398571f87433Sdalcinl       stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha);
398671f87433Sdalcinl       stol = PetscMax(rtol,stol);
398771f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
398871f87433Sdalcinl       /* safeguard: avoid oversolving */
398971f87433Sdalcinl       stol = kctx->gamma*(snes->ttol)/snes->norm;
399071f87433Sdalcinl       stol = PetscMax(rtol,stol);
399171f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
3992e32f2f54SBarry Smith     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
399371f87433Sdalcinl   }
399471f87433Sdalcinl   /* safeguard: avoid rtol greater than one */
399571f87433Sdalcinl   rtol = PetscMin(rtol,kctx->rtol_max);
399671f87433Sdalcinl   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
399771f87433Sdalcinl   ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr);
399871f87433Sdalcinl   PetscFunctionReturn(0);
399971f87433Sdalcinl }
400071f87433Sdalcinl 
400171f87433Sdalcinl #undef __FUNCT__
4002fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve"
4003fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x)
400471f87433Sdalcinl {
400571f87433Sdalcinl   PetscErrorCode ierr;
4006fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
400771f87433Sdalcinl   PCSide         pcside;
400871f87433Sdalcinl   Vec            lres;
400971f87433Sdalcinl 
401071f87433Sdalcinl   PetscFunctionBegin;
4011e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
401271f87433Sdalcinl   ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr);
401371f87433Sdalcinl   ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr);
401471f87433Sdalcinl   if (kctx->version == 1) {
4015b037da10SBarry Smith     ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr);
401671f87433Sdalcinl     if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
401771f87433Sdalcinl       /* KSP residual is true linear residual */
401871f87433Sdalcinl       ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr);
401971f87433Sdalcinl     } else {
402071f87433Sdalcinl       /* KSP residual is preconditioned residual */
402171f87433Sdalcinl       /* compute true linear residual norm */
402271f87433Sdalcinl       ierr = VecDuplicate(b,&lres);CHKERRQ(ierr);
402371f87433Sdalcinl       ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr);
402471f87433Sdalcinl       ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr);
402571f87433Sdalcinl       ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr);
40266bf464f9SBarry Smith       ierr = VecDestroy(&lres);CHKERRQ(ierr);
402771f87433Sdalcinl     }
402871f87433Sdalcinl   }
402971f87433Sdalcinl   PetscFunctionReturn(0);
403071f87433Sdalcinl }
403171f87433Sdalcinl 
403271f87433Sdalcinl #undef __FUNCT__
403371f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve"
403471f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x)
403571f87433Sdalcinl {
403671f87433Sdalcinl   PetscErrorCode ierr;
403771f87433Sdalcinl 
403871f87433Sdalcinl   PetscFunctionBegin;
4039fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr);  }
404071f87433Sdalcinl   ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr);
4041fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); }
404271f87433Sdalcinl   PetscFunctionReturn(0);
404371f87433Sdalcinl }
40446c699258SBarry Smith 
40456c699258SBarry Smith #undef __FUNCT__
40466c699258SBarry Smith #define __FUNCT__ "SNESSetDM"
40476c699258SBarry Smith /*@
40486c699258SBarry Smith    SNESSetDM - Sets the DM that may be used by some preconditioners
40496c699258SBarry Smith 
40503f9fe445SBarry Smith    Logically Collective on SNES
40516c699258SBarry Smith 
40526c699258SBarry Smith    Input Parameters:
40536c699258SBarry Smith +  snes - the preconditioner context
40546c699258SBarry Smith -  dm - the dm
40556c699258SBarry Smith 
40566c699258SBarry Smith    Level: intermediate
40576c699258SBarry Smith 
40586c699258SBarry Smith 
40596c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM()
40606c699258SBarry Smith @*/
40617087cfbeSBarry Smith PetscErrorCode  SNESSetDM(SNES snes,DM dm)
40626c699258SBarry Smith {
40636c699258SBarry Smith   PetscErrorCode ierr;
4064345fed2cSBarry Smith   KSP            ksp;
40656cab3a1bSJed Brown   SNESDM         sdm;
40666c699258SBarry Smith 
40676c699258SBarry Smith   PetscFunctionBegin;
40680700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4069d0660788SBarry Smith   if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);}
40706cab3a1bSJed Brown   if (snes->dm) {               /* Move the SNESDM context over to the new DM unless the new DM already has one */
40716cab3a1bSJed Brown     PetscContainer oldcontainer,container;
40726cab3a1bSJed Brown     ierr = PetscObjectQuery((PetscObject)snes->dm,"SNESDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr);
40736cab3a1bSJed Brown     ierr = PetscObjectQuery((PetscObject)dm,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr);
40746cab3a1bSJed Brown     if (oldcontainer && !container) {
40756cab3a1bSJed Brown       ierr = DMSNESCopyContext(snes->dm,dm);CHKERRQ(ierr);
40766cab3a1bSJed Brown       ierr = DMSNESGetContext(snes->dm,&sdm);CHKERRQ(ierr);
40776cab3a1bSJed Brown       if (sdm->originaldm == snes->dm) { /* Grant write privileges to the replacement DM */
40786cab3a1bSJed Brown         sdm->originaldm = dm;
40796cab3a1bSJed Brown       }
40806cab3a1bSJed Brown     }
40816bf464f9SBarry Smith     ierr = DMDestroy(&snes->dm);CHKERRQ(ierr);
40826cab3a1bSJed Brown   }
40836c699258SBarry Smith   snes->dm = dm;
4084345fed2cSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
4085345fed2cSBarry Smith   ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr);
4086f22f69f0SBarry Smith   ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr);
40872c155ee1SBarry Smith   if (snes->pc) {
40882c155ee1SBarry Smith     ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr);
40892c155ee1SBarry Smith   }
40906c699258SBarry Smith   PetscFunctionReturn(0);
40916c699258SBarry Smith }
40926c699258SBarry Smith 
40936c699258SBarry Smith #undef __FUNCT__
40946c699258SBarry Smith #define __FUNCT__ "SNESGetDM"
40956c699258SBarry Smith /*@
40966c699258SBarry Smith    SNESGetDM - Gets the DM that may be used by some preconditioners
40976c699258SBarry Smith 
40983f9fe445SBarry Smith    Not Collective but DM obtained is parallel on SNES
40996c699258SBarry Smith 
41006c699258SBarry Smith    Input Parameter:
41016c699258SBarry Smith . snes - the preconditioner context
41026c699258SBarry Smith 
41036c699258SBarry Smith    Output Parameter:
41046c699258SBarry Smith .  dm - the dm
41056c699258SBarry Smith 
41066c699258SBarry Smith    Level: intermediate
41076c699258SBarry Smith 
41086c699258SBarry Smith 
41096c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM()
41106c699258SBarry Smith @*/
41117087cfbeSBarry Smith PetscErrorCode  SNESGetDM(SNES snes,DM *dm)
41126c699258SBarry Smith {
41136cab3a1bSJed Brown   PetscErrorCode ierr;
41146cab3a1bSJed Brown 
41156c699258SBarry Smith   PetscFunctionBegin;
41160700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
41176cab3a1bSJed Brown   if (!snes->dm) {
41186cab3a1bSJed Brown     ierr = DMShellCreate(((PetscObject)snes)->comm,&snes->dm);CHKERRQ(ierr);
41196cab3a1bSJed Brown   }
41206c699258SBarry Smith   *dm = snes->dm;
41216c699258SBarry Smith   PetscFunctionReturn(0);
41226c699258SBarry Smith }
41230807856dSBarry Smith 
412431823bd8SMatthew G Knepley #undef __FUNCT__
412531823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC"
412631823bd8SMatthew G Knepley /*@
4127fd4b34e9SJed Brown   SNESSetPC - Sets the nonlinear preconditioner to be used.
412831823bd8SMatthew G Knepley 
412931823bd8SMatthew G Knepley   Collective on SNES
413031823bd8SMatthew G Knepley 
413131823bd8SMatthew G Knepley   Input Parameters:
413231823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate()
413331823bd8SMatthew G Knepley - pc   - the preconditioner object
413431823bd8SMatthew G Knepley 
413531823bd8SMatthew G Knepley   Notes:
413631823bd8SMatthew G Knepley   Use SNESGetPC() to retrieve the preconditioner context (for example,
413731823bd8SMatthew G Knepley   to configure it using the API).
413831823bd8SMatthew G Knepley 
413931823bd8SMatthew G Knepley   Level: developer
414031823bd8SMatthew G Knepley 
414131823bd8SMatthew G Knepley .keywords: SNES, set, precondition
414231823bd8SMatthew G Knepley .seealso: SNESGetPC()
414331823bd8SMatthew G Knepley @*/
414431823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc)
414531823bd8SMatthew G Knepley {
414631823bd8SMatthew G Knepley   PetscErrorCode ierr;
414731823bd8SMatthew G Knepley 
414831823bd8SMatthew G Knepley   PetscFunctionBegin;
414931823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
415031823bd8SMatthew G Knepley   PetscValidHeaderSpecific(pc, SNES_CLASSID, 2);
415131823bd8SMatthew G Knepley   PetscCheckSameComm(snes, 1, pc, 2);
415231823bd8SMatthew G Knepley   ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr);
4153bf11d3b6SBarry Smith   ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr);
415431823bd8SMatthew G Knepley   snes->pc = pc;
415531823bd8SMatthew G Knepley   ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr);
415631823bd8SMatthew G Knepley   PetscFunctionReturn(0);
415731823bd8SMatthew G Knepley }
415831823bd8SMatthew G Knepley 
415931823bd8SMatthew G Knepley #undef __FUNCT__
416031823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC"
416131823bd8SMatthew G Knepley /*@
4162fd4b34e9SJed Brown   SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC().
416331823bd8SMatthew G Knepley 
416431823bd8SMatthew G Knepley   Not Collective
416531823bd8SMatthew G Knepley 
416631823bd8SMatthew G Knepley   Input Parameter:
416731823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate()
416831823bd8SMatthew G Knepley 
416931823bd8SMatthew G Knepley   Output Parameter:
417031823bd8SMatthew G Knepley . pc - preconditioner context
417131823bd8SMatthew G Knepley 
417231823bd8SMatthew G Knepley   Level: developer
417331823bd8SMatthew G Knepley 
417431823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner
417531823bd8SMatthew G Knepley .seealso: SNESSetPC()
417631823bd8SMatthew G Knepley @*/
417731823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc)
417831823bd8SMatthew G Knepley {
417931823bd8SMatthew G Knepley   PetscErrorCode ierr;
418031823bd8SMatthew G Knepley 
418131823bd8SMatthew G Knepley   PetscFunctionBegin;
418231823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
418331823bd8SMatthew G Knepley   PetscValidPointer(pc, 2);
418431823bd8SMatthew G Knepley   if (!snes->pc) {
418531823bd8SMatthew G Knepley     ierr = SNESCreate(((PetscObject) snes)->comm, &snes->pc);CHKERRQ(ierr);
41864a0c5b0cSMatthew G Knepley     ierr = PetscObjectIncrementTabLevel((PetscObject) snes->pc, (PetscObject) snes, 1);CHKERRQ(ierr);
418731823bd8SMatthew G Knepley     ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr);
418831823bd8SMatthew G Knepley   }
418931823bd8SMatthew G Knepley   *pc = snes->pc;
419031823bd8SMatthew G Knepley   PetscFunctionReturn(0);
419131823bd8SMatthew G Knepley }
419231823bd8SMatthew G Knepley 
419369b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
4194c6db04a5SJed Brown #include <mex.h>
419569b4f73cSBarry Smith 
41968f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext;
41978f6e6473SBarry Smith 
41980807856dSBarry Smith #undef __FUNCT__
41990807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab"
42000807856dSBarry Smith /*
42010807856dSBarry Smith    SNESComputeFunction_Matlab - Calls the function that has been set with
42020807856dSBarry Smith                          SNESSetFunctionMatlab().
42030807856dSBarry Smith 
42040807856dSBarry Smith    Collective on SNES
42050807856dSBarry Smith 
42060807856dSBarry Smith    Input Parameters:
42070807856dSBarry Smith +  snes - the SNES context
42080807856dSBarry Smith -  x - input vector
42090807856dSBarry Smith 
42100807856dSBarry Smith    Output Parameter:
42110807856dSBarry Smith .  y - function vector, as set by SNESSetFunction()
42120807856dSBarry Smith 
42130807856dSBarry Smith    Notes:
42140807856dSBarry Smith    SNESComputeFunction() is typically used within nonlinear solvers
42150807856dSBarry Smith    implementations, so most users would not generally call this routine
42160807856dSBarry Smith    themselves.
42170807856dSBarry Smith 
42180807856dSBarry Smith    Level: developer
42190807856dSBarry Smith 
42200807856dSBarry Smith .keywords: SNES, nonlinear, compute, function
42210807856dSBarry Smith 
42220807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
422361b2408cSBarry Smith */
42247087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx)
42250807856dSBarry Smith {
4226e650e774SBarry Smith   PetscErrorCode    ierr;
42278f6e6473SBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
42288f6e6473SBarry Smith   int               nlhs = 1,nrhs = 5;
42298f6e6473SBarry Smith   mxArray	    *plhs[1],*prhs[5];
423091621f2eSBarry Smith   long long int     lx = 0,ly = 0,ls = 0;
4231e650e774SBarry Smith 
42320807856dSBarry Smith   PetscFunctionBegin;
42330807856dSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
42340807856dSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
42350807856dSBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
42360807856dSBarry Smith   PetscCheckSameComm(snes,1,x,2);
42370807856dSBarry Smith   PetscCheckSameComm(snes,1,y,3);
42380807856dSBarry Smith 
42390807856dSBarry Smith   /* call Matlab function in ctx with arguments x and y */
4240e650e774SBarry Smith 
424191621f2eSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4242e650e774SBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4243e650e774SBarry Smith   ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr);
424491621f2eSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
424591621f2eSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
424691621f2eSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)ly);
42478f6e6473SBarry Smith   prhs[3] =  mxCreateString(sctx->funcname);
42488f6e6473SBarry Smith   prhs[4] =  sctx->ctx;
4249b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr);
4250e650e774SBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4251e650e774SBarry Smith   mxDestroyArray(prhs[0]);
4252e650e774SBarry Smith   mxDestroyArray(prhs[1]);
4253e650e774SBarry Smith   mxDestroyArray(prhs[2]);
42548f6e6473SBarry Smith   mxDestroyArray(prhs[3]);
4255e650e774SBarry Smith   mxDestroyArray(plhs[0]);
42560807856dSBarry Smith   PetscFunctionReturn(0);
42570807856dSBarry Smith }
42580807856dSBarry Smith 
42590807856dSBarry Smith 
42600807856dSBarry Smith #undef __FUNCT__
42610807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab"
426261b2408cSBarry Smith /*
42630807856dSBarry Smith    SNESSetFunctionMatlab - Sets the function evaluation routine and function
42640807856dSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4265e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
42660807856dSBarry Smith 
42670807856dSBarry Smith    Logically Collective on SNES
42680807856dSBarry Smith 
42690807856dSBarry Smith    Input Parameters:
42700807856dSBarry Smith +  snes - the SNES context
42710807856dSBarry Smith .  r - vector to store function value
42720807856dSBarry Smith -  func - function evaluation routine
42730807856dSBarry Smith 
42740807856dSBarry Smith    Calling sequence of func:
427561b2408cSBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
42760807856dSBarry Smith 
42770807856dSBarry Smith 
42780807856dSBarry Smith    Notes:
42790807856dSBarry Smith    The Newton-like methods typically solve linear systems of the form
42800807856dSBarry Smith $      f'(x) x = -f(x),
42810807856dSBarry Smith    where f'(x) denotes the Jacobian matrix and f(x) is the function.
42820807856dSBarry Smith 
42830807856dSBarry Smith    Level: beginner
42840807856dSBarry Smith 
42850807856dSBarry Smith .keywords: SNES, nonlinear, set, function
42860807856dSBarry Smith 
42870807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
428861b2408cSBarry Smith */
42897087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx)
42900807856dSBarry Smith {
42910807856dSBarry Smith   PetscErrorCode    ierr;
42928f6e6473SBarry Smith   SNESMatlabContext *sctx;
42930807856dSBarry Smith 
42940807856dSBarry Smith   PetscFunctionBegin;
42958f6e6473SBarry Smith   /* currently sctx is memory bleed */
42968f6e6473SBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
42978f6e6473SBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
42988f6e6473SBarry Smith   /*
42998f6e6473SBarry Smith      This should work, but it doesn't
43008f6e6473SBarry Smith   sctx->ctx = ctx;
43018f6e6473SBarry Smith   mexMakeArrayPersistent(sctx->ctx);
43028f6e6473SBarry Smith   */
43038f6e6473SBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
43048f6e6473SBarry Smith   ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr);
43050807856dSBarry Smith   PetscFunctionReturn(0);
43060807856dSBarry Smith }
430769b4f73cSBarry Smith 
430861b2408cSBarry Smith #undef __FUNCT__
430961b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab"
431061b2408cSBarry Smith /*
431161b2408cSBarry Smith    SNESComputeJacobian_Matlab - Calls the function that has been set with
431261b2408cSBarry Smith                          SNESSetJacobianMatlab().
431361b2408cSBarry Smith 
431461b2408cSBarry Smith    Collective on SNES
431561b2408cSBarry Smith 
431661b2408cSBarry Smith    Input Parameters:
431761b2408cSBarry Smith +  snes - the SNES context
431861b2408cSBarry Smith .  x - input vector
431961b2408cSBarry Smith .  A, B - the matrices
432061b2408cSBarry Smith -  ctx - user context
432161b2408cSBarry Smith 
432261b2408cSBarry Smith    Output Parameter:
432361b2408cSBarry Smith .  flag - structure of the matrix
432461b2408cSBarry Smith 
432561b2408cSBarry Smith    Level: developer
432661b2408cSBarry Smith 
432761b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function
432861b2408cSBarry Smith 
432961b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
433061b2408cSBarry Smith @*/
43317087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx)
433261b2408cSBarry Smith {
433361b2408cSBarry Smith   PetscErrorCode    ierr;
433461b2408cSBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
433561b2408cSBarry Smith   int               nlhs = 2,nrhs = 6;
433661b2408cSBarry Smith   mxArray	    *plhs[2],*prhs[6];
433761b2408cSBarry Smith   long long int     lx = 0,lA = 0,ls = 0, lB = 0;
433861b2408cSBarry Smith 
433961b2408cSBarry Smith   PetscFunctionBegin;
434061b2408cSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
434161b2408cSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
434261b2408cSBarry Smith 
434361b2408cSBarry Smith   /* call Matlab function in ctx with arguments x and y */
434461b2408cSBarry Smith 
434561b2408cSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
434661b2408cSBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
434761b2408cSBarry Smith   ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr);
434861b2408cSBarry Smith   ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr);
434961b2408cSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
435061b2408cSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
435161b2408cSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)lA);
435261b2408cSBarry Smith   prhs[3] =  mxCreateDoubleScalar((double)lB);
435361b2408cSBarry Smith   prhs[4] =  mxCreateString(sctx->funcname);
435461b2408cSBarry Smith   prhs[5] =  sctx->ctx;
4355b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr);
435661b2408cSBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
435761b2408cSBarry Smith   *flag   =  (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr);
435861b2408cSBarry Smith   mxDestroyArray(prhs[0]);
435961b2408cSBarry Smith   mxDestroyArray(prhs[1]);
436061b2408cSBarry Smith   mxDestroyArray(prhs[2]);
436161b2408cSBarry Smith   mxDestroyArray(prhs[3]);
436261b2408cSBarry Smith   mxDestroyArray(prhs[4]);
436361b2408cSBarry Smith   mxDestroyArray(plhs[0]);
436461b2408cSBarry Smith   mxDestroyArray(plhs[1]);
436561b2408cSBarry Smith   PetscFunctionReturn(0);
436661b2408cSBarry Smith }
436761b2408cSBarry Smith 
436861b2408cSBarry Smith 
436961b2408cSBarry Smith #undef __FUNCT__
437061b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab"
437161b2408cSBarry Smith /*
437261b2408cSBarry Smith    SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
437361b2408cSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4374e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
437561b2408cSBarry Smith 
437661b2408cSBarry Smith    Logically Collective on SNES
437761b2408cSBarry Smith 
437861b2408cSBarry Smith    Input Parameters:
437961b2408cSBarry Smith +  snes - the SNES context
438061b2408cSBarry Smith .  A,B - Jacobian matrices
438161b2408cSBarry Smith .  func - function evaluation routine
438261b2408cSBarry Smith -  ctx - user context
438361b2408cSBarry Smith 
438461b2408cSBarry Smith    Calling sequence of func:
438561b2408cSBarry Smith $    flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx);
438661b2408cSBarry Smith 
438761b2408cSBarry Smith 
438861b2408cSBarry Smith    Level: developer
438961b2408cSBarry Smith 
439061b2408cSBarry Smith .keywords: SNES, nonlinear, set, function
439161b2408cSBarry Smith 
439261b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
439361b2408cSBarry Smith */
43947087cfbeSBarry Smith PetscErrorCode  SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx)
439561b2408cSBarry Smith {
439661b2408cSBarry Smith   PetscErrorCode    ierr;
439761b2408cSBarry Smith   SNESMatlabContext *sctx;
439861b2408cSBarry Smith 
439961b2408cSBarry Smith   PetscFunctionBegin;
440061b2408cSBarry Smith   /* currently sctx is memory bleed */
440161b2408cSBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
440261b2408cSBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
440361b2408cSBarry Smith   /*
440461b2408cSBarry Smith      This should work, but it doesn't
440561b2408cSBarry Smith   sctx->ctx = ctx;
440661b2408cSBarry Smith   mexMakeArrayPersistent(sctx->ctx);
440761b2408cSBarry Smith   */
440861b2408cSBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
440961b2408cSBarry Smith   ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
441061b2408cSBarry Smith   PetscFunctionReturn(0);
441161b2408cSBarry Smith }
441269b4f73cSBarry Smith 
4413f9eb7ae2SShri Abhyankar #undef __FUNCT__
4414f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab"
4415f9eb7ae2SShri Abhyankar /*
4416f9eb7ae2SShri Abhyankar    SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab().
4417f9eb7ae2SShri Abhyankar 
4418f9eb7ae2SShri Abhyankar    Collective on SNES
4419f9eb7ae2SShri Abhyankar 
4420f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction()
4421f9eb7ae2SShri Abhyankar @*/
44227087cfbeSBarry Smith PetscErrorCode  SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx)
4423f9eb7ae2SShri Abhyankar {
4424f9eb7ae2SShri Abhyankar   PetscErrorCode  ierr;
442548f37e70SShri Abhyankar   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
4426f9eb7ae2SShri Abhyankar   int             nlhs = 1,nrhs = 6;
4427f9eb7ae2SShri Abhyankar   mxArray	  *plhs[1],*prhs[6];
4428f9eb7ae2SShri Abhyankar   long long int   lx = 0,ls = 0;
4429f9eb7ae2SShri Abhyankar   Vec             x=snes->vec_sol;
4430f9eb7ae2SShri Abhyankar 
4431f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4432f9eb7ae2SShri Abhyankar   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4433f9eb7ae2SShri Abhyankar 
4434f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4435f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4436f9eb7ae2SShri Abhyankar   prhs[0] =  mxCreateDoubleScalar((double)ls);
4437f9eb7ae2SShri Abhyankar   prhs[1] =  mxCreateDoubleScalar((double)it);
4438f9eb7ae2SShri Abhyankar   prhs[2] =  mxCreateDoubleScalar((double)fnorm);
4439f9eb7ae2SShri Abhyankar   prhs[3] =  mxCreateDoubleScalar((double)lx);
4440f9eb7ae2SShri Abhyankar   prhs[4] =  mxCreateString(sctx->funcname);
4441f9eb7ae2SShri Abhyankar   prhs[5] =  sctx->ctx;
4442f9eb7ae2SShri Abhyankar   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr);
4443f9eb7ae2SShri Abhyankar   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4444f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[0]);
4445f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[1]);
4446f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[2]);
4447f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[3]);
4448f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[4]);
4449f9eb7ae2SShri Abhyankar   mxDestroyArray(plhs[0]);
4450f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
4451f9eb7ae2SShri Abhyankar }
4452f9eb7ae2SShri Abhyankar 
4453f9eb7ae2SShri Abhyankar 
4454f9eb7ae2SShri Abhyankar #undef __FUNCT__
4455f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab"
4456f9eb7ae2SShri Abhyankar /*
4457e3c5b3baSBarry Smith    SNESMonitorSetMatlab - Sets the monitor function from MATLAB
4458f9eb7ae2SShri Abhyankar 
4459f9eb7ae2SShri Abhyankar    Level: developer
4460f9eb7ae2SShri Abhyankar 
4461f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function
4462f9eb7ae2SShri Abhyankar 
4463f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
4464f9eb7ae2SShri Abhyankar */
44657087cfbeSBarry Smith PetscErrorCode  SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx)
4466f9eb7ae2SShri Abhyankar {
4467f9eb7ae2SShri Abhyankar   PetscErrorCode    ierr;
4468f9eb7ae2SShri Abhyankar   SNESMatlabContext *sctx;
4469f9eb7ae2SShri Abhyankar 
4470f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4471f9eb7ae2SShri Abhyankar   /* currently sctx is memory bleed */
4472f9eb7ae2SShri Abhyankar   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
4473f9eb7ae2SShri Abhyankar   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
4474f9eb7ae2SShri Abhyankar   /*
4475f9eb7ae2SShri Abhyankar      This should work, but it doesn't
4476f9eb7ae2SShri Abhyankar   sctx->ctx = ctx;
4477f9eb7ae2SShri Abhyankar   mexMakeArrayPersistent(sctx->ctx);
4478f9eb7ae2SShri Abhyankar   */
4479f9eb7ae2SShri Abhyankar   sctx->ctx = mxDuplicateArray(ctx);
4480f9eb7ae2SShri Abhyankar   ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr);
4481f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
4482f9eb7ae2SShri Abhyankar }
4483f9eb7ae2SShri Abhyankar 
448469b4f73cSBarry Smith #endif
4485