xref: /petsc/src/snes/interface/snes.c (revision 6a388c361ff2893f4363aecae9e02aa0b4e91a18)
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:
99*6a388c36SPeter 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 
115*6a388c36SPeter Brune 
116*6a388c36SPeter Brune #undef __FUNCT__
117*6a388c36SPeter Brune #define __FUNCT__ "SNESGetFunctionDomainError"
118*6a388c36SPeter Brune /*@
119*6a388c36SPeter Brune    SNESSetFunctionDomainError - Gets the status of the domain error after a call to SNESComputeFunction;
120*6a388c36SPeter Brune 
121*6a388c36SPeter Brune    Logically Collective on SNES
122*6a388c36SPeter Brune 
123*6a388c36SPeter Brune    Input Parameters:
124*6a388c36SPeter Brune .  snes - the SNES context
125*6a388c36SPeter Brune 
126*6a388c36SPeter Brune    Output Parameters:
127*6a388c36SPeter Brune .  domainerror Set to PETSC_TRUE if there's a domain error; PETSC_FALSE otherwise.
128*6a388c36SPeter Brune 
129*6a388c36SPeter Brune    Level: advanced
130*6a388c36SPeter Brune 
131*6a388c36SPeter Brune .keywords: SNES, view
132*6a388c36SPeter Brune 
133*6a388c36SPeter Brune .seealso: SNESSetFunctionDomainError, SNESComputeFunction()
134*6a388c36SPeter Brune @*/
135*6a388c36SPeter Brune PetscErrorCode  SNESGetFunctionDomainError(SNES snes, PetscBool *domainerror)
136*6a388c36SPeter Brune {
137*6a388c36SPeter Brune   PetscFunctionBegin;
138*6a388c36SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
139*6a388c36SPeter Brune   PetscValidPointer(domainerror, 2);
140*6a388c36SPeter Brune   *domainerror = snes->domainerror;
141*6a388c36SPeter Brune   PetscFunctionReturn(0);
142*6a388c36SPeter Brune }
143*6a388c36SPeter Brune 
144*6a388c36SPeter 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   } else if (!snes->vec_func && snes->dm) {
1370d2a683ecSLisandro Dalcin     ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr);
1371d2a683ecSLisandro Dalcin   }
13726cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
13736cab3a1bSJed Brown   ierr = DMSNESSetFunction(dm,func,ctx);CHKERRQ(ierr);
13743a40ed3dSBarry Smith   PetscFunctionReturn(0);
13759b94acceSBarry Smith }
13769b94acceSBarry Smith 
1377646217ecSPeter Brune 
1378646217ecSPeter Brune #undef __FUNCT__
1379646217ecSPeter Brune #define __FUNCT__ "SNESSetGS"
1380c79ef259SPeter Brune /*@C
1381c79ef259SPeter Brune    SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for
1382c79ef259SPeter Brune    use with composed nonlinear solvers.
1383c79ef259SPeter Brune 
1384c79ef259SPeter Brune    Input Parameters:
1385c79ef259SPeter Brune +  snes   - the SNES context
1386c79ef259SPeter Brune .  gsfunc - function evaluation routine
1387c79ef259SPeter Brune -  ctx    - [optional] user-defined context for private data for the
1388c79ef259SPeter Brune             smoother evaluation routine (may be PETSC_NULL)
1389c79ef259SPeter Brune 
1390c79ef259SPeter Brune    Calling sequence of func:
1391c79ef259SPeter Brune $    func (SNES snes,Vec x,Vec b,void *ctx);
1392c79ef259SPeter Brune 
1393c79ef259SPeter Brune +  X   - solution vector
1394c79ef259SPeter Brune .  B   - RHS vector
1395d28543b3SPeter Brune -  ctx - optional user-defined Gauss-Seidel context
1396c79ef259SPeter Brune 
1397c79ef259SPeter Brune    Notes:
1398c79ef259SPeter Brune    The GS routines are used by the composed nonlinear solver to generate
1399c79ef259SPeter Brune     a problem appropriate update to the solution, particularly FAS.
1400c79ef259SPeter Brune 
1401d28543b3SPeter Brune    Level: intermediate
1402c79ef259SPeter Brune 
1403d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel
1404c79ef259SPeter Brune 
1405c79ef259SPeter Brune .seealso: SNESGetFunction(), SNESComputeGS()
1406c79ef259SPeter Brune @*/
14076cab3a1bSJed Brown PetscErrorCode SNESSetGS(SNES snes,PetscErrorCode (*gsfunc)(SNES,Vec,Vec,void*),void *ctx)
14086cab3a1bSJed Brown {
14096cab3a1bSJed Brown   PetscErrorCode ierr;
14106cab3a1bSJed Brown   DM dm;
14116cab3a1bSJed Brown 
1412646217ecSPeter Brune   PetscFunctionBegin;
14136cab3a1bSJed Brown   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
14146cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
14156cab3a1bSJed Brown   ierr = DMSNESSetGS(dm,gsfunc,ctx);CHKERRQ(ierr);
1416646217ecSPeter Brune   PetscFunctionReturn(0);
1417646217ecSPeter Brune }
1418646217ecSPeter Brune 
1419d25893d9SBarry Smith #undef __FUNCT__
142089b92e6fSPeter Brune #define __FUNCT__ "SNESSetGSSweeps"
142189b92e6fSPeter Brune /*@
142289b92e6fSPeter Brune    SNESSetGSSweeps - Sets the number of sweeps of GS to use.
142389b92e6fSPeter Brune 
142489b92e6fSPeter Brune    Input Parameters:
142589b92e6fSPeter Brune +  snes   - the SNES context
142689b92e6fSPeter Brune -  sweeps  - the number of sweeps of GS to perform.
142789b92e6fSPeter Brune 
142889b92e6fSPeter Brune    Level: intermediate
142989b92e6fSPeter Brune 
143089b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel
143189b92e6fSPeter Brune 
143289b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGetGSSweeps()
143389b92e6fSPeter Brune @*/
143489b92e6fSPeter Brune 
143589b92e6fSPeter Brune PetscErrorCode SNESSetGSSweeps(SNES snes, PetscInt sweeps) {
143689b92e6fSPeter Brune   PetscFunctionBegin;
143789b92e6fSPeter Brune   snes->gssweeps = sweeps;
143889b92e6fSPeter Brune   PetscFunctionReturn(0);
143989b92e6fSPeter Brune }
144089b92e6fSPeter Brune 
144189b92e6fSPeter Brune 
144289b92e6fSPeter Brune #undef __FUNCT__
144389b92e6fSPeter Brune #define __FUNCT__ "SNESGetGSSweeps"
144489b92e6fSPeter Brune /*@
144589b92e6fSPeter Brune    SNESGetGSSweeps - Gets the number of sweeps GS will use.
144689b92e6fSPeter Brune 
144789b92e6fSPeter Brune    Input Parameters:
144889b92e6fSPeter Brune .  snes   - the SNES context
144989b92e6fSPeter Brune 
145089b92e6fSPeter Brune    Output Parameters:
145189b92e6fSPeter Brune .  sweeps  - the number of sweeps of GS to perform.
145289b92e6fSPeter Brune 
145389b92e6fSPeter Brune    Level: intermediate
145489b92e6fSPeter Brune 
145589b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel
145689b92e6fSPeter Brune 
145789b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESSetGSSweeps()
145889b92e6fSPeter Brune @*/
145989b92e6fSPeter Brune PetscErrorCode SNESGetGSSweeps(SNES snes, PetscInt * sweeps) {
146089b92e6fSPeter Brune   PetscFunctionBegin;
146189b92e6fSPeter Brune   *sweeps = snes->gssweeps;
146289b92e6fSPeter Brune   PetscFunctionReturn(0);
146389b92e6fSPeter Brune }
146489b92e6fSPeter Brune 
146589b92e6fSPeter Brune #undef __FUNCT__
14668b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction"
14678b0a5094SBarry Smith PetscErrorCode  SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx)
14688b0a5094SBarry Smith {
14698b0a5094SBarry Smith   PetscErrorCode ierr;
14706cab3a1bSJed Brown   void *functx,*jacctx;
14716cab3a1bSJed Brown 
14728b0a5094SBarry Smith   PetscFunctionBegin;
14736cab3a1bSJed Brown   ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
14746cab3a1bSJed Brown   ierr = SNESGetJacobian(snes,PETSC_NULL,PETSC_NULL,PETSC_NULL,&jacctx);CHKERRQ(ierr);
14758b0a5094SBarry Smith   /*  A(x)*x - b(x) */
14766cab3a1bSJed Brown   ierr = (*snes->ops->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,jacctx);CHKERRQ(ierr);
14776cab3a1bSJed Brown   ierr = (*snes->ops->computepfunction)(snes,x,f,functx);CHKERRQ(ierr);
14788b0a5094SBarry Smith   ierr = VecView(x,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr);
14798b0a5094SBarry Smith   ierr = VecView(f,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr);
14808b0a5094SBarry Smith   ierr = VecScale(f,-1.0);CHKERRQ(ierr);
14818b0a5094SBarry Smith   ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr);
14828b0a5094SBarry Smith   PetscFunctionReturn(0);
14838b0a5094SBarry Smith }
14848b0a5094SBarry Smith 
14858b0a5094SBarry Smith #undef __FUNCT__
14868b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian"
14878b0a5094SBarry Smith PetscErrorCode  SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx)
14888b0a5094SBarry Smith {
14898b0a5094SBarry Smith   PetscFunctionBegin;
14908b0a5094SBarry Smith   *flag = snes->matstruct;
14918b0a5094SBarry Smith   PetscFunctionReturn(0);
14928b0a5094SBarry Smith }
14938b0a5094SBarry Smith 
14948b0a5094SBarry Smith #undef __FUNCT__
14958b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard"
14968b0a5094SBarry Smith /*@C
14970d04baf8SBarry Smith    SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization)
14988b0a5094SBarry Smith 
14998b0a5094SBarry Smith    Logically Collective on SNES
15008b0a5094SBarry Smith 
15018b0a5094SBarry Smith    Input Parameters:
15028b0a5094SBarry Smith +  snes - the SNES context
15038b0a5094SBarry Smith .  r - vector to store function value
15048b0a5094SBarry Smith .  func - function evaluation routine
15058b0a5094SBarry 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)
15068b0a5094SBarry Smith .  mat - matrix to store A
15078b0a5094SBarry Smith .  mfunc  - function to compute matrix value
15088b0a5094SBarry Smith -  ctx - [optional] user-defined context for private data for the
15098b0a5094SBarry Smith          function evaluation routine (may be PETSC_NULL)
15108b0a5094SBarry Smith 
15118b0a5094SBarry Smith    Calling sequence of func:
15128b0a5094SBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
15138b0a5094SBarry Smith 
15148b0a5094SBarry Smith +  f - function vector
15158b0a5094SBarry Smith -  ctx - optional user-defined function context
15168b0a5094SBarry Smith 
15178b0a5094SBarry Smith    Calling sequence of mfunc:
15188b0a5094SBarry Smith $     mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx);
15198b0a5094SBarry Smith 
15208b0a5094SBarry Smith +  x - input vector
15218b0a5094SBarry 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(),
15228b0a5094SBarry Smith           normally just pass mat in this location
15238b0a5094SBarry Smith .  mat - form A(x) matrix
15248b0a5094SBarry Smith .  flag - flag indicating information about the preconditioner matrix
15258b0a5094SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
15268b0a5094SBarry Smith -  ctx - [optional] user-defined Jacobian context
15278b0a5094SBarry Smith 
15288b0a5094SBarry Smith    Notes:
15298b0a5094SBarry Smith     One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both
15308b0a5094SBarry Smith 
15318b0a5094SBarry 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}
15328b0a5094SBarry 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.
15338b0a5094SBarry Smith 
15348b0a5094SBarry Smith      Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner.
15358b0a5094SBarry Smith 
15360d04baf8SBarry Smith    We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then
15370d04baf8SBarry Smith    the direct Picard iteration A(x^n) x^{n+1} = b(x^n)
15388b0a5094SBarry Smith 
15398b0a5094SBarry 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
15408b0a5094SBarry 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
15418b0a5094SBarry Smith    different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-).
15428b0a5094SBarry Smith 
15438b0a5094SBarry Smith    Level: beginner
15448b0a5094SBarry Smith 
15458b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function
15468b0a5094SBarry Smith 
15470d04baf8SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard()
15488b0a5094SBarry Smith @*/
15498b0a5094SBarry 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)
15508b0a5094SBarry Smith {
15518b0a5094SBarry Smith   PetscErrorCode ierr;
15528b0a5094SBarry Smith   PetscFunctionBegin;
15538b0a5094SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
15548b0a5094SBarry Smith   snes->ops->computepfunction = func;
15558b0a5094SBarry Smith   snes->ops->computepjacobian = mfunc;
15568b0a5094SBarry Smith   ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr);
15578b0a5094SBarry Smith   ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr);
15588b0a5094SBarry Smith   PetscFunctionReturn(0);
15598b0a5094SBarry Smith }
15608b0a5094SBarry Smith 
15618b0a5094SBarry Smith #undef __FUNCT__
1562d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess"
1563d25893d9SBarry Smith /*@C
1564d25893d9SBarry Smith    SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem
1565d25893d9SBarry Smith 
1566d25893d9SBarry Smith    Logically Collective on SNES
1567d25893d9SBarry Smith 
1568d25893d9SBarry Smith    Input Parameters:
1569d25893d9SBarry Smith +  snes - the SNES context
1570d25893d9SBarry Smith .  func - function evaluation routine
1571d25893d9SBarry Smith -  ctx - [optional] user-defined context for private data for the
1572d25893d9SBarry Smith          function evaluation routine (may be PETSC_NULL)
1573d25893d9SBarry Smith 
1574d25893d9SBarry Smith    Calling sequence of func:
1575d25893d9SBarry Smith $    func (SNES snes,Vec x,void *ctx);
1576d25893d9SBarry Smith 
1577d25893d9SBarry Smith .  f - function vector
1578d25893d9SBarry Smith -  ctx - optional user-defined function context
1579d25893d9SBarry Smith 
1580d25893d9SBarry Smith    Level: intermediate
1581d25893d9SBarry Smith 
1582d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function
1583d25893d9SBarry Smith 
1584d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
1585d25893d9SBarry Smith @*/
1586d25893d9SBarry Smith PetscErrorCode  SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx)
1587d25893d9SBarry Smith {
1588d25893d9SBarry Smith   PetscFunctionBegin;
1589d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1590d25893d9SBarry Smith   if (func) snes->ops->computeinitialguess = func;
1591d25893d9SBarry Smith   if (ctx)  snes->initialguessP            = ctx;
1592d25893d9SBarry Smith   PetscFunctionReturn(0);
1593d25893d9SBarry Smith }
1594d25893d9SBarry Smith 
15953ab0aad5SBarry Smith /* --------------------------------------------------------------- */
15963ab0aad5SBarry Smith #undef __FUNCT__
15971096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs"
15981096aae1SMatthew Knepley /*@C
15991096aae1SMatthew Knepley    SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
16001096aae1SMatthew Knepley    it assumes a zero right hand side.
16011096aae1SMatthew Knepley 
16023f9fe445SBarry Smith    Logically Collective on SNES
16031096aae1SMatthew Knepley 
16041096aae1SMatthew Knepley    Input Parameter:
16051096aae1SMatthew Knepley .  snes - the SNES context
16061096aae1SMatthew Knepley 
16071096aae1SMatthew Knepley    Output Parameter:
1608bc08b0f1SBarry Smith .  rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null
16091096aae1SMatthew Knepley 
16101096aae1SMatthew Knepley    Level: intermediate
16111096aae1SMatthew Knepley 
16121096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side
16131096aae1SMatthew Knepley 
161485385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
16151096aae1SMatthew Knepley @*/
16167087cfbeSBarry Smith PetscErrorCode  SNESGetRhs(SNES snes,Vec *rhs)
16171096aae1SMatthew Knepley {
16181096aae1SMatthew Knepley   PetscFunctionBegin;
16190700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
16201096aae1SMatthew Knepley   PetscValidPointer(rhs,2);
162185385478SLisandro Dalcin   *rhs = snes->vec_rhs;
16221096aae1SMatthew Knepley   PetscFunctionReturn(0);
16231096aae1SMatthew Knepley }
16241096aae1SMatthew Knepley 
16251096aae1SMatthew Knepley #undef __FUNCT__
16264a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction"
16279b94acceSBarry Smith /*@
162836851e7fSLois Curfman McInnes    SNESComputeFunction - Calls the function that has been set with
16299b94acceSBarry Smith                          SNESSetFunction().
16309b94acceSBarry Smith 
1631c7afd0dbSLois Curfman McInnes    Collective on SNES
1632c7afd0dbSLois Curfman McInnes 
16339b94acceSBarry Smith    Input Parameters:
1634c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1635c7afd0dbSLois Curfman McInnes -  x - input vector
16369b94acceSBarry Smith 
16379b94acceSBarry Smith    Output Parameter:
16383638b69dSLois Curfman McInnes .  y - function vector, as set by SNESSetFunction()
16399b94acceSBarry Smith 
16401bffabb2SLois Curfman McInnes    Notes:
164136851e7fSLois Curfman McInnes    SNESComputeFunction() is typically used within nonlinear solvers
164236851e7fSLois Curfman McInnes    implementations, so most users would not generally call this routine
164336851e7fSLois Curfman McInnes    themselves.
164436851e7fSLois Curfman McInnes 
164536851e7fSLois Curfman McInnes    Level: developer
164636851e7fSLois Curfman McInnes 
16479b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function
16489b94acceSBarry Smith 
1649a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction()
16509b94acceSBarry Smith @*/
16517087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction(SNES snes,Vec x,Vec y)
16529b94acceSBarry Smith {
1653dfbe8321SBarry Smith   PetscErrorCode ierr;
16546cab3a1bSJed Brown   DM             dm;
16556cab3a1bSJed Brown   SNESDM         sdm;
16569b94acceSBarry Smith 
16573a40ed3dSBarry Smith   PetscFunctionBegin;
16580700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
16590700a824SBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
16600700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
1661c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,x,2);
1662c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,3);
16634ec14c9cSBarry Smith   VecValidValues(x,2,PETSC_TRUE);
1664184914b5SBarry Smith 
16656cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
16666cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
1667d5ba7fb7SMatthew Knepley   ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
16686cab3a1bSJed Brown   if (sdm->computefunction) {
1669d64ed03dSBarry Smith     PetscStackPush("SNES user function");
16706cab3a1bSJed Brown     ierr = (*sdm->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr);
1671d64ed03dSBarry Smith     PetscStackPop;
167273250ac0SBarry Smith   } else if (snes->dm) {
1673644e2e5bSBarry Smith     ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr);
1674c90fad12SPeter Brune   } else if (snes->vec_rhs) {
1675c90fad12SPeter Brune     ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr);
1676644e2e5bSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve().");
167785385478SLisandro Dalcin   if (snes->vec_rhs) {
167885385478SLisandro Dalcin     ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr);
16793ab0aad5SBarry Smith   }
1680ae3c334cSLois Curfman McInnes   snes->nfuncs++;
1681d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
16824ec14c9cSBarry Smith   VecValidValues(y,3,PETSC_FALSE);
16833a40ed3dSBarry Smith   PetscFunctionReturn(0);
16849b94acceSBarry Smith }
16859b94acceSBarry Smith 
16864a2ae208SSatish Balay #undef __FUNCT__
1687646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS"
1688c79ef259SPeter Brune /*@
1689c79ef259SPeter Brune    SNESComputeGS - Calls the Gauss-Seidel function that has been set with
1690c79ef259SPeter Brune                    SNESSetGS().
1691c79ef259SPeter Brune 
1692c79ef259SPeter Brune    Collective on SNES
1693c79ef259SPeter Brune 
1694c79ef259SPeter Brune    Input Parameters:
1695c79ef259SPeter Brune +  snes - the SNES context
1696c79ef259SPeter Brune .  x - input vector
1697c79ef259SPeter Brune -  b - rhs vector
1698c79ef259SPeter Brune 
1699c79ef259SPeter Brune    Output Parameter:
1700c79ef259SPeter Brune .  x - new solution vector
1701c79ef259SPeter Brune 
1702c79ef259SPeter Brune    Notes:
1703c79ef259SPeter Brune    SNESComputeGS() is typically used within composed nonlinear solver
1704c79ef259SPeter Brune    implementations, so most users would not generally call this routine
1705c79ef259SPeter Brune    themselves.
1706c79ef259SPeter Brune 
1707c79ef259SPeter Brune    Level: developer
1708c79ef259SPeter Brune 
1709c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function
1710c79ef259SPeter Brune 
1711c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction()
1712c79ef259SPeter Brune @*/
1713646217ecSPeter Brune PetscErrorCode  SNESComputeGS(SNES snes,Vec b,Vec x)
1714646217ecSPeter Brune {
1715646217ecSPeter Brune   PetscErrorCode ierr;
171689b92e6fSPeter Brune   PetscInt i;
17176cab3a1bSJed Brown   DM dm;
17186cab3a1bSJed Brown   SNESDM sdm;
1719646217ecSPeter Brune 
1720646217ecSPeter Brune   PetscFunctionBegin;
1721646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1722646217ecSPeter Brune   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
1723646217ecSPeter Brune   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3);
1724646217ecSPeter Brune   PetscCheckSameComm(snes,1,x,2);
1725646217ecSPeter Brune   if(b) PetscCheckSameComm(snes,1,b,3);
17264ec14c9cSBarry Smith   if (b) VecValidValues(b,2,PETSC_TRUE);
1727701cf23dSPeter Brune   ierr = PetscLogEventBegin(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr);
17286cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
17296cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
17306cab3a1bSJed Brown   if (sdm->computegs) {
173189b92e6fSPeter Brune     for (i = 0; i < snes->gssweeps; i++) {
1732646217ecSPeter Brune       PetscStackPush("SNES user GS");
17336cab3a1bSJed Brown       ierr = (*sdm->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr);
1734646217ecSPeter Brune       PetscStackPop;
173589b92e6fSPeter Brune     }
1736646217ecSPeter Brune   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve().");
1737701cf23dSPeter Brune   ierr = PetscLogEventEnd(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr);
17384ec14c9cSBarry Smith   VecValidValues(x,3,PETSC_FALSE);
1739646217ecSPeter Brune   PetscFunctionReturn(0);
1740646217ecSPeter Brune }
1741646217ecSPeter Brune 
1742646217ecSPeter Brune 
1743646217ecSPeter Brune #undef __FUNCT__
17444a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian"
174562fef451SLois Curfman McInnes /*@
174662fef451SLois Curfman McInnes    SNESComputeJacobian - Computes the Jacobian matrix that has been
174762fef451SLois Curfman McInnes    set with SNESSetJacobian().
174862fef451SLois Curfman McInnes 
1749c7afd0dbSLois Curfman McInnes    Collective on SNES and Mat
1750c7afd0dbSLois Curfman McInnes 
175162fef451SLois Curfman McInnes    Input Parameters:
1752c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1753c7afd0dbSLois Curfman McInnes -  x - input vector
175462fef451SLois Curfman McInnes 
175562fef451SLois Curfman McInnes    Output Parameters:
1756c7afd0dbSLois Curfman McInnes +  A - Jacobian matrix
175762fef451SLois Curfman McInnes .  B - optional preconditioning matrix
17582b668275SBarry Smith -  flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER)
1759fee21e36SBarry Smith 
1760e35cf81dSBarry Smith   Options Database Keys:
1761e35cf81dSBarry Smith +    -snes_lag_preconditioner <lag>
1762693365a8SJed Brown .    -snes_lag_jacobian <lag>
1763693365a8SJed Brown .    -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences
1764693365a8SJed Brown .    -snes_compare_explicit_draw  - Compare the computed Jacobian to the finite difference Jacobian and draw the result
1765693365a8SJed Brown .    -snes_compare_explicit_contour  - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result
17664c30e9fbSJed Brown .    -snes_compare_operator  - Make the comparison options above use the operator instead of the preconditioning matrix
1767c01495d3SJed Brown .    -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference
1768c01495d3SJed Brown .    -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences
1769c01495d3SJed Brown .    -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold
1770c01495d3SJed Brown .    -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
1771c01495d3SJed Brown .    -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
17724c30e9fbSJed Brown .    -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences
1773c01495d3SJed Brown -    -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences
1774c01495d3SJed Brown 
1775e35cf81dSBarry Smith 
177662fef451SLois Curfman McInnes    Notes:
177762fef451SLois Curfman McInnes    Most users should not need to explicitly call this routine, as it
177862fef451SLois Curfman McInnes    is used internally within the nonlinear solvers.
177962fef451SLois Curfman McInnes 
178094b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the
1781dc5a77f8SLois Curfman McInnes    flag parameter.
178262fef451SLois Curfman McInnes 
178336851e7fSLois Curfman McInnes    Level: developer
178436851e7fSLois Curfman McInnes 
178562fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix
178662fef451SLois Curfman McInnes 
1787e35cf81dSBarry Smith .seealso:  SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian()
178862fef451SLois Curfman McInnes @*/
17897087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg)
17909b94acceSBarry Smith {
1791dfbe8321SBarry Smith   PetscErrorCode ierr;
1792ace3abfcSBarry Smith   PetscBool      flag;
17936cab3a1bSJed Brown   DM             dm;
17946cab3a1bSJed Brown   SNESDM         sdm;
17953a40ed3dSBarry Smith 
17963a40ed3dSBarry Smith   PetscFunctionBegin;
17970700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
17980700a824SBarry Smith   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
17994482741eSBarry Smith   PetscValidPointer(flg,5);
1800c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,X,2);
18014ec14c9cSBarry Smith   VecValidValues(X,2,PETSC_TRUE);
18026cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
18036cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
18046cab3a1bSJed Brown   if (!sdm->computejacobian) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc");
1805ebd3b9afSBarry Smith 
1806ebd3b9afSBarry Smith   /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */
1807ebd3b9afSBarry Smith 
1808fe3ffe1eSBarry Smith   if (snes->lagjacobian == -2) {
1809fe3ffe1eSBarry Smith     snes->lagjacobian = -1;
1810fe3ffe1eSBarry Smith     ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr);
1811fe3ffe1eSBarry Smith   } else if (snes->lagjacobian == -1) {
1812e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
1813e35cf81dSBarry Smith     ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr);
1814ebd3b9afSBarry Smith     ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
1815ebd3b9afSBarry Smith     if (flag) {
1816ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1817ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1818ebd3b9afSBarry Smith     }
1819e35cf81dSBarry Smith     PetscFunctionReturn(0);
1820e35cf81dSBarry Smith   } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) {
1821e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
1822e35cf81dSBarry Smith     ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr);
1823ebd3b9afSBarry Smith     ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
1824ebd3b9afSBarry Smith     if (flag) {
1825ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1826ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1827ebd3b9afSBarry Smith     }
1828e35cf81dSBarry Smith     PetscFunctionReturn(0);
1829e35cf81dSBarry Smith   }
1830e35cf81dSBarry Smith 
1831c4fc05e7SBarry Smith   *flg = DIFFERENT_NONZERO_PATTERN;
1832e35cf81dSBarry Smith   ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
1833d64ed03dSBarry Smith   PetscStackPush("SNES user Jacobian function");
18346cab3a1bSJed Brown   ierr = (*sdm->computejacobian)(snes,X,A,B,flg,sdm->jacobianctx);CHKERRQ(ierr);
1835d64ed03dSBarry Smith   PetscStackPop;
1836d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
1837a8054027SBarry Smith 
18383b4f5425SBarry Smith   if (snes->lagpreconditioner == -2) {
18393b4f5425SBarry Smith     ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr);
18403b4f5425SBarry Smith     snes->lagpreconditioner = -1;
18413b4f5425SBarry Smith   } else if (snes->lagpreconditioner == -1) {
1842a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
1843a8054027SBarry Smith     ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr);
1844a8054027SBarry Smith   } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) {
1845a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
1846a8054027SBarry Smith     ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr);
1847a8054027SBarry Smith   }
1848a8054027SBarry Smith 
18496d84be18SBarry Smith   /* make sure user returned a correct Jacobian and preconditioner */
18500700a824SBarry Smith   /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3);
18510700a824SBarry Smith     PetscValidHeaderSpecific(*B,MAT_CLASSID,4);   */
1852693365a8SJed Brown   {
1853693365a8SJed Brown     PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE;
1854693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr);
1855693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr);
1856693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr);
1857693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr);
1858693365a8SJed Brown     if (flag || flag_draw || flag_contour) {
1859693365a8SJed Brown       Mat Bexp_mine = PETSC_NULL,Bexp,FDexp;
1860693365a8SJed Brown       MatStructure mstruct;
1861693365a8SJed Brown       PetscViewer vdraw,vstdout;
18626b3a5b13SJed Brown       PetscBool flg;
1863693365a8SJed Brown       if (flag_operator) {
1864693365a8SJed Brown         ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr);
1865693365a8SJed Brown         Bexp = Bexp_mine;
1866693365a8SJed Brown       } else {
1867693365a8SJed Brown         /* See if the preconditioning matrix can be viewed and added directly */
1868693365a8SJed Brown         ierr = PetscTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr);
1869693365a8SJed Brown         if (flg) Bexp = *B;
1870693365a8SJed Brown         else {
1871693365a8SJed Brown           /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */
1872693365a8SJed Brown           ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr);
1873693365a8SJed Brown           Bexp = Bexp_mine;
1874693365a8SJed Brown         }
1875693365a8SJed Brown       }
1876693365a8SJed Brown       ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr);
1877693365a8SJed Brown       ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr);
1878693365a8SJed Brown       ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr);
1879693365a8SJed Brown       if (flag_draw || flag_contour) {
1880693365a8SJed Brown         ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
1881693365a8SJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
1882693365a8SJed Brown       } else vdraw = PETSC_NULL;
1883693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr);
1884693365a8SJed Brown       if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);}
1885693365a8SJed Brown       if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);}
1886693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr);
1887693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
1888693365a8SJed Brown       if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);}
1889693365a8SJed Brown       ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
1890693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr);
1891693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
1892693365a8SJed Brown       if (vdraw) {              /* Always use contour for the difference */
1893693365a8SJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
1894693365a8SJed Brown         ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);
1895693365a8SJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
1896693365a8SJed Brown       }
1897693365a8SJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
1898693365a8SJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
1899693365a8SJed Brown       ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr);
1900693365a8SJed Brown       ierr = MatDestroy(&FDexp);CHKERRQ(ierr);
1901693365a8SJed Brown     }
1902693365a8SJed Brown   }
19034c30e9fbSJed Brown   {
19046719d8e4SJed Brown     PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE;
19056719d8e4SJed Brown     PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON;
19064c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr);
19076719d8e4SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr);
19084c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr);
19094c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr);
19106719d8e4SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr);
19116719d8e4SJed Brown     ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr);
19126719d8e4SJed Brown     ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr);
19136719d8e4SJed Brown     if (flag || flag_display || flag_draw || flag_contour || flag_threshold) {
19144c30e9fbSJed Brown       Mat Bfd;
19154c30e9fbSJed Brown       MatStructure mstruct;
19164c30e9fbSJed Brown       PetscViewer vdraw,vstdout;
19174c30e9fbSJed Brown       ISColoring iscoloring;
19184c30e9fbSJed Brown       MatFDColoring matfdcoloring;
19194c30e9fbSJed Brown       PetscErrorCode (*func)(SNES,Vec,Vec,void*);
19204c30e9fbSJed Brown       void *funcctx;
19216719d8e4SJed Brown       PetscReal norm1,norm2,normmax;
19224c30e9fbSJed Brown 
19234c30e9fbSJed Brown       ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr);
19244c30e9fbSJed Brown       ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr);
19254c30e9fbSJed Brown       ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr);
19264c30e9fbSJed Brown       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
19274c30e9fbSJed Brown 
19284c30e9fbSJed Brown       /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */
19294c30e9fbSJed Brown       ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr);
19304c30e9fbSJed Brown       ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr);
19314c30e9fbSJed Brown       ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr);
19324c30e9fbSJed Brown       ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr);
19334c30e9fbSJed Brown       ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr);
19344c30e9fbSJed Brown       ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr);
19354c30e9fbSJed Brown       ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr);
19364c30e9fbSJed Brown 
19374c30e9fbSJed Brown       ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr);
19384c30e9fbSJed Brown       if (flag_draw || flag_contour) {
19394c30e9fbSJed Brown         ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
19404c30e9fbSJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
19414c30e9fbSJed Brown       } else vdraw = PETSC_NULL;
19424c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr);
19436719d8e4SJed Brown       if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);}
19444c30e9fbSJed Brown       if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);}
19454c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr);
19466719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
19474c30e9fbSJed Brown       if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);}
19484c30e9fbSJed Brown       ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
19494c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr);
19506719d8e4SJed Brown       ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr);
19514c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr);
19526719d8e4SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr);
19536719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
19544c30e9fbSJed Brown       if (vdraw) {              /* Always use contour for the difference */
19554c30e9fbSJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
19564c30e9fbSJed Brown         ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);
19574c30e9fbSJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
19584c30e9fbSJed Brown       }
19594c30e9fbSJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
19606719d8e4SJed Brown 
19616719d8e4SJed Brown       if (flag_threshold) {
19626719d8e4SJed Brown         PetscInt bs,rstart,rend,i;
19636719d8e4SJed Brown         ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr);
19646719d8e4SJed Brown         ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr);
19656719d8e4SJed Brown         for (i=rstart; i<rend; i++) {
19666719d8e4SJed Brown           const PetscScalar *ba,*ca;
19676719d8e4SJed Brown           const PetscInt *bj,*cj;
19686719d8e4SJed Brown           PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1;
19696719d8e4SJed Brown           PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0;
19706719d8e4SJed Brown           ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr);
19716719d8e4SJed Brown           ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
19726719d8e4SJed Brown           if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold");
19736719d8e4SJed Brown           for (j=0; j<bn; j++) {
19746719d8e4SJed Brown             PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
19756719d8e4SJed Brown             if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) {
19766719d8e4SJed Brown               maxentrycol = bj[j];
19776719d8e4SJed Brown               maxentry = PetscRealPart(ba[j]);
19786719d8e4SJed Brown             }
19796719d8e4SJed Brown             if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) {
19806719d8e4SJed Brown               maxdiffcol = bj[j];
19816719d8e4SJed Brown               maxdiff = PetscRealPart(ca[j]);
19826719d8e4SJed Brown             }
19836719d8e4SJed Brown             if (rdiff > maxrdiff) {
19846719d8e4SJed Brown               maxrdiffcol = bj[j];
19856719d8e4SJed Brown               maxrdiff = rdiff;
19866719d8e4SJed Brown             }
19876719d8e4SJed Brown           }
19886719d8e4SJed Brown           if (maxrdiff > 1) {
19896719d8e4SJed 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);
19906719d8e4SJed Brown             for (j=0; j<bn; j++) {
19916719d8e4SJed Brown               PetscReal rdiff;
19926719d8e4SJed Brown               rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
19936719d8e4SJed Brown               if (rdiff > 1) {
19946719d8e4SJed Brown                 ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr);
19956719d8e4SJed Brown               }
19966719d8e4SJed Brown             }
19976719d8e4SJed Brown             ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr);
19986719d8e4SJed Brown           }
19996719d8e4SJed Brown           ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr);
20006719d8e4SJed Brown           ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
20016719d8e4SJed Brown         }
20026719d8e4SJed Brown       }
20034c30e9fbSJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
20044c30e9fbSJed Brown       ierr = MatDestroy(&Bfd);CHKERRQ(ierr);
20054c30e9fbSJed Brown     }
20064c30e9fbSJed Brown   }
20073a40ed3dSBarry Smith   PetscFunctionReturn(0);
20089b94acceSBarry Smith }
20099b94acceSBarry Smith 
20104a2ae208SSatish Balay #undef __FUNCT__
20114a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian"
20129b94acceSBarry Smith /*@C
20139b94acceSBarry Smith    SNESSetJacobian - Sets the function to compute Jacobian as well as the
2014044dda88SLois Curfman McInnes    location to store the matrix.
20159b94acceSBarry Smith 
20163f9fe445SBarry Smith    Logically Collective on SNES and Mat
2017c7afd0dbSLois Curfman McInnes 
20189b94acceSBarry Smith    Input Parameters:
2019c7afd0dbSLois Curfman McInnes +  snes - the SNES context
20209b94acceSBarry Smith .  A - Jacobian matrix
20219b94acceSBarry Smith .  B - preconditioner matrix (usually same as the Jacobian)
2022efd51863SBarry Smith .  func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value)
2023c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
2024efd51863SBarry Smith          Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value)
20259b94acceSBarry Smith 
20269b94acceSBarry Smith    Calling sequence of func:
20278d76a1e5SLois Curfman McInnes $     func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx);
20289b94acceSBarry Smith 
2029c7afd0dbSLois Curfman McInnes +  x - input vector
20309b94acceSBarry Smith .  A - Jacobian matrix
20319b94acceSBarry Smith .  B - preconditioner matrix, usually the same as A
2032ac21db08SLois Curfman McInnes .  flag - flag indicating information about the preconditioner matrix
20332b668275SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
2034c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined Jacobian context
20359b94acceSBarry Smith 
20369b94acceSBarry Smith    Notes:
203794b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the flag
20382cd2dfdcSLois Curfman McInnes    output parameter in the routine func().  Be sure to read this information!
2039ac21db08SLois Curfman McInnes 
2040ac21db08SLois Curfman McInnes    The routine func() takes Mat * as the matrix arguments rather than Mat.
20419b94acceSBarry Smith    This allows the Jacobian evaluation routine to replace A and/or B with a
20429b94acceSBarry Smith    completely new new matrix structure (not just different matrix elements)
20439b94acceSBarry Smith    when appropriate, for instance, if the nonzero structure is changing
20449b94acceSBarry Smith    throughout the global iterations.
20459b94acceSBarry Smith 
204616913363SBarry Smith    If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on
204716913363SBarry Smith    each matrix.
204816913363SBarry Smith 
2049a8a26c1eSJed Brown    If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument
2050a8a26c1eSJed Brown    must be a MatFDColoring.
2051a8a26c1eSJed Brown 
2052c3cc8fd1SJed Brown    Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian.  One common
2053c3cc8fd1SJed Brown    example is to use the "Picard linearization" which only differentiates through the highest order parts of each term.
2054c3cc8fd1SJed Brown 
205536851e7fSLois Curfman McInnes    Level: beginner
205636851e7fSLois Curfman McInnes 
20579b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix
20589b94acceSBarry Smith 
20593ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure
20609b94acceSBarry Smith @*/
20617087cfbeSBarry Smith PetscErrorCode  SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
20629b94acceSBarry Smith {
2063dfbe8321SBarry Smith   PetscErrorCode ierr;
20646cab3a1bSJed Brown   DM             dm;
20653a7fca6bSBarry Smith 
20663a40ed3dSBarry Smith   PetscFunctionBegin;
20670700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
20680700a824SBarry Smith   if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2);
20690700a824SBarry Smith   if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3);
2070c9780b6fSBarry Smith   if (A) PetscCheckSameComm(snes,1,A,2);
207106975374SJed Brown   if (B) PetscCheckSameComm(snes,1,B,3);
20726cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
20736cab3a1bSJed Brown   ierr = DMSNESSetJacobian(dm,func,ctx);CHKERRQ(ierr);
20743a7fca6bSBarry Smith   if (A) {
20757dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
20766bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
20779b94acceSBarry Smith     snes->jacobian = A;
20783a7fca6bSBarry Smith   }
20793a7fca6bSBarry Smith   if (B) {
20807dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr);
20816bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
20829b94acceSBarry Smith     snes->jacobian_pre = B;
20833a7fca6bSBarry Smith   }
20843a40ed3dSBarry Smith   PetscFunctionReturn(0);
20859b94acceSBarry Smith }
208662fef451SLois Curfman McInnes 
20874a2ae208SSatish Balay #undef __FUNCT__
20884a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian"
2089c2aafc4cSSatish Balay /*@C
2090b4fd4287SBarry Smith    SNESGetJacobian - Returns the Jacobian matrix and optionally the user
2091b4fd4287SBarry Smith    provided context for evaluating the Jacobian.
2092b4fd4287SBarry Smith 
2093c7afd0dbSLois Curfman McInnes    Not Collective, but Mat object will be parallel if SNES object is
2094c7afd0dbSLois Curfman McInnes 
2095b4fd4287SBarry Smith    Input Parameter:
2096b4fd4287SBarry Smith .  snes - the nonlinear solver context
2097b4fd4287SBarry Smith 
2098b4fd4287SBarry Smith    Output Parameters:
2099c7afd0dbSLois Curfman McInnes +  A - location to stash Jacobian matrix (or PETSC_NULL)
2100b4fd4287SBarry Smith .  B - location to stash preconditioner matrix (or PETSC_NULL)
210170e92668SMatthew Knepley .  func - location to put Jacobian function (or PETSC_NULL)
210270e92668SMatthew Knepley -  ctx - location to stash Jacobian ctx (or PETSC_NULL)
2103fee21e36SBarry Smith 
210436851e7fSLois Curfman McInnes    Level: advanced
210536851e7fSLois Curfman McInnes 
2106b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian()
2107b4fd4287SBarry Smith @*/
21087087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
2109b4fd4287SBarry Smith {
21106cab3a1bSJed Brown   PetscErrorCode ierr;
21116cab3a1bSJed Brown   DM             dm;
21126cab3a1bSJed Brown   SNESDM         sdm;
21136cab3a1bSJed Brown 
21143a40ed3dSBarry Smith   PetscFunctionBegin;
21150700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2116b4fd4287SBarry Smith   if (A)    *A    = snes->jacobian;
2117b4fd4287SBarry Smith   if (B)    *B    = snes->jacobian_pre;
21186cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
21196cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
21206cab3a1bSJed Brown   if (func) *func = sdm->computejacobian;
21216cab3a1bSJed Brown   if (ctx)  *ctx  = sdm->jacobianctx;
21223a40ed3dSBarry Smith   PetscFunctionReturn(0);
2123b4fd4287SBarry Smith }
2124b4fd4287SBarry Smith 
21259b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */
21269b94acceSBarry Smith 
21274a2ae208SSatish Balay #undef __FUNCT__
21284a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp"
21299b94acceSBarry Smith /*@
21309b94acceSBarry Smith    SNESSetUp - Sets up the internal data structures for the later use
2131272ac6f2SLois Curfman McInnes    of a nonlinear solver.
21329b94acceSBarry Smith 
2133fee21e36SBarry Smith    Collective on SNES
2134fee21e36SBarry Smith 
2135c7afd0dbSLois Curfman McInnes    Input Parameters:
213670e92668SMatthew Knepley .  snes - the SNES context
2137c7afd0dbSLois Curfman McInnes 
2138272ac6f2SLois Curfman McInnes    Notes:
2139272ac6f2SLois Curfman McInnes    For basic use of the SNES solvers the user need not explicitly call
2140272ac6f2SLois Curfman McInnes    SNESSetUp(), since these actions will automatically occur during
2141272ac6f2SLois Curfman McInnes    the call to SNESSolve().  However, if one wishes to control this
2142272ac6f2SLois Curfman McInnes    phase separately, SNESSetUp() should be called after SNESCreate()
2143272ac6f2SLois Curfman McInnes    and optional routines of the form SNESSetXXX(), but before SNESSolve().
2144272ac6f2SLois Curfman McInnes 
214536851e7fSLois Curfman McInnes    Level: advanced
214636851e7fSLois Curfman McInnes 
21479b94acceSBarry Smith .keywords: SNES, nonlinear, setup
21489b94acceSBarry Smith 
21499b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
21509b94acceSBarry Smith @*/
21517087cfbeSBarry Smith PetscErrorCode  SNESSetUp(SNES snes)
21529b94acceSBarry Smith {
2153dfbe8321SBarry Smith   PetscErrorCode ierr;
21546cab3a1bSJed Brown   DM             dm;
21556cab3a1bSJed Brown   SNESDM         sdm;
21563a40ed3dSBarry Smith 
21573a40ed3dSBarry Smith   PetscFunctionBegin;
21580700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
21594dc4c822SBarry Smith   if (snes->setupcalled) PetscFunctionReturn(0);
21609b94acceSBarry Smith 
21617adad957SLisandro Dalcin   if (!((PetscObject)snes)->type_name) {
216285385478SLisandro Dalcin     ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr);
216385385478SLisandro Dalcin   }
216485385478SLisandro Dalcin 
2165a63bb30eSJed Brown   ierr = SNESGetFunction(snes,&snes->vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
216617186662SBarry Smith   if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
216758c9b817SLisandro Dalcin   if (snes->vec_rhs  == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector");
216858c9b817SLisandro Dalcin 
216958c9b817SLisandro Dalcin   if (!snes->vec_sol_update /* && snes->vec_sol */) {
217058c9b817SLisandro Dalcin     ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr);
217158c9b817SLisandro Dalcin     ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr);
217258c9b817SLisandro Dalcin   }
217358c9b817SLisandro Dalcin 
21746cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
21756cab3a1bSJed Brown   ierr = DMSNESSetUpLegacy(dm);CHKERRQ(ierr); /* To be removed when function routines are taken out of the DM package */
21766cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
21776cab3a1bSJed Brown   if (!sdm->computefunction) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction(), DMSNESSetFunction(), DMDASNESSetFunctionLocal(), etc");
21786cab3a1bSJed Brown   if (!snes->vec_func) {
21796cab3a1bSJed Brown     ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr);
2180214df951SJed Brown   }
2181efd51863SBarry Smith 
2182b710008aSBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);}
2183b710008aSBarry Smith 
2184d25893d9SBarry Smith   if (snes->ops->usercompute && !snes->user) {
2185d25893d9SBarry Smith     ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr);
2186d25893d9SBarry Smith   }
2187d25893d9SBarry Smith 
2188410397dcSLisandro Dalcin   if (snes->ops->setup) {
2189410397dcSLisandro Dalcin     ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr);
2190410397dcSLisandro Dalcin   }
219158c9b817SLisandro Dalcin 
21927aaed0d8SBarry Smith   snes->setupcalled = PETSC_TRUE;
21933a40ed3dSBarry Smith   PetscFunctionReturn(0);
21949b94acceSBarry Smith }
21959b94acceSBarry Smith 
21964a2ae208SSatish Balay #undef __FUNCT__
219737596af1SLisandro Dalcin #define __FUNCT__ "SNESReset"
219837596af1SLisandro Dalcin /*@
219937596af1SLisandro Dalcin    SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats
220037596af1SLisandro Dalcin 
220137596af1SLisandro Dalcin    Collective on SNES
220237596af1SLisandro Dalcin 
220337596af1SLisandro Dalcin    Input Parameter:
220437596af1SLisandro Dalcin .  snes - iterative context obtained from SNESCreate()
220537596af1SLisandro Dalcin 
2206d25893d9SBarry Smith    Level: intermediate
2207d25893d9SBarry Smith 
2208d25893d9SBarry Smith    Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext()
220937596af1SLisandro Dalcin 
221037596af1SLisandro Dalcin .keywords: SNES, destroy
221137596af1SLisandro Dalcin 
221237596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve()
221337596af1SLisandro Dalcin @*/
221437596af1SLisandro Dalcin PetscErrorCode  SNESReset(SNES snes)
221537596af1SLisandro Dalcin {
221637596af1SLisandro Dalcin   PetscErrorCode ierr;
221737596af1SLisandro Dalcin 
221837596af1SLisandro Dalcin   PetscFunctionBegin;
221937596af1SLisandro Dalcin   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2220d25893d9SBarry Smith   if (snes->ops->userdestroy && snes->user) {
2221d25893d9SBarry Smith     ierr       = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr);
2222d25893d9SBarry Smith     snes->user = PETSC_NULL;
2223d25893d9SBarry Smith   }
22248a23116dSBarry Smith   if (snes->pc) {
22258a23116dSBarry Smith     ierr = SNESReset(snes->pc);CHKERRQ(ierr);
22268a23116dSBarry Smith   }
22278a23116dSBarry Smith 
222837596af1SLisandro Dalcin   if (snes->ops->reset) {
222937596af1SLisandro Dalcin     ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr);
223037596af1SLisandro Dalcin   }
223137596af1SLisandro Dalcin   if (snes->ksp) {ierr = KSPReset(snes->ksp);CHKERRQ(ierr);}
22326bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
22336bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
22346bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr);
22356bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
22366bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
22376bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
2238c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);
2239c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);
224037596af1SLisandro Dalcin   snes->nwork = snes->nvwork = 0;
224137596af1SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
224237596af1SLisandro Dalcin   PetscFunctionReturn(0);
224337596af1SLisandro Dalcin }
224437596af1SLisandro Dalcin 
224537596af1SLisandro Dalcin #undef __FUNCT__
22464a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy"
224752baeb72SSatish Balay /*@
22489b94acceSBarry Smith    SNESDestroy - Destroys the nonlinear solver context that was created
22499b94acceSBarry Smith    with SNESCreate().
22509b94acceSBarry Smith 
2251c7afd0dbSLois Curfman McInnes    Collective on SNES
2252c7afd0dbSLois Curfman McInnes 
22539b94acceSBarry Smith    Input Parameter:
22549b94acceSBarry Smith .  snes - the SNES context
22559b94acceSBarry Smith 
225636851e7fSLois Curfman McInnes    Level: beginner
225736851e7fSLois Curfman McInnes 
22589b94acceSBarry Smith .keywords: SNES, nonlinear, destroy
22599b94acceSBarry Smith 
226063a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve()
22619b94acceSBarry Smith @*/
22626bf464f9SBarry Smith PetscErrorCode  SNESDestroy(SNES *snes)
22639b94acceSBarry Smith {
22646849ba73SBarry Smith   PetscErrorCode ierr;
22653a40ed3dSBarry Smith 
22663a40ed3dSBarry Smith   PetscFunctionBegin;
22676bf464f9SBarry Smith   if (!*snes) PetscFunctionReturn(0);
22686bf464f9SBarry Smith   PetscValidHeaderSpecific((*snes),SNES_CLASSID,1);
22696bf464f9SBarry Smith   if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);}
2270d4bb536fSBarry Smith 
22716bf464f9SBarry Smith   ierr = SNESReset((*snes));CHKERRQ(ierr);
22728a23116dSBarry Smith   ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr);
22736b8b9a38SLisandro Dalcin 
2274be0abb6dSBarry Smith   /* if memory was published with AMS then destroy it */
22756bf464f9SBarry Smith   ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr);
22766bf464f9SBarry Smith   if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);}
22776d4c513bSLisandro Dalcin 
22786bf464f9SBarry Smith   ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr);
22796bf464f9SBarry Smith   ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr);
22806b8b9a38SLisandro Dalcin 
22816bf464f9SBarry Smith   ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr);
22826bf464f9SBarry Smith   if ((*snes)->ops->convergeddestroy) {
22836bf464f9SBarry Smith     ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr);
22846b8b9a38SLisandro Dalcin   }
22856bf464f9SBarry Smith   if ((*snes)->conv_malloc) {
22866bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr);
22876bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr);
228858c9b817SLisandro Dalcin   }
2289ea630c6eSPeter Brune   ierr = PetscViewerDestroy(&(*snes)->ls_monitor);CHKERRQ(ierr);
22906bf464f9SBarry Smith   ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr);
2291a79aaaedSSatish Balay   ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr);
22923a40ed3dSBarry Smith  PetscFunctionReturn(0);
22939b94acceSBarry Smith }
22949b94acceSBarry Smith 
22959b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */
22969b94acceSBarry Smith 
22974a2ae208SSatish Balay #undef __FUNCT__
2298a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner"
2299a8054027SBarry Smith /*@
2300a8054027SBarry Smith    SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.
2301a8054027SBarry Smith 
23023f9fe445SBarry Smith    Logically Collective on SNES
2303a8054027SBarry Smith 
2304a8054027SBarry Smith    Input Parameters:
2305a8054027SBarry Smith +  snes - the SNES context
2306a8054027SBarry 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
23073b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2308a8054027SBarry Smith 
2309a8054027SBarry Smith    Options Database Keys:
2310a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2311a8054027SBarry Smith 
2312a8054027SBarry Smith    Notes:
2313a8054027SBarry Smith    The default is 1
2314a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2315a8054027SBarry Smith    If  -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use
2316a8054027SBarry Smith 
2317a8054027SBarry Smith    Level: intermediate
2318a8054027SBarry Smith 
2319a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2320a8054027SBarry Smith 
2321e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2322a8054027SBarry Smith 
2323a8054027SBarry Smith @*/
23247087cfbeSBarry Smith PetscErrorCode  SNESSetLagPreconditioner(SNES snes,PetscInt lag)
2325a8054027SBarry Smith {
2326a8054027SBarry Smith   PetscFunctionBegin;
23270700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2328e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2329e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2330c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2331a8054027SBarry Smith   snes->lagpreconditioner = lag;
2332a8054027SBarry Smith   PetscFunctionReturn(0);
2333a8054027SBarry Smith }
2334a8054027SBarry Smith 
2335a8054027SBarry Smith #undef __FUNCT__
2336efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence"
2337efd51863SBarry Smith /*@
2338efd51863SBarry Smith    SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does
2339efd51863SBarry Smith 
2340efd51863SBarry Smith    Logically Collective on SNES
2341efd51863SBarry Smith 
2342efd51863SBarry Smith    Input Parameters:
2343efd51863SBarry Smith +  snes - the SNES context
2344efd51863SBarry Smith -  steps - the number of refinements to do, defaults to 0
2345efd51863SBarry Smith 
2346efd51863SBarry Smith    Options Database Keys:
2347efd51863SBarry Smith .    -snes_grid_sequence <steps>
2348efd51863SBarry Smith 
2349efd51863SBarry Smith    Level: intermediate
2350efd51863SBarry Smith 
2351c0df2a02SJed Brown    Notes:
2352c0df2a02SJed Brown    Use SNESGetSolution() to extract the fine grid solution after grid sequencing.
2353c0df2a02SJed Brown 
2354efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2355efd51863SBarry Smith 
2356efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2357efd51863SBarry Smith 
2358efd51863SBarry Smith @*/
2359efd51863SBarry Smith PetscErrorCode  SNESSetGridSequence(SNES snes,PetscInt steps)
2360efd51863SBarry Smith {
2361efd51863SBarry Smith   PetscFunctionBegin;
2362efd51863SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2363efd51863SBarry Smith   PetscValidLogicalCollectiveInt(snes,steps,2);
2364efd51863SBarry Smith   snes->gridsequence = steps;
2365efd51863SBarry Smith   PetscFunctionReturn(0);
2366efd51863SBarry Smith }
2367efd51863SBarry Smith 
2368efd51863SBarry Smith #undef __FUNCT__
2369a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner"
2370a8054027SBarry Smith /*@
2371a8054027SBarry Smith    SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt
2372a8054027SBarry Smith 
23733f9fe445SBarry Smith    Not Collective
2374a8054027SBarry Smith 
2375a8054027SBarry Smith    Input Parameter:
2376a8054027SBarry Smith .  snes - the SNES context
2377a8054027SBarry Smith 
2378a8054027SBarry Smith    Output Parameter:
2379a8054027SBarry 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
23803b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2381a8054027SBarry Smith 
2382a8054027SBarry Smith    Options Database Keys:
2383a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2384a8054027SBarry Smith 
2385a8054027SBarry Smith    Notes:
2386a8054027SBarry Smith    The default is 1
2387a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2388a8054027SBarry Smith 
2389a8054027SBarry Smith    Level: intermediate
2390a8054027SBarry Smith 
2391a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2392a8054027SBarry Smith 
2393a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner()
2394a8054027SBarry Smith 
2395a8054027SBarry Smith @*/
23967087cfbeSBarry Smith PetscErrorCode  SNESGetLagPreconditioner(SNES snes,PetscInt *lag)
2397a8054027SBarry Smith {
2398a8054027SBarry Smith   PetscFunctionBegin;
23990700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2400a8054027SBarry Smith   *lag = snes->lagpreconditioner;
2401a8054027SBarry Smith   PetscFunctionReturn(0);
2402a8054027SBarry Smith }
2403a8054027SBarry Smith 
2404a8054027SBarry Smith #undef __FUNCT__
2405e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian"
2406e35cf81dSBarry Smith /*@
2407e35cf81dSBarry Smith    SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how
2408e35cf81dSBarry Smith      often the preconditioner is rebuilt.
2409e35cf81dSBarry Smith 
24103f9fe445SBarry Smith    Logically Collective on SNES
2411e35cf81dSBarry Smith 
2412e35cf81dSBarry Smith    Input Parameters:
2413e35cf81dSBarry Smith +  snes - the SNES context
2414e35cf81dSBarry 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
2415fe3ffe1eSBarry Smith          the Jacobian is built etc. -2 means rebuild at next chance but then never again
2416e35cf81dSBarry Smith 
2417e35cf81dSBarry Smith    Options Database Keys:
2418e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2419e35cf81dSBarry Smith 
2420e35cf81dSBarry Smith    Notes:
2421e35cf81dSBarry Smith    The default is 1
2422e35cf81dSBarry Smith    The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2423fe3ffe1eSBarry 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
2424fe3ffe1eSBarry Smith    at the next Newton step but never again (unless it is reset to another value)
2425e35cf81dSBarry Smith 
2426e35cf81dSBarry Smith    Level: intermediate
2427e35cf81dSBarry Smith 
2428e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2429e35cf81dSBarry Smith 
2430e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian()
2431e35cf81dSBarry Smith 
2432e35cf81dSBarry Smith @*/
24337087cfbeSBarry Smith PetscErrorCode  SNESSetLagJacobian(SNES snes,PetscInt lag)
2434e35cf81dSBarry Smith {
2435e35cf81dSBarry Smith   PetscFunctionBegin;
24360700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2437e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2438e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2439c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2440e35cf81dSBarry Smith   snes->lagjacobian = lag;
2441e35cf81dSBarry Smith   PetscFunctionReturn(0);
2442e35cf81dSBarry Smith }
2443e35cf81dSBarry Smith 
2444e35cf81dSBarry Smith #undef __FUNCT__
2445e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian"
2446e35cf81dSBarry Smith /*@
2447e35cf81dSBarry Smith    SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt
2448e35cf81dSBarry Smith 
24493f9fe445SBarry Smith    Not Collective
2450e35cf81dSBarry Smith 
2451e35cf81dSBarry Smith    Input Parameter:
2452e35cf81dSBarry Smith .  snes - the SNES context
2453e35cf81dSBarry Smith 
2454e35cf81dSBarry Smith    Output Parameter:
2455e35cf81dSBarry 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
2456e35cf81dSBarry Smith          the Jacobian is built etc.
2457e35cf81dSBarry Smith 
2458e35cf81dSBarry Smith    Options Database Keys:
2459e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2460e35cf81dSBarry Smith 
2461e35cf81dSBarry Smith    Notes:
2462e35cf81dSBarry Smith    The default is 1
2463e35cf81dSBarry Smith    The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2464e35cf81dSBarry Smith 
2465e35cf81dSBarry Smith    Level: intermediate
2466e35cf81dSBarry Smith 
2467e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2468e35cf81dSBarry Smith 
2469e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner()
2470e35cf81dSBarry Smith 
2471e35cf81dSBarry Smith @*/
24727087cfbeSBarry Smith PetscErrorCode  SNESGetLagJacobian(SNES snes,PetscInt *lag)
2473e35cf81dSBarry Smith {
2474e35cf81dSBarry Smith   PetscFunctionBegin;
24750700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2476e35cf81dSBarry Smith   *lag = snes->lagjacobian;
2477e35cf81dSBarry Smith   PetscFunctionReturn(0);
2478e35cf81dSBarry Smith }
2479e35cf81dSBarry Smith 
2480e35cf81dSBarry Smith #undef __FUNCT__
24814a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances"
24829b94acceSBarry Smith /*@
2483d7a720efSLois Curfman McInnes    SNESSetTolerances - Sets various parameters used in convergence tests.
24849b94acceSBarry Smith 
24853f9fe445SBarry Smith    Logically Collective on SNES
2486c7afd0dbSLois Curfman McInnes 
24879b94acceSBarry Smith    Input Parameters:
2488c7afd0dbSLois Curfman McInnes +  snes - the SNES context
248970441072SBarry Smith .  abstol - absolute convergence tolerance
249033174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
249133174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
249233174efeSLois Curfman McInnes            of the change in the solution between steps
249333174efeSLois Curfman McInnes .  maxit - maximum number of iterations
2494c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
2495fee21e36SBarry Smith 
249633174efeSLois Curfman McInnes    Options Database Keys:
249770441072SBarry Smith +    -snes_atol <abstol> - Sets abstol
2498c7afd0dbSLois Curfman McInnes .    -snes_rtol <rtol> - Sets rtol
2499c7afd0dbSLois Curfman McInnes .    -snes_stol <stol> - Sets stol
2500c7afd0dbSLois Curfman McInnes .    -snes_max_it <maxit> - Sets maxit
2501c7afd0dbSLois Curfman McInnes -    -snes_max_funcs <maxf> - Sets maxf
25029b94acceSBarry Smith 
2503d7a720efSLois Curfman McInnes    Notes:
25049b94acceSBarry Smith    The default maximum number of iterations is 50.
25059b94acceSBarry Smith    The default maximum number of function evaluations is 1000.
25069b94acceSBarry Smith 
250736851e7fSLois Curfman McInnes    Level: intermediate
250836851e7fSLois Curfman McInnes 
250933174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances
25109b94acceSBarry Smith 
25112492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance()
25129b94acceSBarry Smith @*/
25137087cfbeSBarry Smith PetscErrorCode  SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
25149b94acceSBarry Smith {
25153a40ed3dSBarry Smith   PetscFunctionBegin;
25160700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2517c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,abstol,2);
2518c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol,3);
2519c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,stol,4);
2520c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxit,5);
2521c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxf,6);
2522c5eb9154SBarry Smith 
2523ab54825eSJed Brown   if (abstol != PETSC_DEFAULT) {
2524ab54825eSJed Brown     if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol);
2525ab54825eSJed Brown     snes->abstol = abstol;
2526ab54825eSJed Brown   }
2527ab54825eSJed Brown   if (rtol != PETSC_DEFAULT) {
2528ab54825eSJed 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);
2529ab54825eSJed Brown     snes->rtol = rtol;
2530ab54825eSJed Brown   }
2531ab54825eSJed Brown   if (stol != PETSC_DEFAULT) {
2532ab54825eSJed Brown     if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol);
2533ab54825eSJed Brown     snes->xtol = stol;
2534ab54825eSJed Brown   }
2535ab54825eSJed Brown   if (maxit != PETSC_DEFAULT) {
2536ab54825eSJed Brown     if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit);
2537ab54825eSJed Brown     snes->max_its = maxit;
2538ab54825eSJed Brown   }
2539ab54825eSJed Brown   if (maxf != PETSC_DEFAULT) {
2540ab54825eSJed Brown     if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf);
2541ab54825eSJed Brown     snes->max_funcs = maxf;
2542ab54825eSJed Brown   }
25433a40ed3dSBarry Smith   PetscFunctionReturn(0);
25449b94acceSBarry Smith }
25459b94acceSBarry Smith 
25464a2ae208SSatish Balay #undef __FUNCT__
25474a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances"
25489b94acceSBarry Smith /*@
254933174efeSLois Curfman McInnes    SNESGetTolerances - Gets various parameters used in convergence tests.
255033174efeSLois Curfman McInnes 
2551c7afd0dbSLois Curfman McInnes    Not Collective
2552c7afd0dbSLois Curfman McInnes 
255333174efeSLois Curfman McInnes    Input Parameters:
2554c7afd0dbSLois Curfman McInnes +  snes - the SNES context
255585385478SLisandro Dalcin .  atol - absolute convergence tolerance
255633174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
255733174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
255833174efeSLois Curfman McInnes            of the change in the solution between steps
255933174efeSLois Curfman McInnes .  maxit - maximum number of iterations
2560c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
2561fee21e36SBarry Smith 
256233174efeSLois Curfman McInnes    Notes:
256333174efeSLois Curfman McInnes    The user can specify PETSC_NULL for any parameter that is not needed.
256433174efeSLois Curfman McInnes 
256536851e7fSLois Curfman McInnes    Level: intermediate
256636851e7fSLois Curfman McInnes 
256733174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances
256833174efeSLois Curfman McInnes 
256933174efeSLois Curfman McInnes .seealso: SNESSetTolerances()
257033174efeSLois Curfman McInnes @*/
25717087cfbeSBarry Smith PetscErrorCode  SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
257233174efeSLois Curfman McInnes {
25733a40ed3dSBarry Smith   PetscFunctionBegin;
25740700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
257585385478SLisandro Dalcin   if (atol)  *atol  = snes->abstol;
257633174efeSLois Curfman McInnes   if (rtol)  *rtol  = snes->rtol;
257733174efeSLois Curfman McInnes   if (stol)  *stol  = snes->xtol;
257833174efeSLois Curfman McInnes   if (maxit) *maxit = snes->max_its;
257933174efeSLois Curfman McInnes   if (maxf)  *maxf  = snes->max_funcs;
25803a40ed3dSBarry Smith   PetscFunctionReturn(0);
258133174efeSLois Curfman McInnes }
258233174efeSLois Curfman McInnes 
25834a2ae208SSatish Balay #undef __FUNCT__
25844a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance"
258533174efeSLois Curfman McInnes /*@
25869b94acceSBarry Smith    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
25879b94acceSBarry Smith 
25883f9fe445SBarry Smith    Logically Collective on SNES
2589fee21e36SBarry Smith 
2590c7afd0dbSLois Curfman McInnes    Input Parameters:
2591c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2592c7afd0dbSLois Curfman McInnes -  tol - tolerance
2593c7afd0dbSLois Curfman McInnes 
25949b94acceSBarry Smith    Options Database Key:
2595c7afd0dbSLois Curfman McInnes .  -snes_trtol <tol> - Sets tol
25969b94acceSBarry Smith 
259736851e7fSLois Curfman McInnes    Level: intermediate
259836851e7fSLois Curfman McInnes 
25999b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance
26009b94acceSBarry Smith 
26012492ecdbSBarry Smith .seealso: SNESSetTolerances()
26029b94acceSBarry Smith @*/
26037087cfbeSBarry Smith PetscErrorCode  SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
26049b94acceSBarry Smith {
26053a40ed3dSBarry Smith   PetscFunctionBegin;
26060700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2607c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,tol,2);
26089b94acceSBarry Smith   snes->deltatol = tol;
26093a40ed3dSBarry Smith   PetscFunctionReturn(0);
26109b94acceSBarry Smith }
26119b94acceSBarry Smith 
2612df9fa365SBarry Smith /*
2613df9fa365SBarry Smith    Duplicate the lg monitors for SNES from KSP; for some reason with
2614df9fa365SBarry Smith    dynamic libraries things don't work under Sun4 if we just use
2615df9fa365SBarry Smith    macros instead of functions
2616df9fa365SBarry Smith */
26174a2ae208SSatish Balay #undef __FUNCT__
2618a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG"
26197087cfbeSBarry Smith PetscErrorCode  SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx)
2620ce1608b8SBarry Smith {
2621dfbe8321SBarry Smith   PetscErrorCode ierr;
2622ce1608b8SBarry Smith 
2623ce1608b8SBarry Smith   PetscFunctionBegin;
26240700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2625a6570f20SBarry Smith   ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr);
2626ce1608b8SBarry Smith   PetscFunctionReturn(0);
2627ce1608b8SBarry Smith }
2628ce1608b8SBarry Smith 
26294a2ae208SSatish Balay #undef __FUNCT__
2630a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate"
26317087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2632df9fa365SBarry Smith {
2633dfbe8321SBarry Smith   PetscErrorCode ierr;
2634df9fa365SBarry Smith 
2635df9fa365SBarry Smith   PetscFunctionBegin;
2636a6570f20SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2637df9fa365SBarry Smith   PetscFunctionReturn(0);
2638df9fa365SBarry Smith }
2639df9fa365SBarry Smith 
26404a2ae208SSatish Balay #undef __FUNCT__
2641a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy"
26426bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGDestroy(PetscDrawLG *draw)
2643df9fa365SBarry Smith {
2644dfbe8321SBarry Smith   PetscErrorCode ierr;
2645df9fa365SBarry Smith 
2646df9fa365SBarry Smith   PetscFunctionBegin;
2647a6570f20SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2648df9fa365SBarry Smith   PetscFunctionReturn(0);
2649df9fa365SBarry Smith }
2650df9fa365SBarry Smith 
26517087cfbeSBarry Smith extern PetscErrorCode  SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
2652b271bb04SBarry Smith #undef __FUNCT__
2653b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange"
26547087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx)
2655b271bb04SBarry Smith {
2656b271bb04SBarry Smith   PetscDrawLG      lg;
2657b271bb04SBarry Smith   PetscErrorCode   ierr;
2658b271bb04SBarry Smith   PetscReal        x,y,per;
2659b271bb04SBarry Smith   PetscViewer      v = (PetscViewer)monctx;
2660b271bb04SBarry Smith   static PetscReal prev; /* should be in the context */
2661b271bb04SBarry Smith   PetscDraw        draw;
2662b271bb04SBarry Smith   PetscFunctionBegin;
2663b271bb04SBarry Smith   if (!monctx) {
2664b271bb04SBarry Smith     MPI_Comm    comm;
2665b271bb04SBarry Smith 
2666b271bb04SBarry Smith     ierr   = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
2667b271bb04SBarry Smith     v      = PETSC_VIEWER_DRAW_(comm);
2668b271bb04SBarry Smith   }
2669b271bb04SBarry Smith   ierr   = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr);
2670b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2671b271bb04SBarry Smith   ierr   = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2672b271bb04SBarry Smith   ierr   = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr);
2673b271bb04SBarry Smith   x = (PetscReal) n;
2674b271bb04SBarry Smith   if (rnorm > 0.0) y = log10(rnorm); else y = -15.0;
2675b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2676b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2677b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2678b271bb04SBarry Smith   }
2679b271bb04SBarry Smith 
2680b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr);
2681b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2682b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2683b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr);
2684b271bb04SBarry Smith   ierr =  SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr);
2685b271bb04SBarry Smith   x = (PetscReal) n;
2686b271bb04SBarry Smith   y = 100.0*per;
2687b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2688b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2689b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2690b271bb04SBarry Smith   }
2691b271bb04SBarry Smith 
2692b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr);
2693b271bb04SBarry Smith   if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2694b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2695b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr);
2696b271bb04SBarry Smith   x = (PetscReal) n;
2697b271bb04SBarry Smith   y = (prev - rnorm)/prev;
2698b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2699b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2700b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2701b271bb04SBarry Smith   }
2702b271bb04SBarry Smith 
2703b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr);
2704b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2705b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2706b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr);
2707b271bb04SBarry Smith   x = (PetscReal) n;
2708b271bb04SBarry Smith   y = (prev - rnorm)/(prev*per);
2709b271bb04SBarry Smith   if (n > 2) { /*skip initial crazy value */
2710b271bb04SBarry Smith     ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2711b271bb04SBarry Smith   }
2712b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2713b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2714b271bb04SBarry Smith   }
2715b271bb04SBarry Smith   prev = rnorm;
2716b271bb04SBarry Smith   PetscFunctionReturn(0);
2717b271bb04SBarry Smith }
2718b271bb04SBarry Smith 
2719b271bb04SBarry Smith #undef __FUNCT__
2720b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate"
27217087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2722b271bb04SBarry Smith {
2723b271bb04SBarry Smith   PetscErrorCode ierr;
2724b271bb04SBarry Smith 
2725b271bb04SBarry Smith   PetscFunctionBegin;
2726b271bb04SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2727b271bb04SBarry Smith   PetscFunctionReturn(0);
2728b271bb04SBarry Smith }
2729b271bb04SBarry Smith 
2730b271bb04SBarry Smith #undef __FUNCT__
2731b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy"
27326bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGRangeDestroy(PetscDrawLG *draw)
2733b271bb04SBarry Smith {
2734b271bb04SBarry Smith   PetscErrorCode ierr;
2735b271bb04SBarry Smith 
2736b271bb04SBarry Smith   PetscFunctionBegin;
2737b271bb04SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2738b271bb04SBarry Smith   PetscFunctionReturn(0);
2739b271bb04SBarry Smith }
2740b271bb04SBarry Smith 
27417a03ce2fSLisandro Dalcin #undef __FUNCT__
27427a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor"
2743228d79bcSJed Brown /*@
2744228d79bcSJed Brown    SNESMonitor - runs the user provided monitor routines, if they exist
2745228d79bcSJed Brown 
2746228d79bcSJed Brown    Collective on SNES
2747228d79bcSJed Brown 
2748228d79bcSJed Brown    Input Parameters:
2749228d79bcSJed Brown +  snes - nonlinear solver context obtained from SNESCreate()
2750228d79bcSJed Brown .  iter - iteration number
2751228d79bcSJed Brown -  rnorm - relative norm of the residual
2752228d79bcSJed Brown 
2753228d79bcSJed Brown    Notes:
2754228d79bcSJed Brown    This routine is called by the SNES implementations.
2755228d79bcSJed Brown    It does not typically need to be called by the user.
2756228d79bcSJed Brown 
2757228d79bcSJed Brown    Level: developer
2758228d79bcSJed Brown 
2759228d79bcSJed Brown .seealso: SNESMonitorSet()
2760228d79bcSJed Brown @*/
27617a03ce2fSLisandro Dalcin PetscErrorCode  SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm)
27627a03ce2fSLisandro Dalcin {
27637a03ce2fSLisandro Dalcin   PetscErrorCode ierr;
27647a03ce2fSLisandro Dalcin   PetscInt       i,n = snes->numbermonitors;
27657a03ce2fSLisandro Dalcin 
27667a03ce2fSLisandro Dalcin   PetscFunctionBegin;
27677a03ce2fSLisandro Dalcin   for (i=0; i<n; i++) {
27687a03ce2fSLisandro Dalcin     ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr);
27697a03ce2fSLisandro Dalcin   }
27707a03ce2fSLisandro Dalcin   PetscFunctionReturn(0);
27717a03ce2fSLisandro Dalcin }
27727a03ce2fSLisandro Dalcin 
27739b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */
27749b94acceSBarry Smith 
27754a2ae208SSatish Balay #undef __FUNCT__
2776a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet"
27779b94acceSBarry Smith /*@C
2778a6570f20SBarry Smith    SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
27799b94acceSBarry Smith    iteration of the nonlinear solver to display the iteration's
27809b94acceSBarry Smith    progress.
27819b94acceSBarry Smith 
27823f9fe445SBarry Smith    Logically Collective on SNES
2783fee21e36SBarry Smith 
2784c7afd0dbSLois Curfman McInnes    Input Parameters:
2785c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2786c7afd0dbSLois Curfman McInnes .  func - monitoring routine
2787b8a78c4aSBarry Smith .  mctx - [optional] user-defined context for private data for the
2788e8105e01SRichard Katz           monitor routine (use PETSC_NULL if no context is desired)
2789b3006f0bSLois Curfman McInnes -  monitordestroy - [optional] routine that frees monitor context
2790b3006f0bSLois Curfman McInnes           (may be PETSC_NULL)
27919b94acceSBarry Smith 
2792c7afd0dbSLois Curfman McInnes    Calling sequence of func:
2793a7cc72afSBarry Smith $     int func(SNES snes,PetscInt its, PetscReal norm,void *mctx)
2794c7afd0dbSLois Curfman McInnes 
2795c7afd0dbSLois Curfman McInnes +    snes - the SNES context
2796c7afd0dbSLois Curfman McInnes .    its - iteration number
2797c7afd0dbSLois Curfman McInnes .    norm - 2-norm function value (may be estimated)
279840a0c1c6SLois Curfman McInnes -    mctx - [optional] monitoring context
27999b94acceSBarry Smith 
28009665c990SLois Curfman McInnes    Options Database Keys:
2801a6570f20SBarry Smith +    -snes_monitor        - sets SNESMonitorDefault()
2802a6570f20SBarry Smith .    -snes_monitor_draw    - sets line graph monitor,
2803a6570f20SBarry Smith                             uses SNESMonitorLGCreate()
2804cca6129bSJed Brown -    -snes_monitor_cancel - cancels all monitors that have
2805c7afd0dbSLois Curfman McInnes                             been hardwired into a code by
2806a6570f20SBarry Smith                             calls to SNESMonitorSet(), but
2807c7afd0dbSLois Curfman McInnes                             does not cancel those set via
2808c7afd0dbSLois Curfman McInnes                             the options database.
28099665c990SLois Curfman McInnes 
2810639f9d9dSBarry Smith    Notes:
28116bc08f3fSLois Curfman McInnes    Several different monitoring routines may be set by calling
2812a6570f20SBarry Smith    SNESMonitorSet() multiple times; all will be called in the
28136bc08f3fSLois Curfman McInnes    order in which they were set.
2814639f9d9dSBarry Smith 
2815025f1a04SBarry Smith    Fortran notes: Only a single monitor function can be set for each SNES object
2816025f1a04SBarry Smith 
281736851e7fSLois Curfman McInnes    Level: intermediate
281836851e7fSLois Curfman McInnes 
28199b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor
28209b94acceSBarry Smith 
2821a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel()
28229b94acceSBarry Smith @*/
2823c2efdce3SBarry Smith PetscErrorCode  SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
28249b94acceSBarry Smith {
2825b90d0a6eSBarry Smith   PetscInt       i;
2826649052a6SBarry Smith   PetscErrorCode ierr;
2827b90d0a6eSBarry Smith 
28283a40ed3dSBarry Smith   PetscFunctionBegin;
28290700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
283017186662SBarry Smith   if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
2831b90d0a6eSBarry Smith   for (i=0; i<snes->numbermonitors;i++) {
2832649052a6SBarry Smith     if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) {
2833649052a6SBarry Smith       if (monitordestroy) {
2834c2efdce3SBarry Smith         ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr);
2835649052a6SBarry Smith       }
2836b90d0a6eSBarry Smith       PetscFunctionReturn(0);
2837b90d0a6eSBarry Smith     }
2838b90d0a6eSBarry Smith   }
2839b90d0a6eSBarry Smith   snes->monitor[snes->numbermonitors]           = monitor;
2840b8a78c4aSBarry Smith   snes->monitordestroy[snes->numbermonitors]    = monitordestroy;
2841639f9d9dSBarry Smith   snes->monitorcontext[snes->numbermonitors++]  = (void*)mctx;
28423a40ed3dSBarry Smith   PetscFunctionReturn(0);
28439b94acceSBarry Smith }
28449b94acceSBarry Smith 
28454a2ae208SSatish Balay #undef __FUNCT__
2846a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel"
28475cd90555SBarry Smith /*@C
2848a6570f20SBarry Smith    SNESMonitorCancel - Clears all the monitor functions for a SNES object.
28495cd90555SBarry Smith 
28503f9fe445SBarry Smith    Logically Collective on SNES
2851c7afd0dbSLois Curfman McInnes 
28525cd90555SBarry Smith    Input Parameters:
28535cd90555SBarry Smith .  snes - the SNES context
28545cd90555SBarry Smith 
28551a480d89SAdministrator    Options Database Key:
2856a6570f20SBarry Smith .  -snes_monitor_cancel - cancels all monitors that have been hardwired
2857a6570f20SBarry Smith     into a code by calls to SNESMonitorSet(), but does not cancel those
2858c7afd0dbSLois Curfman McInnes     set via the options database
28595cd90555SBarry Smith 
28605cd90555SBarry Smith    Notes:
28615cd90555SBarry Smith    There is no way to clear one specific monitor from a SNES object.
28625cd90555SBarry Smith 
286336851e7fSLois Curfman McInnes    Level: intermediate
286436851e7fSLois Curfman McInnes 
28655cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor
28665cd90555SBarry Smith 
2867a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet()
28685cd90555SBarry Smith @*/
28697087cfbeSBarry Smith PetscErrorCode  SNESMonitorCancel(SNES snes)
28705cd90555SBarry Smith {
2871d952e501SBarry Smith   PetscErrorCode ierr;
2872d952e501SBarry Smith   PetscInt       i;
2873d952e501SBarry Smith 
28745cd90555SBarry Smith   PetscFunctionBegin;
28750700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2876d952e501SBarry Smith   for (i=0; i<snes->numbermonitors; i++) {
2877d952e501SBarry Smith     if (snes->monitordestroy[i]) {
28783c4aec1bSBarry Smith       ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr);
2879d952e501SBarry Smith     }
2880d952e501SBarry Smith   }
28815cd90555SBarry Smith   snes->numbermonitors = 0;
28825cd90555SBarry Smith   PetscFunctionReturn(0);
28835cd90555SBarry Smith }
28845cd90555SBarry Smith 
28854a2ae208SSatish Balay #undef __FUNCT__
28864a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest"
28879b94acceSBarry Smith /*@C
28889b94acceSBarry Smith    SNESSetConvergenceTest - Sets the function that is to be used
28899b94acceSBarry Smith    to test for convergence of the nonlinear iterative solution.
28909b94acceSBarry Smith 
28913f9fe445SBarry Smith    Logically Collective on SNES
2892fee21e36SBarry Smith 
2893c7afd0dbSLois Curfman McInnes    Input Parameters:
2894c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2895c7afd0dbSLois Curfman McInnes .  func - routine to test for convergence
28967f7931b9SBarry Smith .  cctx - [optional] context for private data for the convergence routine  (may be PETSC_NULL)
28977f7931b9SBarry Smith -  destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran)
28989b94acceSBarry Smith 
2899c7afd0dbSLois Curfman McInnes    Calling sequence of func:
290006ee9f85SBarry Smith $     PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
2901c7afd0dbSLois Curfman McInnes 
2902c7afd0dbSLois Curfman McInnes +    snes - the SNES context
290306ee9f85SBarry Smith .    it - current iteration (0 is the first and is before any Newton step)
2904c7afd0dbSLois Curfman McInnes .    cctx - [optional] convergence context
2905184914b5SBarry Smith .    reason - reason for convergence/divergence
2906c7afd0dbSLois Curfman McInnes .    xnorm - 2-norm of current iterate
29074b27c08aSLois Curfman McInnes .    gnorm - 2-norm of current step
29084b27c08aSLois Curfman McInnes -    f - 2-norm of function
29099b94acceSBarry Smith 
291036851e7fSLois Curfman McInnes    Level: advanced
291136851e7fSLois Curfman McInnes 
29129b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test
29139b94acceSBarry Smith 
291485385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged()
29159b94acceSBarry Smith @*/
29167087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
29179b94acceSBarry Smith {
29187f7931b9SBarry Smith   PetscErrorCode ierr;
29197f7931b9SBarry Smith 
29203a40ed3dSBarry Smith   PetscFunctionBegin;
29210700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
292285385478SLisandro Dalcin   if (!func) func = SNESSkipConverged;
29237f7931b9SBarry Smith   if (snes->ops->convergeddestroy) {
29247f7931b9SBarry Smith     ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr);
29257f7931b9SBarry Smith   }
292685385478SLisandro Dalcin   snes->ops->converged        = func;
29277f7931b9SBarry Smith   snes->ops->convergeddestroy = destroy;
292885385478SLisandro Dalcin   snes->cnvP                  = cctx;
29293a40ed3dSBarry Smith   PetscFunctionReturn(0);
29309b94acceSBarry Smith }
29319b94acceSBarry Smith 
29324a2ae208SSatish Balay #undef __FUNCT__
29334a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason"
293452baeb72SSatish Balay /*@
2935184914b5SBarry Smith    SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
2936184914b5SBarry Smith 
2937184914b5SBarry Smith    Not Collective
2938184914b5SBarry Smith 
2939184914b5SBarry Smith    Input Parameter:
2940184914b5SBarry Smith .  snes - the SNES context
2941184914b5SBarry Smith 
2942184914b5SBarry Smith    Output Parameter:
29434d0a8057SBarry Smith .  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
2944184914b5SBarry Smith             manual pages for the individual convergence tests for complete lists
2945184914b5SBarry Smith 
2946184914b5SBarry Smith    Level: intermediate
2947184914b5SBarry Smith 
2948184914b5SBarry Smith    Notes: Can only be called after the call the SNESSolve() is complete.
2949184914b5SBarry Smith 
2950184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test
2951184914b5SBarry Smith 
295285385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason
2953184914b5SBarry Smith @*/
29547087cfbeSBarry Smith PetscErrorCode  SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
2955184914b5SBarry Smith {
2956184914b5SBarry Smith   PetscFunctionBegin;
29570700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
29584482741eSBarry Smith   PetscValidPointer(reason,2);
2959184914b5SBarry Smith   *reason = snes->reason;
2960184914b5SBarry Smith   PetscFunctionReturn(0);
2961184914b5SBarry Smith }
2962184914b5SBarry Smith 
29634a2ae208SSatish Balay #undef __FUNCT__
29644a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory"
2965c9005455SLois Curfman McInnes /*@
2966c9005455SLois Curfman McInnes    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
2967c9005455SLois Curfman McInnes 
29683f9fe445SBarry Smith    Logically Collective on SNES
2969fee21e36SBarry Smith 
2970c7afd0dbSLois Curfman McInnes    Input Parameters:
2971c7afd0dbSLois Curfman McInnes +  snes - iterative context obtained from SNESCreate()
29728c7482ecSBarry Smith .  a   - array to hold history, this array will contain the function norms computed at each step
2973cd5578b5SBarry Smith .  its - integer array holds the number of linear iterations for each solve.
2974758f92a0SBarry Smith .  na  - size of a and its
297564731454SLois Curfman McInnes -  reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
2976758f92a0SBarry Smith            else it continues storing new values for new nonlinear solves after the old ones
2977c7afd0dbSLois Curfman McInnes 
2978308dcc3eSBarry Smith    Notes:
2979308dcc3eSBarry Smith    If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a
2980308dcc3eSBarry Smith    default array of length 10000 is allocated.
2981308dcc3eSBarry Smith 
2982c9005455SLois Curfman McInnes    This routine is useful, e.g., when running a code for purposes
2983c9005455SLois Curfman McInnes    of accurate performance monitoring, when no I/O should be done
2984c9005455SLois Curfman McInnes    during the section of code that is being timed.
2985c9005455SLois Curfman McInnes 
298636851e7fSLois Curfman McInnes    Level: intermediate
298736851e7fSLois Curfman McInnes 
2988c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history
2989758f92a0SBarry Smith 
299008405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory()
2991758f92a0SBarry Smith 
2992c9005455SLois Curfman McInnes @*/
29937087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool  reset)
2994c9005455SLois Curfman McInnes {
2995308dcc3eSBarry Smith   PetscErrorCode ierr;
2996308dcc3eSBarry Smith 
29973a40ed3dSBarry Smith   PetscFunctionBegin;
29980700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
29994482741eSBarry Smith   if (na)  PetscValidScalarPointer(a,2);
3000a562a398SLisandro Dalcin   if (its) PetscValidIntPointer(its,3);
3001308dcc3eSBarry Smith   if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) {
3002308dcc3eSBarry Smith     if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
3003308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr);
3004308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr);
3005308dcc3eSBarry Smith     snes->conv_malloc   = PETSC_TRUE;
3006308dcc3eSBarry Smith   }
3007c9005455SLois Curfman McInnes   snes->conv_hist       = a;
3008758f92a0SBarry Smith   snes->conv_hist_its   = its;
3009758f92a0SBarry Smith   snes->conv_hist_max   = na;
3010a12bc48fSLisandro Dalcin   snes->conv_hist_len   = 0;
3011758f92a0SBarry Smith   snes->conv_hist_reset = reset;
3012758f92a0SBarry Smith   PetscFunctionReturn(0);
3013758f92a0SBarry Smith }
3014758f92a0SBarry Smith 
3015308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3016c6db04a5SJed Brown #include <engine.h>   /* MATLAB include file */
3017c6db04a5SJed Brown #include <mex.h>      /* MATLAB include file */
3018308dcc3eSBarry Smith EXTERN_C_BEGIN
3019308dcc3eSBarry Smith #undef __FUNCT__
3020308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab"
3021308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes)
3022308dcc3eSBarry Smith {
3023308dcc3eSBarry Smith   mxArray        *mat;
3024308dcc3eSBarry Smith   PetscInt       i;
3025308dcc3eSBarry Smith   PetscReal      *ar;
3026308dcc3eSBarry Smith 
3027308dcc3eSBarry Smith   PetscFunctionBegin;
3028308dcc3eSBarry Smith   mat  = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL);
3029308dcc3eSBarry Smith   ar   = (PetscReal*) mxGetData(mat);
3030308dcc3eSBarry Smith   for (i=0; i<snes->conv_hist_len; i++) {
3031308dcc3eSBarry Smith     ar[i] = snes->conv_hist[i];
3032308dcc3eSBarry Smith   }
3033308dcc3eSBarry Smith   PetscFunctionReturn(mat);
3034308dcc3eSBarry Smith }
3035308dcc3eSBarry Smith EXTERN_C_END
3036308dcc3eSBarry Smith #endif
3037308dcc3eSBarry Smith 
3038308dcc3eSBarry Smith 
30394a2ae208SSatish Balay #undef __FUNCT__
30404a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory"
30410c4c9dddSBarry Smith /*@C
3042758f92a0SBarry Smith    SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
3043758f92a0SBarry Smith 
30443f9fe445SBarry Smith    Not Collective
3045758f92a0SBarry Smith 
3046758f92a0SBarry Smith    Input Parameter:
3047758f92a0SBarry Smith .  snes - iterative context obtained from SNESCreate()
3048758f92a0SBarry Smith 
3049758f92a0SBarry Smith    Output Parameters:
3050758f92a0SBarry Smith .  a   - array to hold history
3051758f92a0SBarry Smith .  its - integer array holds the number of linear iterations (or
3052758f92a0SBarry Smith          negative if not converged) for each solve.
3053758f92a0SBarry Smith -  na  - size of a and its
3054758f92a0SBarry Smith 
3055758f92a0SBarry Smith    Notes:
3056758f92a0SBarry Smith     The calling sequence for this routine in Fortran is
3057758f92a0SBarry Smith $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
3058758f92a0SBarry Smith 
3059758f92a0SBarry Smith    This routine is useful, e.g., when running a code for purposes
3060758f92a0SBarry Smith    of accurate performance monitoring, when no I/O should be done
3061758f92a0SBarry Smith    during the section of code that is being timed.
3062758f92a0SBarry Smith 
3063758f92a0SBarry Smith    Level: intermediate
3064758f92a0SBarry Smith 
3065758f92a0SBarry Smith .keywords: SNES, get, convergence, history
3066758f92a0SBarry Smith 
3067758f92a0SBarry Smith .seealso: SNESSetConvergencHistory()
3068758f92a0SBarry Smith 
3069758f92a0SBarry Smith @*/
30707087cfbeSBarry Smith PetscErrorCode  SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
3071758f92a0SBarry Smith {
3072758f92a0SBarry Smith   PetscFunctionBegin;
30730700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3074758f92a0SBarry Smith   if (a)   *a   = snes->conv_hist;
3075758f92a0SBarry Smith   if (its) *its = snes->conv_hist_its;
3076758f92a0SBarry Smith   if (na)  *na  = snes->conv_hist_len;
30773a40ed3dSBarry Smith   PetscFunctionReturn(0);
3078c9005455SLois Curfman McInnes }
3079c9005455SLois Curfman McInnes 
3080e74ef692SMatthew Knepley #undef __FUNCT__
3081e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate"
3082ac226902SBarry Smith /*@C
308376b2cf59SMatthew Knepley   SNESSetUpdate - Sets the general-purpose update function called
3084eec8f646SJed Brown   at the beginning of every iteration of the nonlinear solve. Specifically
30857e4bb74cSBarry Smith   it is called just before the Jacobian is "evaluated".
308676b2cf59SMatthew Knepley 
30873f9fe445SBarry Smith   Logically Collective on SNES
308876b2cf59SMatthew Knepley 
308976b2cf59SMatthew Knepley   Input Parameters:
309076b2cf59SMatthew Knepley . snes - The nonlinear solver context
309176b2cf59SMatthew Knepley . func - The function
309276b2cf59SMatthew Knepley 
309376b2cf59SMatthew Knepley   Calling sequence of func:
3094b5d30489SBarry Smith . func (SNES snes, PetscInt step);
309576b2cf59SMatthew Knepley 
309676b2cf59SMatthew Knepley . step - The current step of the iteration
309776b2cf59SMatthew Knepley 
3098fe97e370SBarry Smith   Level: advanced
3099fe97e370SBarry Smith 
3100fe97e370SBarry 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()
3101fe97e370SBarry Smith         This is not used by most users.
310276b2cf59SMatthew Knepley 
310376b2cf59SMatthew Knepley .keywords: SNES, update
3104b5d30489SBarry Smith 
310585385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve()
310676b2cf59SMatthew Knepley @*/
31077087cfbeSBarry Smith PetscErrorCode  SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
310876b2cf59SMatthew Knepley {
310976b2cf59SMatthew Knepley   PetscFunctionBegin;
31100700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID,1);
3111e7788613SBarry Smith   snes->ops->update = func;
311276b2cf59SMatthew Knepley   PetscFunctionReturn(0);
311376b2cf59SMatthew Knepley }
311476b2cf59SMatthew Knepley 
3115e74ef692SMatthew Knepley #undef __FUNCT__
3116e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate"
311776b2cf59SMatthew Knepley /*@
311876b2cf59SMatthew Knepley   SNESDefaultUpdate - The default update function which does nothing.
311976b2cf59SMatthew Knepley 
312076b2cf59SMatthew Knepley   Not collective
312176b2cf59SMatthew Knepley 
312276b2cf59SMatthew Knepley   Input Parameters:
312376b2cf59SMatthew Knepley . snes - The nonlinear solver context
312476b2cf59SMatthew Knepley . step - The current step of the iteration
312576b2cf59SMatthew Knepley 
3126205452f4SMatthew Knepley   Level: intermediate
3127205452f4SMatthew Knepley 
312876b2cf59SMatthew Knepley .keywords: SNES, update
3129a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC()
313076b2cf59SMatthew Knepley @*/
31317087cfbeSBarry Smith PetscErrorCode  SNESDefaultUpdate(SNES snes, PetscInt step)
313276b2cf59SMatthew Knepley {
313376b2cf59SMatthew Knepley   PetscFunctionBegin;
313476b2cf59SMatthew Knepley   PetscFunctionReturn(0);
313576b2cf59SMatthew Knepley }
313676b2cf59SMatthew Knepley 
31374a2ae208SSatish Balay #undef __FUNCT__
31384a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private"
31399b94acceSBarry Smith /*
31409b94acceSBarry Smith    SNESScaleStep_Private - Scales a step so that its length is less than the
31419b94acceSBarry Smith    positive parameter delta.
31429b94acceSBarry Smith 
31439b94acceSBarry Smith     Input Parameters:
3144c7afd0dbSLois Curfman McInnes +   snes - the SNES context
31459b94acceSBarry Smith .   y - approximate solution of linear system
31469b94acceSBarry Smith .   fnorm - 2-norm of current function
3147c7afd0dbSLois Curfman McInnes -   delta - trust region size
31489b94acceSBarry Smith 
31499b94acceSBarry Smith     Output Parameters:
3150c7afd0dbSLois Curfman McInnes +   gpnorm - predicted function norm at the new point, assuming local
31519b94acceSBarry Smith     linearization.  The value is zero if the step lies within the trust
31529b94acceSBarry Smith     region, and exceeds zero otherwise.
3153c7afd0dbSLois Curfman McInnes -   ynorm - 2-norm of the step
31549b94acceSBarry Smith 
31559b94acceSBarry Smith     Note:
31564b27c08aSLois Curfman McInnes     For non-trust region methods such as SNESLS, the parameter delta
31579b94acceSBarry Smith     is set to be the maximum allowable step size.
31589b94acceSBarry Smith 
31599b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step
31609b94acceSBarry Smith */
3161dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
31629b94acceSBarry Smith {
3163064f8208SBarry Smith   PetscReal      nrm;
3164ea709b57SSatish Balay   PetscScalar    cnorm;
3165dfbe8321SBarry Smith   PetscErrorCode ierr;
31663a40ed3dSBarry Smith 
31673a40ed3dSBarry Smith   PetscFunctionBegin;
31680700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
31690700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3170c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,2);
3171184914b5SBarry Smith 
3172064f8208SBarry Smith   ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr);
3173064f8208SBarry Smith   if (nrm > *delta) {
3174064f8208SBarry Smith      nrm = *delta/nrm;
3175064f8208SBarry Smith      *gpnorm = (1.0 - nrm)*(*fnorm);
3176064f8208SBarry Smith      cnorm = nrm;
31772dcb1b2aSMatthew Knepley      ierr = VecScale(y,cnorm);CHKERRQ(ierr);
31789b94acceSBarry Smith      *ynorm = *delta;
31799b94acceSBarry Smith   } else {
31809b94acceSBarry Smith      *gpnorm = 0.0;
3181064f8208SBarry Smith      *ynorm = nrm;
31829b94acceSBarry Smith   }
31833a40ed3dSBarry Smith   PetscFunctionReturn(0);
31849b94acceSBarry Smith }
31859b94acceSBarry Smith 
31864a2ae208SSatish Balay #undef __FUNCT__
31874a2ae208SSatish Balay #define __FUNCT__ "SNESSolve"
31886ce558aeSBarry Smith /*@C
3189f69a0ea3SMatthew Knepley    SNESSolve - Solves a nonlinear system F(x) = b.
3190f69a0ea3SMatthew Knepley    Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
31919b94acceSBarry Smith 
3192c7afd0dbSLois Curfman McInnes    Collective on SNES
3193c7afd0dbSLois Curfman McInnes 
3194b2002411SLois Curfman McInnes    Input Parameters:
3195c7afd0dbSLois Curfman McInnes +  snes - the SNES context
31963cebf274SJed Brown .  b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero.
319785385478SLisandro Dalcin -  x - the solution vector.
31989b94acceSBarry Smith 
3199b2002411SLois Curfman McInnes    Notes:
32008ddd3da0SLois Curfman McInnes    The user should initialize the vector,x, with the initial guess
32018ddd3da0SLois Curfman McInnes    for the nonlinear solve prior to calling SNESSolve.  In particular,
32028ddd3da0SLois Curfman McInnes    to employ an initial guess of zero, the user should explicitly set
32038ddd3da0SLois Curfman McInnes    this vector to zero by calling VecSet().
32048ddd3da0SLois Curfman McInnes 
320536851e7fSLois Curfman McInnes    Level: beginner
320636851e7fSLois Curfman McInnes 
32079b94acceSBarry Smith .keywords: SNES, nonlinear, solve
32089b94acceSBarry Smith 
3209c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution()
32109b94acceSBarry Smith @*/
32117087cfbeSBarry Smith PetscErrorCode  SNESSolve(SNES snes,Vec b,Vec x)
32129b94acceSBarry Smith {
3213dfbe8321SBarry Smith   PetscErrorCode ierr;
3214ace3abfcSBarry Smith   PetscBool      flg;
3215eabae89aSBarry Smith   char           filename[PETSC_MAX_PATH_LEN];
3216eabae89aSBarry Smith   PetscViewer    viewer;
3217efd51863SBarry Smith   PetscInt       grid;
3218a69afd8bSBarry Smith   Vec            xcreated = PETSC_NULL;
3219052efed2SBarry Smith 
32203a40ed3dSBarry Smith   PetscFunctionBegin;
32210700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3222a69afd8bSBarry Smith   if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3223a69afd8bSBarry Smith   if (x) PetscCheckSameComm(snes,1,x,3);
32240700a824SBarry Smith   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2);
322585385478SLisandro Dalcin   if (b) PetscCheckSameComm(snes,1,b,2);
322685385478SLisandro Dalcin 
3227a69afd8bSBarry Smith   if (!x && snes->dm) {
3228a69afd8bSBarry Smith     ierr = DMCreateGlobalVector(snes->dm,&xcreated);CHKERRQ(ierr);
3229a69afd8bSBarry Smith     x    = xcreated;
3230a69afd8bSBarry Smith   }
3231a69afd8bSBarry Smith 
3232a8248277SBarry Smith   for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);}
3233efd51863SBarry Smith   for (grid=0; grid<snes->gridsequence+1; grid++) {
3234efd51863SBarry Smith 
323585385478SLisandro Dalcin     /* set solution vector */
3236efd51863SBarry Smith     if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);}
32376bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
323885385478SLisandro Dalcin     snes->vec_sol = x;
323985385478SLisandro Dalcin     /* set afine vector if provided */
324085385478SLisandro Dalcin     if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); }
32416bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
324285385478SLisandro Dalcin     snes->vec_rhs = b;
324385385478SLisandro Dalcin 
324470e92668SMatthew Knepley     ierr = SNESSetUp(snes);CHKERRQ(ierr);
32453f149594SLisandro Dalcin 
32467eee914bSBarry Smith     if (!grid) {
32477eee914bSBarry Smith       if (snes->ops->computeinitialguess) {
3248d25893d9SBarry Smith         ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr);
3249dd568438SSatish Balay       } else if (snes->dm) {
3250dd568438SSatish Balay         PetscBool ig;
3251dd568438SSatish Balay         ierr = DMHasInitialGuess(snes->dm,&ig);CHKERRQ(ierr);
3252dd568438SSatish Balay         if (ig) {
32537eee914bSBarry Smith           ierr = DMComputeInitialGuess(snes->dm,snes->vec_sol);CHKERRQ(ierr);
32547eee914bSBarry Smith         }
3255d25893d9SBarry Smith       }
3256dd568438SSatish Balay     }
3257d25893d9SBarry Smith 
3258abc0a331SBarry Smith     if (snes->conv_hist_reset) snes->conv_hist_len = 0;
325950ffb88aSMatthew Knepley     snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;
3260d5e45103SBarry Smith 
32613f149594SLisandro Dalcin     ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
32624936397dSBarry Smith     ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr);
326385385478SLisandro Dalcin     ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
32644936397dSBarry Smith     if (snes->domainerror){
32654936397dSBarry Smith       snes->reason      = SNES_DIVERGED_FUNCTION_DOMAIN;
32664936397dSBarry Smith       snes->domainerror = PETSC_FALSE;
32674936397dSBarry Smith     }
326817186662SBarry Smith     if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
32693f149594SLisandro Dalcin 
32707adad957SLisandro Dalcin     ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
3271eabae89aSBarry Smith     if (flg && !PetscPreLoadingOn) {
32727adad957SLisandro Dalcin       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr);
3273eabae89aSBarry Smith       ierr = SNESView(snes,viewer);CHKERRQ(ierr);
32746bf464f9SBarry Smith       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
3275eabae89aSBarry Smith     }
3276eabae89aSBarry Smith 
327790d69ab7SBarry Smith     flg  = PETSC_FALSE;
3278acfcf0e5SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr);
3279da9b6338SBarry Smith     if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); }
32805968eb51SBarry Smith     if (snes->printreason) {
3281a8248277SBarry Smith       ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
32825968eb51SBarry Smith       if (snes->reason > 0) {
3283a8248277SBarry Smith         ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),"Nonlinear solve converged due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr);
32845968eb51SBarry Smith       } else {
3285a8248277SBarry Smith         ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),"Nonlinear solve did not converge due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr);
32865968eb51SBarry Smith       }
3287a8248277SBarry Smith       ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
32885968eb51SBarry Smith     }
32895968eb51SBarry Smith 
32908501fc72SJed Brown     flg = PETSC_FALSE;
32918501fc72SJed Brown     ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
32928501fc72SJed Brown     if (flg) {
32938501fc72SJed Brown       PetscViewer viewer;
32948501fc72SJed Brown       ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr);
32958501fc72SJed Brown       ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr);
32968501fc72SJed Brown       ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr);
32978501fc72SJed Brown       ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr);
32988501fc72SJed Brown       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
32998501fc72SJed Brown     }
33008501fc72SJed Brown 
3301e113a28aSBarry Smith     if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged");
3302efd51863SBarry Smith     if (grid <  snes->gridsequence) {
3303efd51863SBarry Smith       DM  fine;
3304efd51863SBarry Smith       Vec xnew;
3305efd51863SBarry Smith       Mat interp;
3306efd51863SBarry Smith 
3307efd51863SBarry Smith       ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr);
3308e727c939SJed Brown       ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr);
3309efd51863SBarry Smith       ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr);
3310efd51863SBarry Smith       ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr);
3311efd51863SBarry Smith       ierr = MatDestroy(&interp);CHKERRQ(ierr);
3312efd51863SBarry Smith       x    = xnew;
3313efd51863SBarry Smith 
3314efd51863SBarry Smith       ierr = SNESReset(snes);CHKERRQ(ierr);
3315efd51863SBarry Smith       ierr = SNESSetDM(snes,fine);CHKERRQ(ierr);
3316efd51863SBarry Smith       ierr = DMDestroy(&fine);CHKERRQ(ierr);
3317a8248277SBarry Smith       ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);
3318efd51863SBarry Smith     }
3319efd51863SBarry Smith   }
3320a69afd8bSBarry Smith   ierr = VecDestroy(&xcreated);CHKERRQ(ierr);
33213a40ed3dSBarry Smith   PetscFunctionReturn(0);
33229b94acceSBarry Smith }
33239b94acceSBarry Smith 
33249b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */
33259b94acceSBarry Smith 
33264a2ae208SSatish Balay #undef __FUNCT__
33274a2ae208SSatish Balay #define __FUNCT__ "SNESSetType"
332882bf6240SBarry Smith /*@C
33294b0e389bSBarry Smith    SNESSetType - Sets the method for the nonlinear solver.
33309b94acceSBarry Smith 
3331fee21e36SBarry Smith    Collective on SNES
3332fee21e36SBarry Smith 
3333c7afd0dbSLois Curfman McInnes    Input Parameters:
3334c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3335454a90a3SBarry Smith -  type - a known method
3336c7afd0dbSLois Curfman McInnes 
3337c7afd0dbSLois Curfman McInnes    Options Database Key:
3338454a90a3SBarry Smith .  -snes_type <type> - Sets the method; use -help for a list
3339c7afd0dbSLois Curfman McInnes    of available methods (for instance, ls or tr)
3340ae12b187SLois Curfman McInnes 
33419b94acceSBarry Smith    Notes:
3342e090d566SSatish Balay    See "petsc/include/petscsnes.h" for available methods (for instance)
33434b27c08aSLois Curfman McInnes +    SNESLS - Newton's method with line search
3344c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
33454b27c08aSLois Curfman McInnes .    SNESTR - Newton's method with trust region
3346c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
33479b94acceSBarry Smith 
3348ae12b187SLois Curfman McInnes   Normally, it is best to use the SNESSetFromOptions() command and then
3349ae12b187SLois Curfman McInnes   set the SNES solver type from the options database rather than by using
3350ae12b187SLois Curfman McInnes   this routine.  Using the options database provides the user with
3351ae12b187SLois Curfman McInnes   maximum flexibility in evaluating the many nonlinear solvers.
3352ae12b187SLois Curfman McInnes   The SNESSetType() routine is provided for those situations where it
3353ae12b187SLois Curfman McInnes   is necessary to set the nonlinear solver independently of the command
3354ae12b187SLois Curfman McInnes   line or options database.  This might be the case, for example, when
3355ae12b187SLois Curfman McInnes   the choice of solver changes during the execution of the program,
3356ae12b187SLois Curfman McInnes   and the user's application is taking responsibility for choosing the
3357b0a32e0cSBarry Smith   appropriate method.
335836851e7fSLois Curfman McInnes 
335936851e7fSLois Curfman McInnes   Level: intermediate
3360a703fe33SLois Curfman McInnes 
3361454a90a3SBarry Smith .keywords: SNES, set, type
3362435da068SBarry Smith 
3363435da068SBarry Smith .seealso: SNESType, SNESCreate()
3364435da068SBarry Smith 
33659b94acceSBarry Smith @*/
33667087cfbeSBarry Smith PetscErrorCode  SNESSetType(SNES snes,const SNESType type)
33679b94acceSBarry Smith {
3368dfbe8321SBarry Smith   PetscErrorCode ierr,(*r)(SNES);
3369ace3abfcSBarry Smith   PetscBool      match;
33703a40ed3dSBarry Smith 
33713a40ed3dSBarry Smith   PetscFunctionBegin;
33720700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
33734482741eSBarry Smith   PetscValidCharPointer(type,2);
337482bf6240SBarry Smith 
33756831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr);
33760f5bd95cSBarry Smith   if (match) PetscFunctionReturn(0);
337792ff6ae8SBarry Smith 
33784b91b6eaSBarry Smith   ierr =  PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr);
3379e32f2f54SBarry Smith   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
338075396ef9SLisandro Dalcin   /* Destroy the previous private SNES context */
3381b5c23020SJed Brown   if (snes->ops->destroy) {
3382b5c23020SJed Brown     ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr);
3383b5c23020SJed Brown     snes->ops->destroy = PETSC_NULL;
3384b5c23020SJed Brown   }
338575396ef9SLisandro Dalcin   /* Reinitialize function pointers in SNESOps structure */
338675396ef9SLisandro Dalcin   snes->ops->setup          = 0;
338775396ef9SLisandro Dalcin   snes->ops->solve          = 0;
338875396ef9SLisandro Dalcin   snes->ops->view           = 0;
338975396ef9SLisandro Dalcin   snes->ops->setfromoptions = 0;
339075396ef9SLisandro Dalcin   snes->ops->destroy        = 0;
339175396ef9SLisandro Dalcin   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
339275396ef9SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
3393454a90a3SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr);
339403bfa161SLisandro Dalcin   ierr = (*r)(snes);CHKERRQ(ierr);
33959fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS)
33969fb22e1aSBarry Smith   if (PetscAMSPublishAll) {
33979fb22e1aSBarry Smith     ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr);
33989fb22e1aSBarry Smith   }
33999fb22e1aSBarry Smith #endif
34003a40ed3dSBarry Smith   PetscFunctionReturn(0);
34019b94acceSBarry Smith }
34029b94acceSBarry Smith 
3403a847f771SSatish Balay 
34049b94acceSBarry Smith /* --------------------------------------------------------------------- */
34054a2ae208SSatish Balay #undef __FUNCT__
34064a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy"
340752baeb72SSatish Balay /*@
34089b94acceSBarry Smith    SNESRegisterDestroy - Frees the list of nonlinear solvers that were
3409f1af5d2fSBarry Smith    registered by SNESRegisterDynamic().
34109b94acceSBarry Smith 
3411fee21e36SBarry Smith    Not Collective
3412fee21e36SBarry Smith 
341336851e7fSLois Curfman McInnes    Level: advanced
341436851e7fSLois Curfman McInnes 
34159b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy
34169b94acceSBarry Smith 
34179b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll()
34189b94acceSBarry Smith @*/
34197087cfbeSBarry Smith PetscErrorCode  SNESRegisterDestroy(void)
34209b94acceSBarry Smith {
3421dfbe8321SBarry Smith   PetscErrorCode ierr;
342282bf6240SBarry Smith 
34233a40ed3dSBarry Smith   PetscFunctionBegin;
34241441b1d3SBarry Smith   ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr);
34254c49b128SBarry Smith   SNESRegisterAllCalled = PETSC_FALSE;
34263a40ed3dSBarry Smith   PetscFunctionReturn(0);
34279b94acceSBarry Smith }
34289b94acceSBarry Smith 
34294a2ae208SSatish Balay #undef __FUNCT__
34304a2ae208SSatish Balay #define __FUNCT__ "SNESGetType"
34319b94acceSBarry Smith /*@C
34329a28b0a6SLois Curfman McInnes    SNESGetType - Gets the SNES method type and name (as a string).
34339b94acceSBarry Smith 
3434c7afd0dbSLois Curfman McInnes    Not Collective
3435c7afd0dbSLois Curfman McInnes 
34369b94acceSBarry Smith    Input Parameter:
34374b0e389bSBarry Smith .  snes - nonlinear solver context
34389b94acceSBarry Smith 
34399b94acceSBarry Smith    Output Parameter:
34403a7fca6bSBarry Smith .  type - SNES method (a character string)
34419b94acceSBarry Smith 
344236851e7fSLois Curfman McInnes    Level: intermediate
344336851e7fSLois Curfman McInnes 
3444454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name
34459b94acceSBarry Smith @*/
34467087cfbeSBarry Smith PetscErrorCode  SNESGetType(SNES snes,const SNESType *type)
34479b94acceSBarry Smith {
34483a40ed3dSBarry Smith   PetscFunctionBegin;
34490700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
34504482741eSBarry Smith   PetscValidPointer(type,2);
34517adad957SLisandro Dalcin   *type = ((PetscObject)snes)->type_name;
34523a40ed3dSBarry Smith   PetscFunctionReturn(0);
34539b94acceSBarry Smith }
34549b94acceSBarry Smith 
34554a2ae208SSatish Balay #undef __FUNCT__
34564a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution"
345752baeb72SSatish Balay /*@
34589b94acceSBarry Smith    SNESGetSolution - Returns the vector where the approximate solution is
3459c0df2a02SJed Brown    stored. This is the fine grid solution when using SNESSetGridSequence().
34609b94acceSBarry Smith 
3461c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3462c7afd0dbSLois Curfman McInnes 
34639b94acceSBarry Smith    Input Parameter:
34649b94acceSBarry Smith .  snes - the SNES context
34659b94acceSBarry Smith 
34669b94acceSBarry Smith    Output Parameter:
34679b94acceSBarry Smith .  x - the solution
34689b94acceSBarry Smith 
346970e92668SMatthew Knepley    Level: intermediate
347036851e7fSLois Curfman McInnes 
34719b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution
34729b94acceSBarry Smith 
347385385478SLisandro Dalcin .seealso:  SNESGetSolutionUpdate(), SNESGetFunction()
34749b94acceSBarry Smith @*/
34757087cfbeSBarry Smith PetscErrorCode  SNESGetSolution(SNES snes,Vec *x)
34769b94acceSBarry Smith {
34773a40ed3dSBarry Smith   PetscFunctionBegin;
34780700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
34794482741eSBarry Smith   PetscValidPointer(x,2);
348085385478SLisandro Dalcin   *x = snes->vec_sol;
348170e92668SMatthew Knepley   PetscFunctionReturn(0);
348270e92668SMatthew Knepley }
348370e92668SMatthew Knepley 
348470e92668SMatthew Knepley #undef __FUNCT__
34854a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate"
348652baeb72SSatish Balay /*@
34879b94acceSBarry Smith    SNESGetSolutionUpdate - Returns the vector where the solution update is
34889b94acceSBarry Smith    stored.
34899b94acceSBarry Smith 
3490c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3491c7afd0dbSLois Curfman McInnes 
34929b94acceSBarry Smith    Input Parameter:
34939b94acceSBarry Smith .  snes - the SNES context
34949b94acceSBarry Smith 
34959b94acceSBarry Smith    Output Parameter:
34969b94acceSBarry Smith .  x - the solution update
34979b94acceSBarry Smith 
349836851e7fSLois Curfman McInnes    Level: advanced
349936851e7fSLois Curfman McInnes 
35009b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update
35019b94acceSBarry Smith 
350285385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction()
35039b94acceSBarry Smith @*/
35047087cfbeSBarry Smith PetscErrorCode  SNESGetSolutionUpdate(SNES snes,Vec *x)
35059b94acceSBarry Smith {
35063a40ed3dSBarry Smith   PetscFunctionBegin;
35070700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
35084482741eSBarry Smith   PetscValidPointer(x,2);
350985385478SLisandro Dalcin   *x = snes->vec_sol_update;
35103a40ed3dSBarry Smith   PetscFunctionReturn(0);
35119b94acceSBarry Smith }
35129b94acceSBarry Smith 
35134a2ae208SSatish Balay #undef __FUNCT__
35144a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction"
35159b94acceSBarry Smith /*@C
35163638b69dSLois Curfman McInnes    SNESGetFunction - Returns the vector where the function is stored.
35179b94acceSBarry Smith 
3518a63bb30eSJed Brown    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
3519c7afd0dbSLois Curfman McInnes 
35209b94acceSBarry Smith    Input Parameter:
35219b94acceSBarry Smith .  snes - the SNES context
35229b94acceSBarry Smith 
35239b94acceSBarry Smith    Output Parameter:
35247bf4e008SBarry Smith +  r - the function (or PETSC_NULL)
352570e92668SMatthew Knepley .  func - the function (or PETSC_NULL)
352670e92668SMatthew Knepley -  ctx - the function context (or PETSC_NULL)
35279b94acceSBarry Smith 
352836851e7fSLois Curfman McInnes    Level: advanced
352936851e7fSLois Curfman McInnes 
3530a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function
35319b94acceSBarry Smith 
35324b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution()
35339b94acceSBarry Smith @*/
35347087cfbeSBarry Smith PetscErrorCode  SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
35359b94acceSBarry Smith {
3536a63bb30eSJed Brown   PetscErrorCode ierr;
35376cab3a1bSJed Brown   DM             dm;
3538a63bb30eSJed Brown 
35393a40ed3dSBarry Smith   PetscFunctionBegin;
35400700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3541a63bb30eSJed Brown   if (r) {
3542a63bb30eSJed Brown     if (!snes->vec_func) {
3543a63bb30eSJed Brown       if (snes->vec_rhs) {
3544a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr);
3545a63bb30eSJed Brown       } else if (snes->vec_sol) {
3546a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr);
3547a63bb30eSJed Brown       } else if (snes->dm) {
3548a63bb30eSJed Brown         ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr);
3549a63bb30eSJed Brown       }
3550a63bb30eSJed Brown     }
3551a63bb30eSJed Brown     *r = snes->vec_func;
3552a63bb30eSJed Brown   }
35536cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
35546cab3a1bSJed Brown   ierr = DMSNESGetFunction(dm,func,ctx);CHKERRQ(ierr);
35553a40ed3dSBarry Smith   PetscFunctionReturn(0);
35569b94acceSBarry Smith }
35579b94acceSBarry Smith 
3558c79ef259SPeter Brune /*@C
3559c79ef259SPeter Brune    SNESGetGS - Returns the GS function and context.
3560c79ef259SPeter Brune 
3561c79ef259SPeter Brune    Input Parameter:
3562c79ef259SPeter Brune .  snes - the SNES context
3563c79ef259SPeter Brune 
3564c79ef259SPeter Brune    Output Parameter:
3565c79ef259SPeter Brune +  gsfunc - the function (or PETSC_NULL)
3566c79ef259SPeter Brune -  ctx    - the function context (or PETSC_NULL)
3567c79ef259SPeter Brune 
3568c79ef259SPeter Brune    Level: advanced
3569c79ef259SPeter Brune 
3570c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function
3571c79ef259SPeter Brune 
3572c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction()
3573c79ef259SPeter Brune @*/
3574c79ef259SPeter Brune 
35754a2ae208SSatish Balay #undef __FUNCT__
3576646217ecSPeter Brune #define __FUNCT__ "SNESGetGS"
3577646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx)
3578646217ecSPeter Brune {
35796cab3a1bSJed Brown   PetscErrorCode ierr;
35806cab3a1bSJed Brown   DM             dm;
35816cab3a1bSJed Brown 
3582646217ecSPeter Brune   PetscFunctionBegin;
3583646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
35846cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
35856cab3a1bSJed Brown   ierr = DMSNESGetGS(dm,func,ctx);CHKERRQ(ierr);
3586646217ecSPeter Brune   PetscFunctionReturn(0);
3587646217ecSPeter Brune }
3588646217ecSPeter Brune 
35894a2ae208SSatish Balay #undef __FUNCT__
35904a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix"
35913c7409f5SSatish Balay /*@C
35923c7409f5SSatish Balay    SNESSetOptionsPrefix - Sets the prefix used for searching for all
3593d850072dSLois Curfman McInnes    SNES options in the database.
35943c7409f5SSatish Balay 
35953f9fe445SBarry Smith    Logically Collective on SNES
3596fee21e36SBarry Smith 
3597c7afd0dbSLois Curfman McInnes    Input Parameter:
3598c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3599c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3600c7afd0dbSLois Curfman McInnes 
3601d850072dSLois Curfman McInnes    Notes:
3602a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
3603c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
3604d850072dSLois Curfman McInnes 
360536851e7fSLois Curfman McInnes    Level: advanced
360636851e7fSLois Curfman McInnes 
36073c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database
3608a86d99e1SLois Curfman McInnes 
3609a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions()
36103c7409f5SSatish Balay @*/
36117087cfbeSBarry Smith PetscErrorCode  SNESSetOptionsPrefix(SNES snes,const char prefix[])
36123c7409f5SSatish Balay {
3613dfbe8321SBarry Smith   PetscErrorCode ierr;
36143c7409f5SSatish Balay 
36153a40ed3dSBarry Smith   PetscFunctionBegin;
36160700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3617639f9d9dSBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
36181cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
361994b7f48cSBarry Smith   ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
36203a40ed3dSBarry Smith   PetscFunctionReturn(0);
36213c7409f5SSatish Balay }
36223c7409f5SSatish Balay 
36234a2ae208SSatish Balay #undef __FUNCT__
36244a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix"
36253c7409f5SSatish Balay /*@C
3626f525115eSLois Curfman McInnes    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
3627d850072dSLois Curfman McInnes    SNES options in the database.
36283c7409f5SSatish Balay 
36293f9fe445SBarry Smith    Logically Collective on SNES
3630fee21e36SBarry Smith 
3631c7afd0dbSLois Curfman McInnes    Input Parameters:
3632c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3633c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3634c7afd0dbSLois Curfman McInnes 
3635d850072dSLois Curfman McInnes    Notes:
3636a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
3637c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
3638d850072dSLois Curfman McInnes 
363936851e7fSLois Curfman McInnes    Level: advanced
364036851e7fSLois Curfman McInnes 
36413c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database
3642a86d99e1SLois Curfman McInnes 
3643a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix()
36443c7409f5SSatish Balay @*/
36457087cfbeSBarry Smith PetscErrorCode  SNESAppendOptionsPrefix(SNES snes,const char prefix[])
36463c7409f5SSatish Balay {
3647dfbe8321SBarry Smith   PetscErrorCode ierr;
36483c7409f5SSatish Balay 
36493a40ed3dSBarry Smith   PetscFunctionBegin;
36500700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3651639f9d9dSBarry Smith   ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
36521cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
365394b7f48cSBarry Smith   ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
36543a40ed3dSBarry Smith   PetscFunctionReturn(0);
36553c7409f5SSatish Balay }
36563c7409f5SSatish Balay 
36574a2ae208SSatish Balay #undef __FUNCT__
36584a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix"
36599ab63eb5SSatish Balay /*@C
36603c7409f5SSatish Balay    SNESGetOptionsPrefix - Sets the prefix used for searching for all
36613c7409f5SSatish Balay    SNES options in the database.
36623c7409f5SSatish Balay 
3663c7afd0dbSLois Curfman McInnes    Not Collective
3664c7afd0dbSLois Curfman McInnes 
36653c7409f5SSatish Balay    Input Parameter:
36663c7409f5SSatish Balay .  snes - the SNES context
36673c7409f5SSatish Balay 
36683c7409f5SSatish Balay    Output Parameter:
36693c7409f5SSatish Balay .  prefix - pointer to the prefix string used
36703c7409f5SSatish Balay 
36714ef407dbSRichard Tran Mills    Notes: On the fortran side, the user should pass in a string 'prefix' of
36729ab63eb5SSatish Balay    sufficient length to hold the prefix.
36739ab63eb5SSatish Balay 
367436851e7fSLois Curfman McInnes    Level: advanced
367536851e7fSLois Curfman McInnes 
36763c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database
3677a86d99e1SLois Curfman McInnes 
3678a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix()
36793c7409f5SSatish Balay @*/
36807087cfbeSBarry Smith PetscErrorCode  SNESGetOptionsPrefix(SNES snes,const char *prefix[])
36813c7409f5SSatish Balay {
3682dfbe8321SBarry Smith   PetscErrorCode ierr;
36833c7409f5SSatish Balay 
36843a40ed3dSBarry Smith   PetscFunctionBegin;
36850700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3686639f9d9dSBarry Smith   ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
36873a40ed3dSBarry Smith   PetscFunctionReturn(0);
36883c7409f5SSatish Balay }
36893c7409f5SSatish Balay 
3690b2002411SLois Curfman McInnes 
36914a2ae208SSatish Balay #undef __FUNCT__
36924a2ae208SSatish Balay #define __FUNCT__ "SNESRegister"
36933cea93caSBarry Smith /*@C
36943cea93caSBarry Smith   SNESRegister - See SNESRegisterDynamic()
36953cea93caSBarry Smith 
36967f6c08e0SMatthew Knepley   Level: advanced
36973cea93caSBarry Smith @*/
36987087cfbeSBarry Smith PetscErrorCode  SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES))
3699b2002411SLois Curfman McInnes {
3700e2d1d2b7SBarry Smith   char           fullname[PETSC_MAX_PATH_LEN];
3701dfbe8321SBarry Smith   PetscErrorCode ierr;
3702b2002411SLois Curfman McInnes 
3703b2002411SLois Curfman McInnes   PetscFunctionBegin;
3704b0a32e0cSBarry Smith   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
3705c134de8dSSatish Balay   ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
3706b2002411SLois Curfman McInnes   PetscFunctionReturn(0);
3707b2002411SLois Curfman McInnes }
3708da9b6338SBarry Smith 
3709da9b6338SBarry Smith #undef __FUNCT__
3710da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin"
37117087cfbeSBarry Smith PetscErrorCode  SNESTestLocalMin(SNES snes)
3712da9b6338SBarry Smith {
3713dfbe8321SBarry Smith   PetscErrorCode ierr;
371477431f27SBarry Smith   PetscInt       N,i,j;
3715da9b6338SBarry Smith   Vec            u,uh,fh;
3716da9b6338SBarry Smith   PetscScalar    value;
3717da9b6338SBarry Smith   PetscReal      norm;
3718da9b6338SBarry Smith 
3719da9b6338SBarry Smith   PetscFunctionBegin;
3720da9b6338SBarry Smith   ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr);
3721da9b6338SBarry Smith   ierr = VecDuplicate(u,&uh);CHKERRQ(ierr);
3722da9b6338SBarry Smith   ierr = VecDuplicate(u,&fh);CHKERRQ(ierr);
3723da9b6338SBarry Smith 
3724da9b6338SBarry Smith   /* currently only works for sequential */
3725da9b6338SBarry Smith   ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");
3726da9b6338SBarry Smith   ierr = VecGetSize(u,&N);CHKERRQ(ierr);
3727da9b6338SBarry Smith   for (i=0; i<N; i++) {
3728da9b6338SBarry Smith     ierr = VecCopy(u,uh);CHKERRQ(ierr);
372977431f27SBarry Smith     ierr  = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr);
3730da9b6338SBarry Smith     for (j=-10; j<11; j++) {
3731ccae9161SBarry Smith       value = PetscSign(j)*exp(PetscAbs(j)-10.0);
3732da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
37333ab0aad5SBarry Smith       ierr  = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr);
3734da9b6338SBarry Smith       ierr  = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr);
373577431f27SBarry Smith       ierr  = PetscPrintf(PETSC_COMM_WORLD,"       j norm %D %18.16e\n",j,norm);CHKERRQ(ierr);
3736da9b6338SBarry Smith       value = -value;
3737da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
3738da9b6338SBarry Smith     }
3739da9b6338SBarry Smith   }
37406bf464f9SBarry Smith   ierr = VecDestroy(&uh);CHKERRQ(ierr);
37416bf464f9SBarry Smith   ierr = VecDestroy(&fh);CHKERRQ(ierr);
3742da9b6338SBarry Smith   PetscFunctionReturn(0);
3743da9b6338SBarry Smith }
374471f87433Sdalcinl 
374571f87433Sdalcinl #undef __FUNCT__
3746fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW"
374771f87433Sdalcinl /*@
3748fa9f3622SBarry Smith    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
374971f87433Sdalcinl    computing relative tolerance for linear solvers within an inexact
375071f87433Sdalcinl    Newton method.
375171f87433Sdalcinl 
37523f9fe445SBarry Smith    Logically Collective on SNES
375371f87433Sdalcinl 
375471f87433Sdalcinl    Input Parameters:
375571f87433Sdalcinl +  snes - SNES context
375671f87433Sdalcinl -  flag - PETSC_TRUE or PETSC_FALSE
375771f87433Sdalcinl 
375864ba62caSBarry Smith     Options Database:
375964ba62caSBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
376064ba62caSBarry Smith .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
376164ba62caSBarry Smith .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
376264ba62caSBarry Smith .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
376364ba62caSBarry Smith .  -snes_ksp_ew_gamma <gamma> - Sets gamma
376464ba62caSBarry Smith .  -snes_ksp_ew_alpha <alpha> - Sets alpha
376564ba62caSBarry Smith .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
376664ba62caSBarry Smith -  -snes_ksp_ew_threshold <threshold> - Sets threshold
376764ba62caSBarry Smith 
376871f87433Sdalcinl    Notes:
376971f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
377071f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
377171f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
377271f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
377371f87433Sdalcinl    solver.
377471f87433Sdalcinl 
377571f87433Sdalcinl    Level: advanced
377671f87433Sdalcinl 
377771f87433Sdalcinl    Reference:
377871f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
377971f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
378071f87433Sdalcinl 
378171f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
378271f87433Sdalcinl 
3783fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
378471f87433Sdalcinl @*/
37857087cfbeSBarry Smith PetscErrorCode  SNESKSPSetUseEW(SNES snes,PetscBool  flag)
378671f87433Sdalcinl {
378771f87433Sdalcinl   PetscFunctionBegin;
37880700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3789acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flag,2);
379071f87433Sdalcinl   snes->ksp_ewconv = flag;
379171f87433Sdalcinl   PetscFunctionReturn(0);
379271f87433Sdalcinl }
379371f87433Sdalcinl 
379471f87433Sdalcinl #undef __FUNCT__
3795fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW"
379671f87433Sdalcinl /*@
3797fa9f3622SBarry Smith    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
379871f87433Sdalcinl    for computing relative tolerance for linear solvers within an
379971f87433Sdalcinl    inexact Newton method.
380071f87433Sdalcinl 
380171f87433Sdalcinl    Not Collective
380271f87433Sdalcinl 
380371f87433Sdalcinl    Input Parameter:
380471f87433Sdalcinl .  snes - SNES context
380571f87433Sdalcinl 
380671f87433Sdalcinl    Output Parameter:
380771f87433Sdalcinl .  flag - PETSC_TRUE or PETSC_FALSE
380871f87433Sdalcinl 
380971f87433Sdalcinl    Notes:
381071f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
381171f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
381271f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
381371f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
381471f87433Sdalcinl    solver.
381571f87433Sdalcinl 
381671f87433Sdalcinl    Level: advanced
381771f87433Sdalcinl 
381871f87433Sdalcinl    Reference:
381971f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
382071f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
382171f87433Sdalcinl 
382271f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
382371f87433Sdalcinl 
3824fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
382571f87433Sdalcinl @*/
38267087cfbeSBarry Smith PetscErrorCode  SNESKSPGetUseEW(SNES snes, PetscBool  *flag)
382771f87433Sdalcinl {
382871f87433Sdalcinl   PetscFunctionBegin;
38290700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
383071f87433Sdalcinl   PetscValidPointer(flag,2);
383171f87433Sdalcinl   *flag = snes->ksp_ewconv;
383271f87433Sdalcinl   PetscFunctionReturn(0);
383371f87433Sdalcinl }
383471f87433Sdalcinl 
383571f87433Sdalcinl #undef __FUNCT__
3836fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW"
383771f87433Sdalcinl /*@
3838fa9f3622SBarry Smith    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
383971f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
384071f87433Sdalcinl    Newton method.
384171f87433Sdalcinl 
38423f9fe445SBarry Smith    Logically Collective on SNES
384371f87433Sdalcinl 
384471f87433Sdalcinl    Input Parameters:
384571f87433Sdalcinl +    snes - SNES context
384671f87433Sdalcinl .    version - version 1, 2 (default is 2) or 3
384771f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
384871f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
384971f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
385071f87433Sdalcinl              (0 <= gamma2 <= 1)
385171f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
385271f87433Sdalcinl .    alpha2 - power for safeguard
385371f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
385471f87433Sdalcinl 
385571f87433Sdalcinl    Note:
385671f87433Sdalcinl    Version 3 was contributed by Luis Chacon, June 2006.
385771f87433Sdalcinl 
385871f87433Sdalcinl    Use PETSC_DEFAULT to retain the default for any of the parameters.
385971f87433Sdalcinl 
386071f87433Sdalcinl    Level: advanced
386171f87433Sdalcinl 
386271f87433Sdalcinl    Reference:
386371f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
386471f87433Sdalcinl    inexact Newton method", Utah State University Math. Stat. Dept. Res.
386571f87433Sdalcinl    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
386671f87433Sdalcinl 
386771f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
386871f87433Sdalcinl 
3869fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
387071f87433Sdalcinl @*/
38717087cfbeSBarry Smith PetscErrorCode  SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,
387271f87433Sdalcinl 							    PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
387371f87433Sdalcinl {
3874fa9f3622SBarry Smith   SNESKSPEW *kctx;
387571f87433Sdalcinl   PetscFunctionBegin;
38760700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3877fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
3878e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
3879c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,version,2);
3880c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_0,3);
3881c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_max,4);
3882c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,gamma,5);
3883c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha,6);
3884c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha2,7);
3885c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,threshold,8);
388671f87433Sdalcinl 
388771f87433Sdalcinl   if (version != PETSC_DEFAULT)   kctx->version   = version;
388871f87433Sdalcinl   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
388971f87433Sdalcinl   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
389071f87433Sdalcinl   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
389171f87433Sdalcinl   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
389271f87433Sdalcinl   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
389371f87433Sdalcinl   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
389471f87433Sdalcinl 
389571f87433Sdalcinl   if (kctx->version < 1 || kctx->version > 3) {
3896e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version);
389771f87433Sdalcinl   }
389871f87433Sdalcinl   if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
3899e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0);
390071f87433Sdalcinl   }
390171f87433Sdalcinl   if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
3902e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max);
390371f87433Sdalcinl   }
390471f87433Sdalcinl   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
3905e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma);
390671f87433Sdalcinl   }
390771f87433Sdalcinl   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
3908e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha);
390971f87433Sdalcinl   }
391071f87433Sdalcinl   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
3911e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold);
391271f87433Sdalcinl   }
391371f87433Sdalcinl   PetscFunctionReturn(0);
391471f87433Sdalcinl }
391571f87433Sdalcinl 
391671f87433Sdalcinl #undef __FUNCT__
3917fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW"
391871f87433Sdalcinl /*@
3919fa9f3622SBarry Smith    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
392071f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
392171f87433Sdalcinl    Newton method.
392271f87433Sdalcinl 
392371f87433Sdalcinl    Not Collective
392471f87433Sdalcinl 
392571f87433Sdalcinl    Input Parameters:
392671f87433Sdalcinl      snes - SNES context
392771f87433Sdalcinl 
392871f87433Sdalcinl    Output Parameters:
392971f87433Sdalcinl +    version - version 1, 2 (default is 2) or 3
393071f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
393171f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
393271f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
393371f87433Sdalcinl              (0 <= gamma2 <= 1)
393471f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
393571f87433Sdalcinl .    alpha2 - power for safeguard
393671f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
393771f87433Sdalcinl 
393871f87433Sdalcinl    Level: advanced
393971f87433Sdalcinl 
394071f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters
394171f87433Sdalcinl 
3942fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
394371f87433Sdalcinl @*/
39447087cfbeSBarry Smith PetscErrorCode  SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,
394571f87433Sdalcinl 							    PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
394671f87433Sdalcinl {
3947fa9f3622SBarry Smith   SNESKSPEW *kctx;
394871f87433Sdalcinl   PetscFunctionBegin;
39490700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3950fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
3951e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
395271f87433Sdalcinl   if(version)   *version   = kctx->version;
395371f87433Sdalcinl   if(rtol_0)    *rtol_0    = kctx->rtol_0;
395471f87433Sdalcinl   if(rtol_max)  *rtol_max  = kctx->rtol_max;
395571f87433Sdalcinl   if(gamma)     *gamma     = kctx->gamma;
395671f87433Sdalcinl   if(alpha)     *alpha     = kctx->alpha;
395771f87433Sdalcinl   if(alpha2)    *alpha2    = kctx->alpha2;
395871f87433Sdalcinl   if(threshold) *threshold = kctx->threshold;
395971f87433Sdalcinl   PetscFunctionReturn(0);
396071f87433Sdalcinl }
396171f87433Sdalcinl 
396271f87433Sdalcinl #undef __FUNCT__
3963fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve"
3964fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x)
396571f87433Sdalcinl {
396671f87433Sdalcinl   PetscErrorCode ierr;
3967fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
396871f87433Sdalcinl   PetscReal      rtol=PETSC_DEFAULT,stol;
396971f87433Sdalcinl 
397071f87433Sdalcinl   PetscFunctionBegin;
3971e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
397271f87433Sdalcinl   if (!snes->iter) { /* first time in, so use the original user rtol */
397371f87433Sdalcinl     rtol = kctx->rtol_0;
397471f87433Sdalcinl   } else {
397571f87433Sdalcinl     if (kctx->version == 1) {
397671f87433Sdalcinl       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
397771f87433Sdalcinl       if (rtol < 0.0) rtol = -rtol;
397871f87433Sdalcinl       stol = pow(kctx->rtol_last,kctx->alpha2);
397971f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
398071f87433Sdalcinl     } else if (kctx->version == 2) {
398171f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
398271f87433Sdalcinl       stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
398371f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
398471f87433Sdalcinl     } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */
398571f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
398671f87433Sdalcinl       /* safeguard: avoid sharp decrease of rtol */
398771f87433Sdalcinl       stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha);
398871f87433Sdalcinl       stol = PetscMax(rtol,stol);
398971f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
399071f87433Sdalcinl       /* safeguard: avoid oversolving */
399171f87433Sdalcinl       stol = kctx->gamma*(snes->ttol)/snes->norm;
399271f87433Sdalcinl       stol = PetscMax(rtol,stol);
399371f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
3994e32f2f54SBarry Smith     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
399571f87433Sdalcinl   }
399671f87433Sdalcinl   /* safeguard: avoid rtol greater than one */
399771f87433Sdalcinl   rtol = PetscMin(rtol,kctx->rtol_max);
399871f87433Sdalcinl   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
399971f87433Sdalcinl   ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr);
400071f87433Sdalcinl   PetscFunctionReturn(0);
400171f87433Sdalcinl }
400271f87433Sdalcinl 
400371f87433Sdalcinl #undef __FUNCT__
4004fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve"
4005fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x)
400671f87433Sdalcinl {
400771f87433Sdalcinl   PetscErrorCode ierr;
4008fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
400971f87433Sdalcinl   PCSide         pcside;
401071f87433Sdalcinl   Vec            lres;
401171f87433Sdalcinl 
401271f87433Sdalcinl   PetscFunctionBegin;
4013e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
401471f87433Sdalcinl   ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr);
401571f87433Sdalcinl   ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr);
401671f87433Sdalcinl   if (kctx->version == 1) {
4017b037da10SBarry Smith     ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr);
401871f87433Sdalcinl     if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
401971f87433Sdalcinl       /* KSP residual is true linear residual */
402071f87433Sdalcinl       ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr);
402171f87433Sdalcinl     } else {
402271f87433Sdalcinl       /* KSP residual is preconditioned residual */
402371f87433Sdalcinl       /* compute true linear residual norm */
402471f87433Sdalcinl       ierr = VecDuplicate(b,&lres);CHKERRQ(ierr);
402571f87433Sdalcinl       ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr);
402671f87433Sdalcinl       ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr);
402771f87433Sdalcinl       ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr);
40286bf464f9SBarry Smith       ierr = VecDestroy(&lres);CHKERRQ(ierr);
402971f87433Sdalcinl     }
403071f87433Sdalcinl   }
403171f87433Sdalcinl   PetscFunctionReturn(0);
403271f87433Sdalcinl }
403371f87433Sdalcinl 
403471f87433Sdalcinl #undef __FUNCT__
403571f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve"
403671f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x)
403771f87433Sdalcinl {
403871f87433Sdalcinl   PetscErrorCode ierr;
403971f87433Sdalcinl 
404071f87433Sdalcinl   PetscFunctionBegin;
4041fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr);  }
404271f87433Sdalcinl   ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr);
4043fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); }
404471f87433Sdalcinl   PetscFunctionReturn(0);
404571f87433Sdalcinl }
40466c699258SBarry Smith 
40476c699258SBarry Smith #undef __FUNCT__
40486c699258SBarry Smith #define __FUNCT__ "SNESSetDM"
40496c699258SBarry Smith /*@
40506c699258SBarry Smith    SNESSetDM - Sets the DM that may be used by some preconditioners
40516c699258SBarry Smith 
40523f9fe445SBarry Smith    Logically Collective on SNES
40536c699258SBarry Smith 
40546c699258SBarry Smith    Input Parameters:
40556c699258SBarry Smith +  snes - the preconditioner context
40566c699258SBarry Smith -  dm - the dm
40576c699258SBarry Smith 
40586c699258SBarry Smith    Level: intermediate
40596c699258SBarry Smith 
40606c699258SBarry Smith 
40616c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM()
40626c699258SBarry Smith @*/
40637087cfbeSBarry Smith PetscErrorCode  SNESSetDM(SNES snes,DM dm)
40646c699258SBarry Smith {
40656c699258SBarry Smith   PetscErrorCode ierr;
4066345fed2cSBarry Smith   KSP            ksp;
40676cab3a1bSJed Brown   SNESDM         sdm;
40686c699258SBarry Smith 
40696c699258SBarry Smith   PetscFunctionBegin;
40700700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4071d0660788SBarry Smith   if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);}
40726cab3a1bSJed Brown   if (snes->dm) {               /* Move the SNESDM context over to the new DM unless the new DM already has one */
40736cab3a1bSJed Brown     PetscContainer oldcontainer,container;
40746cab3a1bSJed Brown     ierr = PetscObjectQuery((PetscObject)snes->dm,"SNESDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr);
40756cab3a1bSJed Brown     ierr = PetscObjectQuery((PetscObject)dm,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr);
40766cab3a1bSJed Brown     if (oldcontainer && !container) {
40776cab3a1bSJed Brown       ierr = DMSNESCopyContext(snes->dm,dm);CHKERRQ(ierr);
40786cab3a1bSJed Brown       ierr = DMSNESGetContext(snes->dm,&sdm);CHKERRQ(ierr);
40796cab3a1bSJed Brown       if (sdm->originaldm == snes->dm) { /* Grant write privileges to the replacement DM */
40806cab3a1bSJed Brown         sdm->originaldm = dm;
40816cab3a1bSJed Brown       }
40826cab3a1bSJed Brown     }
40836bf464f9SBarry Smith     ierr = DMDestroy(&snes->dm);CHKERRQ(ierr);
40846cab3a1bSJed Brown   }
40856c699258SBarry Smith   snes->dm = dm;
4086345fed2cSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
4087345fed2cSBarry Smith   ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr);
4088f22f69f0SBarry Smith   ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr);
40892c155ee1SBarry Smith   if (snes->pc) {
40902c155ee1SBarry Smith     ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr);
40912c155ee1SBarry Smith   }
40926c699258SBarry Smith   PetscFunctionReturn(0);
40936c699258SBarry Smith }
40946c699258SBarry Smith 
40956c699258SBarry Smith #undef __FUNCT__
40966c699258SBarry Smith #define __FUNCT__ "SNESGetDM"
40976c699258SBarry Smith /*@
40986c699258SBarry Smith    SNESGetDM - Gets the DM that may be used by some preconditioners
40996c699258SBarry Smith 
41003f9fe445SBarry Smith    Not Collective but DM obtained is parallel on SNES
41016c699258SBarry Smith 
41026c699258SBarry Smith    Input Parameter:
41036c699258SBarry Smith . snes - the preconditioner context
41046c699258SBarry Smith 
41056c699258SBarry Smith    Output Parameter:
41066c699258SBarry Smith .  dm - the dm
41076c699258SBarry Smith 
41086c699258SBarry Smith    Level: intermediate
41096c699258SBarry Smith 
41106c699258SBarry Smith 
41116c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM()
41126c699258SBarry Smith @*/
41137087cfbeSBarry Smith PetscErrorCode  SNESGetDM(SNES snes,DM *dm)
41146c699258SBarry Smith {
41156cab3a1bSJed Brown   PetscErrorCode ierr;
41166cab3a1bSJed Brown 
41176c699258SBarry Smith   PetscFunctionBegin;
41180700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
41196cab3a1bSJed Brown   if (!snes->dm) {
41206cab3a1bSJed Brown     ierr = DMShellCreate(((PetscObject)snes)->comm,&snes->dm);CHKERRQ(ierr);
41216cab3a1bSJed Brown   }
41226c699258SBarry Smith   *dm = snes->dm;
41236c699258SBarry Smith   PetscFunctionReturn(0);
41246c699258SBarry Smith }
41250807856dSBarry Smith 
412631823bd8SMatthew G Knepley #undef __FUNCT__
412731823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC"
412831823bd8SMatthew G Knepley /*@
4129fd4b34e9SJed Brown   SNESSetPC - Sets the nonlinear preconditioner to be used.
413031823bd8SMatthew G Knepley 
413131823bd8SMatthew G Knepley   Collective on SNES
413231823bd8SMatthew G Knepley 
413331823bd8SMatthew G Knepley   Input Parameters:
413431823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate()
413531823bd8SMatthew G Knepley - pc   - the preconditioner object
413631823bd8SMatthew G Knepley 
413731823bd8SMatthew G Knepley   Notes:
413831823bd8SMatthew G Knepley   Use SNESGetPC() to retrieve the preconditioner context (for example,
413931823bd8SMatthew G Knepley   to configure it using the API).
414031823bd8SMatthew G Knepley 
414131823bd8SMatthew G Knepley   Level: developer
414231823bd8SMatthew G Knepley 
414331823bd8SMatthew G Knepley .keywords: SNES, set, precondition
414431823bd8SMatthew G Knepley .seealso: SNESGetPC()
414531823bd8SMatthew G Knepley @*/
414631823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc)
414731823bd8SMatthew G Knepley {
414831823bd8SMatthew G Knepley   PetscErrorCode ierr;
414931823bd8SMatthew G Knepley 
415031823bd8SMatthew G Knepley   PetscFunctionBegin;
415131823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
415231823bd8SMatthew G Knepley   PetscValidHeaderSpecific(pc, SNES_CLASSID, 2);
415331823bd8SMatthew G Knepley   PetscCheckSameComm(snes, 1, pc, 2);
415431823bd8SMatthew G Knepley   ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr);
4155bf11d3b6SBarry Smith   ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr);
415631823bd8SMatthew G Knepley   snes->pc = pc;
415731823bd8SMatthew G Knepley   ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr);
415831823bd8SMatthew G Knepley   PetscFunctionReturn(0);
415931823bd8SMatthew G Knepley }
416031823bd8SMatthew G Knepley 
416131823bd8SMatthew G Knepley #undef __FUNCT__
416231823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC"
416331823bd8SMatthew G Knepley /*@
4164fd4b34e9SJed Brown   SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC().
416531823bd8SMatthew G Knepley 
416631823bd8SMatthew G Knepley   Not Collective
416731823bd8SMatthew G Knepley 
416831823bd8SMatthew G Knepley   Input Parameter:
416931823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate()
417031823bd8SMatthew G Knepley 
417131823bd8SMatthew G Knepley   Output Parameter:
417231823bd8SMatthew G Knepley . pc - preconditioner context
417331823bd8SMatthew G Knepley 
417431823bd8SMatthew G Knepley   Level: developer
417531823bd8SMatthew G Knepley 
417631823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner
417731823bd8SMatthew G Knepley .seealso: SNESSetPC()
417831823bd8SMatthew G Knepley @*/
417931823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc)
418031823bd8SMatthew G Knepley {
418131823bd8SMatthew G Knepley   PetscErrorCode ierr;
418231823bd8SMatthew G Knepley 
418331823bd8SMatthew G Knepley   PetscFunctionBegin;
418431823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
418531823bd8SMatthew G Knepley   PetscValidPointer(pc, 2);
418631823bd8SMatthew G Knepley   if (!snes->pc) {
418731823bd8SMatthew G Knepley     ierr = SNESCreate(((PetscObject) snes)->comm, &snes->pc);CHKERRQ(ierr);
41884a0c5b0cSMatthew G Knepley     ierr = PetscObjectIncrementTabLevel((PetscObject) snes->pc, (PetscObject) snes, 1);CHKERRQ(ierr);
418931823bd8SMatthew G Knepley     ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr);
419031823bd8SMatthew G Knepley   }
419131823bd8SMatthew G Knepley   *pc = snes->pc;
419231823bd8SMatthew G Knepley   PetscFunctionReturn(0);
419331823bd8SMatthew G Knepley }
419431823bd8SMatthew G Knepley 
419569b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
4196c6db04a5SJed Brown #include <mex.h>
419769b4f73cSBarry Smith 
41988f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext;
41998f6e6473SBarry Smith 
42000807856dSBarry Smith #undef __FUNCT__
42010807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab"
42020807856dSBarry Smith /*
42030807856dSBarry Smith    SNESComputeFunction_Matlab - Calls the function that has been set with
42040807856dSBarry Smith                          SNESSetFunctionMatlab().
42050807856dSBarry Smith 
42060807856dSBarry Smith    Collective on SNES
42070807856dSBarry Smith 
42080807856dSBarry Smith    Input Parameters:
42090807856dSBarry Smith +  snes - the SNES context
42100807856dSBarry Smith -  x - input vector
42110807856dSBarry Smith 
42120807856dSBarry Smith    Output Parameter:
42130807856dSBarry Smith .  y - function vector, as set by SNESSetFunction()
42140807856dSBarry Smith 
42150807856dSBarry Smith    Notes:
42160807856dSBarry Smith    SNESComputeFunction() is typically used within nonlinear solvers
42170807856dSBarry Smith    implementations, so most users would not generally call this routine
42180807856dSBarry Smith    themselves.
42190807856dSBarry Smith 
42200807856dSBarry Smith    Level: developer
42210807856dSBarry Smith 
42220807856dSBarry Smith .keywords: SNES, nonlinear, compute, function
42230807856dSBarry Smith 
42240807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
422561b2408cSBarry Smith */
42267087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx)
42270807856dSBarry Smith {
4228e650e774SBarry Smith   PetscErrorCode    ierr;
42298f6e6473SBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
42308f6e6473SBarry Smith   int               nlhs = 1,nrhs = 5;
42318f6e6473SBarry Smith   mxArray	    *plhs[1],*prhs[5];
423291621f2eSBarry Smith   long long int     lx = 0,ly = 0,ls = 0;
4233e650e774SBarry Smith 
42340807856dSBarry Smith   PetscFunctionBegin;
42350807856dSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
42360807856dSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
42370807856dSBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
42380807856dSBarry Smith   PetscCheckSameComm(snes,1,x,2);
42390807856dSBarry Smith   PetscCheckSameComm(snes,1,y,3);
42400807856dSBarry Smith 
42410807856dSBarry Smith   /* call Matlab function in ctx with arguments x and y */
4242e650e774SBarry Smith 
424391621f2eSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4244e650e774SBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4245e650e774SBarry Smith   ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr);
424691621f2eSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
424791621f2eSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
424891621f2eSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)ly);
42498f6e6473SBarry Smith   prhs[3] =  mxCreateString(sctx->funcname);
42508f6e6473SBarry Smith   prhs[4] =  sctx->ctx;
4251b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr);
4252e650e774SBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4253e650e774SBarry Smith   mxDestroyArray(prhs[0]);
4254e650e774SBarry Smith   mxDestroyArray(prhs[1]);
4255e650e774SBarry Smith   mxDestroyArray(prhs[2]);
42568f6e6473SBarry Smith   mxDestroyArray(prhs[3]);
4257e650e774SBarry Smith   mxDestroyArray(plhs[0]);
42580807856dSBarry Smith   PetscFunctionReturn(0);
42590807856dSBarry Smith }
42600807856dSBarry Smith 
42610807856dSBarry Smith 
42620807856dSBarry Smith #undef __FUNCT__
42630807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab"
426461b2408cSBarry Smith /*
42650807856dSBarry Smith    SNESSetFunctionMatlab - Sets the function evaluation routine and function
42660807856dSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4267e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
42680807856dSBarry Smith 
42690807856dSBarry Smith    Logically Collective on SNES
42700807856dSBarry Smith 
42710807856dSBarry Smith    Input Parameters:
42720807856dSBarry Smith +  snes - the SNES context
42730807856dSBarry Smith .  r - vector to store function value
42740807856dSBarry Smith -  func - function evaluation routine
42750807856dSBarry Smith 
42760807856dSBarry Smith    Calling sequence of func:
427761b2408cSBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
42780807856dSBarry Smith 
42790807856dSBarry Smith 
42800807856dSBarry Smith    Notes:
42810807856dSBarry Smith    The Newton-like methods typically solve linear systems of the form
42820807856dSBarry Smith $      f'(x) x = -f(x),
42830807856dSBarry Smith    where f'(x) denotes the Jacobian matrix and f(x) is the function.
42840807856dSBarry Smith 
42850807856dSBarry Smith    Level: beginner
42860807856dSBarry Smith 
42870807856dSBarry Smith .keywords: SNES, nonlinear, set, function
42880807856dSBarry Smith 
42890807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
429061b2408cSBarry Smith */
42917087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx)
42920807856dSBarry Smith {
42930807856dSBarry Smith   PetscErrorCode    ierr;
42948f6e6473SBarry Smith   SNESMatlabContext *sctx;
42950807856dSBarry Smith 
42960807856dSBarry Smith   PetscFunctionBegin;
42978f6e6473SBarry Smith   /* currently sctx is memory bleed */
42988f6e6473SBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
42998f6e6473SBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
43008f6e6473SBarry Smith   /*
43018f6e6473SBarry Smith      This should work, but it doesn't
43028f6e6473SBarry Smith   sctx->ctx = ctx;
43038f6e6473SBarry Smith   mexMakeArrayPersistent(sctx->ctx);
43048f6e6473SBarry Smith   */
43058f6e6473SBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
43068f6e6473SBarry Smith   ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr);
43070807856dSBarry Smith   PetscFunctionReturn(0);
43080807856dSBarry Smith }
430969b4f73cSBarry Smith 
431061b2408cSBarry Smith #undef __FUNCT__
431161b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab"
431261b2408cSBarry Smith /*
431361b2408cSBarry Smith    SNESComputeJacobian_Matlab - Calls the function that has been set with
431461b2408cSBarry Smith                          SNESSetJacobianMatlab().
431561b2408cSBarry Smith 
431661b2408cSBarry Smith    Collective on SNES
431761b2408cSBarry Smith 
431861b2408cSBarry Smith    Input Parameters:
431961b2408cSBarry Smith +  snes - the SNES context
432061b2408cSBarry Smith .  x - input vector
432161b2408cSBarry Smith .  A, B - the matrices
432261b2408cSBarry Smith -  ctx - user context
432361b2408cSBarry Smith 
432461b2408cSBarry Smith    Output Parameter:
432561b2408cSBarry Smith .  flag - structure of the matrix
432661b2408cSBarry Smith 
432761b2408cSBarry Smith    Level: developer
432861b2408cSBarry Smith 
432961b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function
433061b2408cSBarry Smith 
433161b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
433261b2408cSBarry Smith @*/
43337087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx)
433461b2408cSBarry Smith {
433561b2408cSBarry Smith   PetscErrorCode    ierr;
433661b2408cSBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
433761b2408cSBarry Smith   int               nlhs = 2,nrhs = 6;
433861b2408cSBarry Smith   mxArray	    *plhs[2],*prhs[6];
433961b2408cSBarry Smith   long long int     lx = 0,lA = 0,ls = 0, lB = 0;
434061b2408cSBarry Smith 
434161b2408cSBarry Smith   PetscFunctionBegin;
434261b2408cSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
434361b2408cSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
434461b2408cSBarry Smith 
434561b2408cSBarry Smith   /* call Matlab function in ctx with arguments x and y */
434661b2408cSBarry Smith 
434761b2408cSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
434861b2408cSBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
434961b2408cSBarry Smith   ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr);
435061b2408cSBarry Smith   ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr);
435161b2408cSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
435261b2408cSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
435361b2408cSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)lA);
435461b2408cSBarry Smith   prhs[3] =  mxCreateDoubleScalar((double)lB);
435561b2408cSBarry Smith   prhs[4] =  mxCreateString(sctx->funcname);
435661b2408cSBarry Smith   prhs[5] =  sctx->ctx;
4357b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr);
435861b2408cSBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
435961b2408cSBarry Smith   *flag   =  (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr);
436061b2408cSBarry Smith   mxDestroyArray(prhs[0]);
436161b2408cSBarry Smith   mxDestroyArray(prhs[1]);
436261b2408cSBarry Smith   mxDestroyArray(prhs[2]);
436361b2408cSBarry Smith   mxDestroyArray(prhs[3]);
436461b2408cSBarry Smith   mxDestroyArray(prhs[4]);
436561b2408cSBarry Smith   mxDestroyArray(plhs[0]);
436661b2408cSBarry Smith   mxDestroyArray(plhs[1]);
436761b2408cSBarry Smith   PetscFunctionReturn(0);
436861b2408cSBarry Smith }
436961b2408cSBarry Smith 
437061b2408cSBarry Smith 
437161b2408cSBarry Smith #undef __FUNCT__
437261b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab"
437361b2408cSBarry Smith /*
437461b2408cSBarry Smith    SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
437561b2408cSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4376e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
437761b2408cSBarry Smith 
437861b2408cSBarry Smith    Logically Collective on SNES
437961b2408cSBarry Smith 
438061b2408cSBarry Smith    Input Parameters:
438161b2408cSBarry Smith +  snes - the SNES context
438261b2408cSBarry Smith .  A,B - Jacobian matrices
438361b2408cSBarry Smith .  func - function evaluation routine
438461b2408cSBarry Smith -  ctx - user context
438561b2408cSBarry Smith 
438661b2408cSBarry Smith    Calling sequence of func:
438761b2408cSBarry Smith $    flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx);
438861b2408cSBarry Smith 
438961b2408cSBarry Smith 
439061b2408cSBarry Smith    Level: developer
439161b2408cSBarry Smith 
439261b2408cSBarry Smith .keywords: SNES, nonlinear, set, function
439361b2408cSBarry Smith 
439461b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
439561b2408cSBarry Smith */
43967087cfbeSBarry Smith PetscErrorCode  SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx)
439761b2408cSBarry Smith {
439861b2408cSBarry Smith   PetscErrorCode    ierr;
439961b2408cSBarry Smith   SNESMatlabContext *sctx;
440061b2408cSBarry Smith 
440161b2408cSBarry Smith   PetscFunctionBegin;
440261b2408cSBarry Smith   /* currently sctx is memory bleed */
440361b2408cSBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
440461b2408cSBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
440561b2408cSBarry Smith   /*
440661b2408cSBarry Smith      This should work, but it doesn't
440761b2408cSBarry Smith   sctx->ctx = ctx;
440861b2408cSBarry Smith   mexMakeArrayPersistent(sctx->ctx);
440961b2408cSBarry Smith   */
441061b2408cSBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
441161b2408cSBarry Smith   ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
441261b2408cSBarry Smith   PetscFunctionReturn(0);
441361b2408cSBarry Smith }
441469b4f73cSBarry Smith 
4415f9eb7ae2SShri Abhyankar #undef __FUNCT__
4416f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab"
4417f9eb7ae2SShri Abhyankar /*
4418f9eb7ae2SShri Abhyankar    SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab().
4419f9eb7ae2SShri Abhyankar 
4420f9eb7ae2SShri Abhyankar    Collective on SNES
4421f9eb7ae2SShri Abhyankar 
4422f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction()
4423f9eb7ae2SShri Abhyankar @*/
44247087cfbeSBarry Smith PetscErrorCode  SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx)
4425f9eb7ae2SShri Abhyankar {
4426f9eb7ae2SShri Abhyankar   PetscErrorCode  ierr;
442748f37e70SShri Abhyankar   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
4428f9eb7ae2SShri Abhyankar   int             nlhs = 1,nrhs = 6;
4429f9eb7ae2SShri Abhyankar   mxArray	  *plhs[1],*prhs[6];
4430f9eb7ae2SShri Abhyankar   long long int   lx = 0,ls = 0;
4431f9eb7ae2SShri Abhyankar   Vec             x=snes->vec_sol;
4432f9eb7ae2SShri Abhyankar 
4433f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4434f9eb7ae2SShri Abhyankar   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4435f9eb7ae2SShri Abhyankar 
4436f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4437f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4438f9eb7ae2SShri Abhyankar   prhs[0] =  mxCreateDoubleScalar((double)ls);
4439f9eb7ae2SShri Abhyankar   prhs[1] =  mxCreateDoubleScalar((double)it);
4440f9eb7ae2SShri Abhyankar   prhs[2] =  mxCreateDoubleScalar((double)fnorm);
4441f9eb7ae2SShri Abhyankar   prhs[3] =  mxCreateDoubleScalar((double)lx);
4442f9eb7ae2SShri Abhyankar   prhs[4] =  mxCreateString(sctx->funcname);
4443f9eb7ae2SShri Abhyankar   prhs[5] =  sctx->ctx;
4444f9eb7ae2SShri Abhyankar   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr);
4445f9eb7ae2SShri Abhyankar   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4446f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[0]);
4447f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[1]);
4448f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[2]);
4449f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[3]);
4450f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[4]);
4451f9eb7ae2SShri Abhyankar   mxDestroyArray(plhs[0]);
4452f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
4453f9eb7ae2SShri Abhyankar }
4454f9eb7ae2SShri Abhyankar 
4455f9eb7ae2SShri Abhyankar 
4456f9eb7ae2SShri Abhyankar #undef __FUNCT__
4457f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab"
4458f9eb7ae2SShri Abhyankar /*
4459e3c5b3baSBarry Smith    SNESMonitorSetMatlab - Sets the monitor function from MATLAB
4460f9eb7ae2SShri Abhyankar 
4461f9eb7ae2SShri Abhyankar    Level: developer
4462f9eb7ae2SShri Abhyankar 
4463f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function
4464f9eb7ae2SShri Abhyankar 
4465f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
4466f9eb7ae2SShri Abhyankar */
44677087cfbeSBarry Smith PetscErrorCode  SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx)
4468f9eb7ae2SShri Abhyankar {
4469f9eb7ae2SShri Abhyankar   PetscErrorCode    ierr;
4470f9eb7ae2SShri Abhyankar   SNESMatlabContext *sctx;
4471f9eb7ae2SShri Abhyankar 
4472f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4473f9eb7ae2SShri Abhyankar   /* currently sctx is memory bleed */
4474f9eb7ae2SShri Abhyankar   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
4475f9eb7ae2SShri Abhyankar   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
4476f9eb7ae2SShri Abhyankar   /*
4477f9eb7ae2SShri Abhyankar      This should work, but it doesn't
4478f9eb7ae2SShri Abhyankar   sctx->ctx = ctx;
4479f9eb7ae2SShri Abhyankar   mexMakeArrayPersistent(sctx->ctx);
4480f9eb7ae2SShri Abhyankar   */
4481f9eb7ae2SShri Abhyankar   sctx->ctx = mxDuplicateArray(ctx);
4482f9eb7ae2SShri Abhyankar   ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr);
4483f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
4484f9eb7ae2SShri Abhyankar }
4485f9eb7ae2SShri Abhyankar 
448669b4f73cSBarry Smith #endif
4487