xref: /petsc/src/snes/interface/snes.c (revision 6cab3a1b8d4fca83e1d7b61474c608460de73d5f)
19b94acceSBarry Smith 
2c6db04a5SJed Brown #include <private/snesimpl.h>      /*I "petscsnes.h"  I*/
3*6cab3a1bSJed 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:
994936397dSBarry Smith .  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 
1154936397dSBarry Smith #undef __FUNCT__
1164a2ae208SSatish Balay #define __FUNCT__ "SNESView"
1177e2c5f70SBarry Smith /*@C
1189b94acceSBarry Smith    SNESView - Prints the SNES data structure.
1199b94acceSBarry Smith 
1204c49b128SBarry Smith    Collective on SNES
121fee21e36SBarry Smith 
122c7afd0dbSLois Curfman McInnes    Input Parameters:
123c7afd0dbSLois Curfman McInnes +  SNES - the SNES context
124c7afd0dbSLois Curfman McInnes -  viewer - visualization context
125c7afd0dbSLois Curfman McInnes 
1269b94acceSBarry Smith    Options Database Key:
127c8a8ba5cSLois Curfman McInnes .  -snes_view - Calls SNESView() at end of SNESSolve()
1289b94acceSBarry Smith 
1299b94acceSBarry Smith    Notes:
1309b94acceSBarry Smith    The available visualization contexts include
131b0a32e0cSBarry Smith +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
132b0a32e0cSBarry Smith -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
133c8a8ba5cSLois Curfman McInnes          output where only the first processor opens
134c8a8ba5cSLois Curfman McInnes          the file.  All other processors send their
135c8a8ba5cSLois Curfman McInnes          data to the first processor to print.
1369b94acceSBarry Smith 
1373e081fefSLois Curfman McInnes    The user can open an alternative visualization context with
138b0a32e0cSBarry Smith    PetscViewerASCIIOpen() - output to a specified file.
1399b94acceSBarry Smith 
14036851e7fSLois Curfman McInnes    Level: beginner
14136851e7fSLois Curfman McInnes 
1429b94acceSBarry Smith .keywords: SNES, view
1439b94acceSBarry Smith 
144b0a32e0cSBarry Smith .seealso: PetscViewerASCIIOpen()
1459b94acceSBarry Smith @*/
1467087cfbeSBarry Smith PetscErrorCode  SNESView(SNES snes,PetscViewer viewer)
1479b94acceSBarry Smith {
148fa9f3622SBarry Smith   SNESKSPEW           *kctx;
149dfbe8321SBarry Smith   PetscErrorCode      ierr;
15094b7f48cSBarry Smith   KSP                 ksp;
151ace3abfcSBarry Smith   PetscBool           iascii,isstring;
1529b94acceSBarry Smith 
1533a40ed3dSBarry Smith   PetscFunctionBegin;
1540700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1553050cee2SBarry Smith   if (!viewer) {
1567adad957SLisandro Dalcin     ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr);
1573050cee2SBarry Smith   }
1580700a824SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
159c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,viewer,2);
16074679c65SBarry Smith 
1612692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1622692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr);
16332077d6dSBarry Smith   if (iascii) {
164317d6ea6SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer,"SNES Object");CHKERRQ(ierr);
165e7788613SBarry Smith     if (snes->ops->view) {
166b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
167e7788613SBarry Smith       ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr);
168b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1690ef38995SBarry Smith     }
17077431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);CHKERRQ(ierr);
171a83599f4SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  tolerances: relative=%G, absolute=%G, solution=%G\n",
17270441072SBarry Smith                  snes->rtol,snes->abstol,snes->xtol);CHKERRQ(ierr);
17377431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr);
17477431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr);
1759b94acceSBarry Smith     if (snes->ksp_ewconv) {
176fa9f3622SBarry Smith       kctx = (SNESKSPEW *)snes->kspconvctx;
1779b94acceSBarry Smith       if (kctx) {
17877431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"  Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr);
179a83599f4SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    rtol_0=%G, rtol_max=%G, threshold=%G\n",kctx->rtol_0,kctx->rtol_max,kctx->threshold);CHKERRQ(ierr);
180a83599f4SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    gamma=%G, alpha=%G, alpha2=%G\n",kctx->gamma,kctx->alpha,kctx->alpha2);CHKERRQ(ierr);
1819b94acceSBarry Smith       }
1829b94acceSBarry Smith     }
183eb1f6c34SBarry Smith     if (snes->lagpreconditioner == -1) {
184eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is never rebuilt\n");CHKERRQ(ierr);
185eb1f6c34SBarry Smith     } else if (snes->lagpreconditioner > 1) {
186eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr);
187eb1f6c34SBarry Smith     }
188eb1f6c34SBarry Smith     if (snes->lagjacobian == -1) {
189eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is never rebuilt\n");CHKERRQ(ierr);
190eb1f6c34SBarry Smith     } else if (snes->lagjacobian > 1) {
19142f4f86dSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian);CHKERRQ(ierr);
192eb1f6c34SBarry Smith     }
1930f5bd95cSBarry Smith   } else if (isstring) {
194317d6ea6SBarry Smith     const char *type;
195454a90a3SBarry Smith     ierr = SNESGetType(snes,&type);CHKERRQ(ierr);
196b0a32e0cSBarry Smith     ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr);
19719bcc07fSBarry Smith   }
19842f4f86dSBarry Smith   if (snes->pc && snes->usespc) {
1994a0c5b0cSMatthew G Knepley     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
2004a0c5b0cSMatthew G Knepley     ierr = SNESView(snes->pc, viewer);CHKERRQ(ierr);
2014a0c5b0cSMatthew G Knepley     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2024a0c5b0cSMatthew G Knepley   }
2032c155ee1SBarry Smith   if (snes->usesksp) {
2042c155ee1SBarry Smith     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
205b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
20694b7f48cSBarry Smith     ierr = KSPView(ksp,viewer);CHKERRQ(ierr);
207b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2082c155ee1SBarry Smith   }
2093a40ed3dSBarry Smith   PetscFunctionReturn(0);
2109b94acceSBarry Smith }
2119b94acceSBarry Smith 
21276b2cf59SMatthew Knepley /*
21376b2cf59SMatthew Knepley   We retain a list of functions that also take SNES command
21476b2cf59SMatthew Knepley   line options. These are called at the end SNESSetFromOptions()
21576b2cf59SMatthew Knepley */
21676b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5
217a7cc72afSBarry Smith static PetscInt numberofsetfromoptions;
2186849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES);
21976b2cf59SMatthew Knepley 
220e74ef692SMatthew Knepley #undef __FUNCT__
221e74ef692SMatthew Knepley #define __FUNCT__ "SNESAddOptionsChecker"
222ac226902SBarry Smith /*@C
22376b2cf59SMatthew Knepley   SNESAddOptionsChecker - Adds an additional function to check for SNES options.
22476b2cf59SMatthew Knepley 
22576b2cf59SMatthew Knepley   Not Collective
22676b2cf59SMatthew Knepley 
22776b2cf59SMatthew Knepley   Input Parameter:
22876b2cf59SMatthew Knepley . snescheck - function that checks for options
22976b2cf59SMatthew Knepley 
23076b2cf59SMatthew Knepley   Level: developer
23176b2cf59SMatthew Knepley 
23276b2cf59SMatthew Knepley .seealso: SNESSetFromOptions()
23376b2cf59SMatthew Knepley @*/
2347087cfbeSBarry Smith PetscErrorCode  SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES))
23576b2cf59SMatthew Knepley {
23676b2cf59SMatthew Knepley   PetscFunctionBegin;
23776b2cf59SMatthew Knepley   if (numberofsetfromoptions >= MAXSETFROMOPTIONS) {
238e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS);
23976b2cf59SMatthew Knepley   }
24076b2cf59SMatthew Knepley   othersetfromoptions[numberofsetfromoptions++] = snescheck;
24176b2cf59SMatthew Knepley   PetscFunctionReturn(0);
24276b2cf59SMatthew Knepley }
24376b2cf59SMatthew Knepley 
2447087cfbeSBarry Smith extern PetscErrorCode  SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*);
245aa3661deSLisandro Dalcin 
246aa3661deSLisandro Dalcin #undef __FUNCT__
247aa3661deSLisandro Dalcin #define __FUNCT__ "SNESSetUpMatrixFree_Private"
248ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool  hasOperator, PetscInt version)
249aa3661deSLisandro Dalcin {
250aa3661deSLisandro Dalcin   Mat            J;
251aa3661deSLisandro Dalcin   KSP            ksp;
252aa3661deSLisandro Dalcin   PC             pc;
253ace3abfcSBarry Smith   PetscBool      match;
254aa3661deSLisandro Dalcin   PetscErrorCode ierr;
255aa3661deSLisandro Dalcin 
256aa3661deSLisandro Dalcin   PetscFunctionBegin;
2570700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
258aa3661deSLisandro Dalcin 
25998613b67SLisandro Dalcin   if(!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) {
26098613b67SLisandro Dalcin     Mat A = snes->jacobian, B = snes->jacobian_pre;
26198613b67SLisandro Dalcin     ierr = MatGetVecs(A ? A : B, PETSC_NULL,&snes->vec_func);CHKERRQ(ierr);
26298613b67SLisandro Dalcin   }
26398613b67SLisandro Dalcin 
264aa3661deSLisandro Dalcin   if (version == 1) {
265aa3661deSLisandro Dalcin     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
26698613b67SLisandro Dalcin     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
2679c6ac3b3SBarry Smith     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
268aa3661deSLisandro Dalcin   } else if (version == 2) {
269e32f2f54SBarry Smith     if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first");
27082a7e548SBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
271aa3661deSLisandro Dalcin     ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr);
272aa3661deSLisandro Dalcin #else
273e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)");
274aa3661deSLisandro Dalcin #endif
275a8248277SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2");
276aa3661deSLisandro Dalcin 
277aa3661deSLisandro Dalcin   ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr);
278d3462f78SMatthew Knepley   if (hasOperator) {
279aa3661deSLisandro Dalcin     /* This version replaces the user provided Jacobian matrix with a
280aa3661deSLisandro Dalcin        matrix-free version but still employs the user-provided preconditioner matrix. */
281aa3661deSLisandro Dalcin     ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr);
282aa3661deSLisandro Dalcin   } else {
283aa3661deSLisandro Dalcin     /* This version replaces both the user-provided Jacobian and the user-
284aa3661deSLisandro Dalcin        provided preconditioner matrix with the default matrix free version. */
285*6cab3a1bSJed Brown     void *functx;
286*6cab3a1bSJed Brown     ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
287*6cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr);
288aa3661deSLisandro Dalcin     /* Force no preconditioner */
289aa3661deSLisandro Dalcin     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
290aa3661deSLisandro Dalcin     ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr);
291aa3661deSLisandro Dalcin     ierr = PetscTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr);
292aa3661deSLisandro Dalcin     if (!match) {
293aa3661deSLisandro Dalcin       ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr);
294aa3661deSLisandro Dalcin       ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr);
295aa3661deSLisandro Dalcin     }
296aa3661deSLisandro Dalcin   }
2976bf464f9SBarry Smith   ierr = MatDestroy(&J);CHKERRQ(ierr);
298aa3661deSLisandro Dalcin   PetscFunctionReturn(0);
299aa3661deSLisandro Dalcin }
300aa3661deSLisandro Dalcin 
3014a2ae208SSatish Balay #undef __FUNCT__
302*6cab3a1bSJed Brown #define __FUNCT__ "SNESSetUpMatrices"
303*6cab3a1bSJed Brown /*@
304*6cab3a1bSJed Brown    SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX()
305*6cab3a1bSJed Brown 
306*6cab3a1bSJed Brown    Collective
307*6cab3a1bSJed Brown 
308*6cab3a1bSJed Brown    Input Arguments:
309*6cab3a1bSJed Brown .  snes - snes to configure
310*6cab3a1bSJed Brown 
311*6cab3a1bSJed Brown    Level: developer
312*6cab3a1bSJed Brown 
313*6cab3a1bSJed Brown .seealso: SNESSetUp()
314*6cab3a1bSJed Brown @*/
315*6cab3a1bSJed Brown PetscErrorCode SNESSetUpMatrices(SNES snes)
316*6cab3a1bSJed Brown {
317*6cab3a1bSJed Brown   PetscErrorCode ierr;
318*6cab3a1bSJed Brown   DM             dm;
319*6cab3a1bSJed Brown   SNESDM         sdm;
320*6cab3a1bSJed Brown 
321*6cab3a1bSJed Brown   PetscFunctionBegin;
322*6cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
323*6cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
324*6cab3a1bSJed Brown   if (!sdm->computejacobian && snes->dm) {
325*6cab3a1bSJed Brown     Mat J,B;
326*6cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
327*6cab3a1bSJed Brown     if (snes->mf_operator) {
328*6cab3a1bSJed Brown       ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
329*6cab3a1bSJed Brown       ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
330*6cab3a1bSJed Brown       ierr = MatSetFromOptions(J);CHKERRQ(ierr);
331*6cab3a1bSJed Brown     } else {
332*6cab3a1bSJed Brown       J = B;
333*6cab3a1bSJed Brown       ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
334*6cab3a1bSJed Brown     }
335*6cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,PETSC_NULL);CHKERRQ(ierr);
336*6cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
337*6cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
338*6cab3a1bSJed Brown   } else if (!snes->jacobian && sdm->computejacobian == MatMFFDComputeJacobian) {
339*6cab3a1bSJed Brown     Mat J;
340*6cab3a1bSJed Brown     void *functx;
341*6cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
342*6cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
343*6cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
344*6cab3a1bSJed Brown     ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
345*6cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr);
346*6cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
347*6cab3a1bSJed Brown   } else if (snes->dm && snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) {
348*6cab3a1bSJed Brown     Mat J,B;
349*6cab3a1bSJed Brown     void *functx;
350*6cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
351*6cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
352*6cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
353*6cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
354*6cab3a1bSJed Brown     ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
355*6cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,functx);CHKERRQ(ierr);
356*6cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
357*6cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
358*6cab3a1bSJed Brown   } else if (snes->dm && !snes->jacobian_pre) {
359*6cab3a1bSJed Brown     Mat J,B;
360*6cab3a1bSJed Brown     J = snes->jacobian;
361*6cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
362*6cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J?J:B,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
363*6cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
364*6cab3a1bSJed Brown   }
365*6cab3a1bSJed Brown   PetscFunctionReturn(0);
366*6cab3a1bSJed Brown }
367*6cab3a1bSJed Brown 
368*6cab3a1bSJed Brown #undef __FUNCT__
3694a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions"
3709b94acceSBarry Smith /*@
37194b7f48cSBarry Smith    SNESSetFromOptions - Sets various SNES and KSP parameters from user options.
3729b94acceSBarry Smith 
373c7afd0dbSLois Curfman McInnes    Collective on SNES
374c7afd0dbSLois Curfman McInnes 
3759b94acceSBarry Smith    Input Parameter:
3769b94acceSBarry Smith .  snes - the SNES context
3779b94acceSBarry Smith 
37836851e7fSLois Curfman McInnes    Options Database Keys:
379ea630c6eSPeter Brune +  -snes_type <type> - ls, tr, ngmres, ncg, richardson, qn, vi, fas
38082738288SBarry Smith .  -snes_stol - convergence tolerance in terms of the norm
38182738288SBarry Smith                 of the change in the solution between steps
38270441072SBarry Smith .  -snes_atol <abstol> - absolute tolerance of residual norm
383b39c3a46SLois Curfman McInnes .  -snes_rtol <rtol> - relative decrease in tolerance norm from initial
384b39c3a46SLois Curfman McInnes .  -snes_max_it <max_it> - maximum number of iterations
385b39c3a46SLois Curfman McInnes .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
3864839bfe8SBarry Smith .  -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none
387ddf469c8SBarry Smith .  -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops
388a8054027SBarry Smith .  -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild)
389e35cf81dSBarry Smith .  -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild)
390b39c3a46SLois Curfman McInnes .  -snes_trtol <trtol> - trust region tolerance
3912492ecdbSBarry Smith .  -snes_no_convergence_test - skip convergence test in nonlinear
39282738288SBarry Smith                                solver; hence iterations will continue until max_it
3931fbbfb26SLois Curfman McInnes                                or some other criterion is reached. Saves expense
39482738288SBarry Smith                                of convergence test
395e8105e01SRichard Katz .  -snes_monitor <optional filename> - prints residual norm at each iteration. if no
396e8105e01SRichard Katz                                        filename given prints to stdout
397a6570f20SBarry Smith .  -snes_monitor_solution - plots solution at each iteration
398a6570f20SBarry Smith .  -snes_monitor_residual - plots residual (not its norm) at each iteration
399a6570f20SBarry Smith .  -snes_monitor_solution_update - plots update to solution at each iteration
400a6570f20SBarry Smith .  -snes_monitor_draw - plots residual norm at each iteration
401e24b481bSBarry Smith .  -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
4025968eb51SBarry Smith .  -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
403fee2055bSBarry Smith -  -snes_converged_reason - print the reason for convergence/divergence after each solve
40482738288SBarry Smith 
40582738288SBarry Smith     Options Database for Eisenstat-Walker method:
406fa9f3622SBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
4074b27c08aSLois Curfman McInnes .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
40836851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
40936851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
41036851e7fSLois Curfman McInnes .  -snes_ksp_ew_gamma <gamma> - Sets gamma
41136851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha <alpha> - Sets alpha
41236851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
41336851e7fSLois Curfman McInnes -  -snes_ksp_ew_threshold <threshold> - Sets threshold
41482738288SBarry Smith 
41511ca99fdSLois Curfman McInnes    Notes:
41611ca99fdSLois Curfman McInnes    To see all options, run your program with the -help option or consult
4170598bfebSBarry Smith    the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>.
41883e2fdc7SBarry Smith 
41936851e7fSLois Curfman McInnes    Level: beginner
42036851e7fSLois Curfman McInnes 
4219b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database
4229b94acceSBarry Smith 
42369ed319cSSatish Balay .seealso: SNESSetOptionsPrefix()
4249b94acceSBarry Smith @*/
4257087cfbeSBarry Smith PetscErrorCode  SNESSetFromOptions(SNES snes)
4269b94acceSBarry Smith {
427ea630c6eSPeter Brune   PetscBool               flg,set,mf,mf_operator,pcset;
428efd51863SBarry Smith   PetscInt                i,indx,lag,mf_version,grids;
429aa3661deSLisandro Dalcin   MatStructure            matflag;
43085385478SLisandro Dalcin   const char              *deft = SNESLS;
43185385478SLisandro Dalcin   const char              *convtests[] = {"default","skip"};
43285385478SLisandro Dalcin   SNESKSPEW               *kctx = NULL;
433e8105e01SRichard Katz   char                    type[256], monfilename[PETSC_MAX_PATH_LEN];
43451e86f29SPeter Brune   const char              *optionsprefix;
435649052a6SBarry Smith   PetscViewer             monviewer;
43685385478SLisandro Dalcin   PetscErrorCode          ierr;
4379b94acceSBarry Smith 
4383a40ed3dSBarry Smith   PetscFunctionBegin;
4390700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
440ca161407SBarry Smith 
441186905e3SBarry Smith   if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
4423194b578SJed Brown   ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr);
4437adad957SLisandro Dalcin     if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; }
444b0a32e0cSBarry Smith     ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr);
445d64ed03dSBarry Smith     if (flg) {
446186905e3SBarry Smith       ierr = SNESSetType(snes,type);CHKERRQ(ierr);
4477adad957SLisandro Dalcin     } else if (!((PetscObject)snes)->type_name) {
448186905e3SBarry Smith       ierr = SNESSetType(snes,deft);CHKERRQ(ierr);
449d64ed03dSBarry Smith     }
45090d69ab7SBarry Smith     /* not used here, but called so will go into help messaage */
451909c8a9fSBarry Smith     ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr);
45293c39befSBarry Smith 
45357034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->xtol,&snes->xtol,0);CHKERRQ(ierr);
45457034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr);
455186905e3SBarry Smith 
45657034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr);
457b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr);
458b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr);
45950ffb88aSMatthew Knepley     ierr = PetscOptionsInt("-snes_max_fail","Maximum failures","SNESSetTolerances",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr);
460ddf469c8SBarry Smith     ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr);
461acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);CHKERRQ(ierr);
46285385478SLisandro Dalcin 
463a8054027SBarry Smith     ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr);
464a8054027SBarry Smith     if (flg) {
465a8054027SBarry Smith       ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr);
466a8054027SBarry Smith     }
467e35cf81dSBarry Smith     ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr);
468e35cf81dSBarry Smith     if (flg) {
469e35cf81dSBarry Smith       ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr);
470e35cf81dSBarry Smith     }
471efd51863SBarry Smith     ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr);
472efd51863SBarry Smith     if (flg) {
473efd51863SBarry Smith       ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr);
474efd51863SBarry Smith     }
475a8054027SBarry Smith 
47685385478SLisandro Dalcin     ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr);
47785385478SLisandro Dalcin     if (flg) {
47885385478SLisandro Dalcin       switch (indx) {
4797f7931b9SBarry Smith       case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break;
4807f7931b9SBarry Smith       case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);    break;
48185385478SLisandro Dalcin       }
48285385478SLisandro Dalcin     }
48385385478SLisandro Dalcin 
484acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr);
485186905e3SBarry Smith 
48685385478SLisandro Dalcin     kctx = (SNESKSPEW *)snes->kspconvctx;
48785385478SLisandro Dalcin 
488acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr);
489186905e3SBarry Smith 
490fa9f3622SBarry Smith     ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr);
491fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr);
492fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr);
493fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr);
494fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr);
495fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr);
496fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr);
497186905e3SBarry Smith 
49890d69ab7SBarry Smith     flg  = PETSC_FALSE;
499acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
500a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);}
501eabae89aSBarry Smith 
502a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
503e8105e01SRichard Katz     if (flg) {
504649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
505649052a6SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
506e8105e01SRichard Katz     }
507eabae89aSBarry Smith 
508b271bb04SBarry Smith     ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
509b271bb04SBarry Smith     if (flg) {
510b271bb04SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr);
511b271bb04SBarry Smith     }
512b271bb04SBarry Smith 
513a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
514eabae89aSBarry Smith     if (flg) {
515649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
516f1bef1bcSMatthew Knepley       ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr);
517e8105e01SRichard Katz     }
518eabae89aSBarry Smith 
519a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
520eabae89aSBarry Smith     if (flg) {
521649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
522649052a6SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
523eabae89aSBarry Smith     }
524eabae89aSBarry Smith 
5255180491cSLisandro Dalcin     ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
5265180491cSLisandro Dalcin     if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);}
5275180491cSLisandro Dalcin 
52890d69ab7SBarry Smith     flg  = PETSC_FALSE;
529acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
530a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);}
53190d69ab7SBarry Smith     flg  = PETSC_FALSE;
532acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
533a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);}
53490d69ab7SBarry Smith     flg  = PETSC_FALSE;
535acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
536a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);}
53790d69ab7SBarry Smith     flg  = PETSC_FALSE;
538acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
539a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
54090d69ab7SBarry Smith     flg  = PETSC_FALSE;
541acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
542b271bb04SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
543e24b481bSBarry Smith 
54490d69ab7SBarry Smith     flg  = PETSC_FALSE;
545acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
5464b27c08aSLois Curfman McInnes     if (flg) {
547*6cab3a1bSJed Brown       void *functx;
548*6cab3a1bSJed Brown       ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
549*6cab3a1bSJed Brown       ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,functx);CHKERRQ(ierr);
550ae15b995SBarry Smith       ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr);
5519b94acceSBarry Smith     }
552639f9d9dSBarry Smith 
553aa3661deSLisandro Dalcin     mf = mf_operator = PETSC_FALSE;
554aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
555acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr);
556a8248277SBarry Smith     if (flg && mf_operator) {
557a8248277SBarry Smith       snes->mf_operator = PETSC_TRUE;
558a8248277SBarry Smith       mf = PETSC_TRUE;
559a8248277SBarry Smith     }
560aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
561acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);CHKERRQ(ierr);
562aa3661deSLisandro Dalcin     if (!flg && mf_operator) mf = PETSC_TRUE;
563aa3661deSLisandro Dalcin     mf_version = 1;
564aa3661deSLisandro Dalcin     ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);CHKERRQ(ierr);
565aa3661deSLisandro Dalcin 
566d28543b3SPeter Brune 
56789b92e6fSPeter Brune     /* GS Options */
56889b92e6fSPeter Brune     ierr = PetscOptionsInt("-snes_gs_sweeps","Number of sweeps of GS to apply","SNESComputeGS",snes->gssweeps,&snes->gssweeps,PETSC_NULL);CHKERRQ(ierr);
56989b92e6fSPeter Brune 
570ea630c6eSPeter Brune     /* line search options */
571ea630c6eSPeter Brune     ierr = PetscOptionsReal("-snes_ls_alpha","Constant function norm must decrease by","None",snes->ls_alpha,&snes->ls_alpha,0);CHKERRQ(ierr);
572ea630c6eSPeter Brune     ierr = PetscOptionsReal("-snes_ls_maxstep","Step must be less than","None",snes->maxstep,&snes->maxstep,0);CHKERRQ(ierr);
573ea630c6eSPeter Brune     ierr = PetscOptionsReal("-snes_ls_steptol","Minimum lambda allowed","None",snes->steptol,&snes->steptol,0);CHKERRQ(ierr);
574ea630c6eSPeter Brune     ierr = PetscOptionsReal("-snes_ls_damping","Damping parameter","SNES",snes->damping,&snes->damping,&flg);CHKERRQ(ierr);
575af60355fSPeter Brune     ierr = PetscOptionsInt("-snes_ls_it"      ,"Line search iterations","SNES",snes->ls_its,&snes->ls_its,&flg);CHKERRQ(ierr);
576ea630c6eSPeter Brune     ierr = PetscOptionsBool("-snes_ls_monitor","Print progress of line searches","SNESLineSearchSetMonitor",snes->ls_monitor ? PETSC_TRUE : PETSC_FALSE,&flg,&set);CHKERRQ(ierr);
577ea630c6eSPeter Brune     if (set) {ierr = SNESLineSearchSetMonitor(snes,flg);CHKERRQ(ierr);}
57815f5eeeaSPeter Brune     ierr = PetscOptionsEnum("-snes_ls","Line search used","SNESLineSearchSet",SNESLineSearchTypes,(PetscEnum)snes->ls_type,(PetscEnum*)&indx,&flg);CHKERRQ(ierr);
57915f5eeeaSPeter Brune     if (flg) {
580ea630c6eSPeter Brune       ierr = SNESLineSearchSetType(snes,(SNESLineSearchType)indx);CHKERRQ(ierr);
58115f5eeeaSPeter Brune     }
5828e3fc8c0SJed Brown     flg = snes->ops->precheckstep == SNESLineSearchPreCheckPicard ? PETSC_TRUE : PETSC_FALSE;
5838e3fc8c0SJed Brown     ierr = PetscOptionsBool("-snes_ls_precheck_picard","Use a correction that sometimes improves convergence of Picard iteration","SNESLineSearchPreCheckPicard",flg,&flg,&set);CHKERRQ(ierr);
5848e3fc8c0SJed Brown     if (set) {
5858e3fc8c0SJed Brown       if (flg) {
5868e3fc8c0SJed Brown         snes->precheck_picard_angle = 10.; /* correction only active if angle is less than 10 degrees */
5878e3fc8c0SJed 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);
5888e3fc8c0SJed Brown         ierr = SNESLineSearchSetPreCheck(snes,SNESLineSearchPreCheckPicard,&snes->precheck_picard_angle);CHKERRQ(ierr);
5898e3fc8c0SJed Brown       } else {
5908e3fc8c0SJed Brown         ierr = SNESLineSearchSetPreCheck(snes,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
5918e3fc8c0SJed Brown       }
5928e3fc8c0SJed Brown     }
5938e3fc8c0SJed Brown 
59476b2cf59SMatthew Knepley     for(i = 0; i < numberofsetfromoptions; i++) {
59576b2cf59SMatthew Knepley       ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr);
59676b2cf59SMatthew Knepley     }
59776b2cf59SMatthew Knepley 
598e7788613SBarry Smith     if (snes->ops->setfromoptions) {
599e7788613SBarry Smith       ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr);
600639f9d9dSBarry Smith     }
6015d973c19SBarry Smith 
6025d973c19SBarry Smith     /* process any options handlers added with PetscObjectAddOptionsHandler() */
6035d973c19SBarry Smith     ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr);
604b0a32e0cSBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
6054bbc92c1SBarry Smith 
606aa3661deSLisandro Dalcin   if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); }
6071cee3971SBarry Smith 
6081cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
609aa3661deSLisandro Dalcin   ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag);
610aa3661deSLisandro Dalcin   ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr);
61185385478SLisandro Dalcin   ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr);
61293993e2dSLois Curfman McInnes 
61351e86f29SPeter Brune   /* if someone has set the SNES PC type, create it. */
61451e86f29SPeter Brune   ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
61551e86f29SPeter Brune   ierr = PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr);
61651e86f29SPeter Brune   if (pcset && (!snes->pc)) {
61751e86f29SPeter Brune     ierr = SNESGetPC(snes, &snes->pc);CHKERRQ(ierr);
61851e86f29SPeter Brune   }
6194a0c5b0cSMatthew G Knepley   if (snes->pc) {
620fde0ff24SPeter Brune     ierr = SNESSetOptionsPrefix(snes->pc, optionsprefix);CHKERRQ(ierr);
621fde0ff24SPeter Brune     ierr = SNESAppendOptionsPrefix(snes->pc, "npc_");CHKERRQ(ierr);
6224a0c5b0cSMatthew G Knepley     ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr);
6234a0c5b0cSMatthew G Knepley     ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr);
6244a0c5b0cSMatthew G Knepley   }
6253a40ed3dSBarry Smith   PetscFunctionReturn(0);
6269b94acceSBarry Smith }
6279b94acceSBarry Smith 
628d25893d9SBarry Smith #undef __FUNCT__
629d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext"
630d25893d9SBarry Smith /*@
631d25893d9SBarry Smith    SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for
632d25893d9SBarry Smith    the nonlinear solvers.
633d25893d9SBarry Smith 
634d25893d9SBarry Smith    Logically Collective on SNES
635d25893d9SBarry Smith 
636d25893d9SBarry Smith    Input Parameters:
637d25893d9SBarry Smith +  snes - the SNES context
638d25893d9SBarry Smith .  compute - function to compute the context
639d25893d9SBarry Smith -  destroy - function to destroy the context
640d25893d9SBarry Smith 
641d25893d9SBarry Smith    Level: intermediate
642d25893d9SBarry Smith 
643d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context
644d25893d9SBarry Smith 
645d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext()
646d25893d9SBarry Smith @*/
647d25893d9SBarry Smith PetscErrorCode  SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**))
648d25893d9SBarry Smith {
649d25893d9SBarry Smith   PetscFunctionBegin;
650d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
651d25893d9SBarry Smith   snes->ops->usercompute = compute;
652d25893d9SBarry Smith   snes->ops->userdestroy = destroy;
653d25893d9SBarry Smith   PetscFunctionReturn(0);
654d25893d9SBarry Smith }
655a847f771SSatish Balay 
6564a2ae208SSatish Balay #undef __FUNCT__
6574a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext"
658b07ff414SBarry Smith /*@
6599b94acceSBarry Smith    SNESSetApplicationContext - Sets the optional user-defined context for
6609b94acceSBarry Smith    the nonlinear solvers.
6619b94acceSBarry Smith 
6623f9fe445SBarry Smith    Logically Collective on SNES
663fee21e36SBarry Smith 
664c7afd0dbSLois Curfman McInnes    Input Parameters:
665c7afd0dbSLois Curfman McInnes +  snes - the SNES context
666c7afd0dbSLois Curfman McInnes -  usrP - optional user context
667c7afd0dbSLois Curfman McInnes 
66836851e7fSLois Curfman McInnes    Level: intermediate
66936851e7fSLois Curfman McInnes 
6709b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context
6719b94acceSBarry Smith 
672d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetApplicationContext()
6739b94acceSBarry Smith @*/
6747087cfbeSBarry Smith PetscErrorCode  SNESSetApplicationContext(SNES snes,void *usrP)
6759b94acceSBarry Smith {
6761b2093e4SBarry Smith   PetscErrorCode ierr;
677b07ff414SBarry Smith   KSP            ksp;
6781b2093e4SBarry Smith 
6793a40ed3dSBarry Smith   PetscFunctionBegin;
6800700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
681b07ff414SBarry Smith   ierr       = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
682b07ff414SBarry Smith   ierr       = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr);
6839b94acceSBarry Smith   snes->user = usrP;
6843a40ed3dSBarry Smith   PetscFunctionReturn(0);
6859b94acceSBarry Smith }
68674679c65SBarry Smith 
6874a2ae208SSatish Balay #undef __FUNCT__
6884a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext"
689b07ff414SBarry Smith /*@
6909b94acceSBarry Smith    SNESGetApplicationContext - Gets the user-defined context for the
6919b94acceSBarry Smith    nonlinear solvers.
6929b94acceSBarry Smith 
693c7afd0dbSLois Curfman McInnes    Not Collective
694c7afd0dbSLois Curfman McInnes 
6959b94acceSBarry Smith    Input Parameter:
6969b94acceSBarry Smith .  snes - SNES context
6979b94acceSBarry Smith 
6989b94acceSBarry Smith    Output Parameter:
6999b94acceSBarry Smith .  usrP - user context
7009b94acceSBarry Smith 
70136851e7fSLois Curfman McInnes    Level: intermediate
70236851e7fSLois Curfman McInnes 
7039b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context
7049b94acceSBarry Smith 
7059b94acceSBarry Smith .seealso: SNESSetApplicationContext()
7069b94acceSBarry Smith @*/
707e71120c6SJed Brown PetscErrorCode  SNESGetApplicationContext(SNES snes,void *usrP)
7089b94acceSBarry Smith {
7093a40ed3dSBarry Smith   PetscFunctionBegin;
7100700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
711e71120c6SJed Brown   *(void**)usrP = snes->user;
7123a40ed3dSBarry Smith   PetscFunctionReturn(0);
7139b94acceSBarry Smith }
71474679c65SBarry Smith 
7154a2ae208SSatish Balay #undef __FUNCT__
7164a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber"
7179b94acceSBarry Smith /*@
718c8228a4eSBarry Smith    SNESGetIterationNumber - Gets the number of nonlinear iterations completed
719c8228a4eSBarry Smith    at this time.
7209b94acceSBarry Smith 
721c7afd0dbSLois Curfman McInnes    Not Collective
722c7afd0dbSLois Curfman McInnes 
7239b94acceSBarry Smith    Input Parameter:
7249b94acceSBarry Smith .  snes - SNES context
7259b94acceSBarry Smith 
7269b94acceSBarry Smith    Output Parameter:
7279b94acceSBarry Smith .  iter - iteration number
7289b94acceSBarry Smith 
729c8228a4eSBarry Smith    Notes:
730c8228a4eSBarry Smith    For example, during the computation of iteration 2 this would return 1.
731c8228a4eSBarry Smith 
732c8228a4eSBarry Smith    This is useful for using lagged Jacobians (where one does not recompute the
73308405cd6SLois Curfman McInnes    Jacobian at each SNES iteration). For example, the code
73408405cd6SLois Curfman McInnes .vb
73508405cd6SLois Curfman McInnes       ierr = SNESGetIterationNumber(snes,&it);
73608405cd6SLois Curfman McInnes       if (!(it % 2)) {
73708405cd6SLois Curfman McInnes         [compute Jacobian here]
73808405cd6SLois Curfman McInnes       }
73908405cd6SLois Curfman McInnes .ve
740c8228a4eSBarry Smith    can be used in your ComputeJacobian() function to cause the Jacobian to be
74108405cd6SLois Curfman McInnes    recomputed every second SNES iteration.
742c8228a4eSBarry Smith 
74336851e7fSLois Curfman McInnes    Level: intermediate
74436851e7fSLois Curfman McInnes 
7452b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number,
7462b668275SBarry Smith 
747b850b91aSLisandro Dalcin .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
7489b94acceSBarry Smith @*/
7497087cfbeSBarry Smith PetscErrorCode  SNESGetIterationNumber(SNES snes,PetscInt* iter)
7509b94acceSBarry Smith {
7513a40ed3dSBarry Smith   PetscFunctionBegin;
7520700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
7534482741eSBarry Smith   PetscValidIntPointer(iter,2);
7549b94acceSBarry Smith   *iter = snes->iter;
7553a40ed3dSBarry Smith   PetscFunctionReturn(0);
7569b94acceSBarry Smith }
75774679c65SBarry Smith 
7584a2ae208SSatish Balay #undef __FUNCT__
759360c497dSPeter Brune #define __FUNCT__ "SNESSetIterationNumber"
760360c497dSPeter Brune /*@
761360c497dSPeter Brune    SNESSetIterationNumber - Sets the current iteration number.
762360c497dSPeter Brune 
763360c497dSPeter Brune    Not Collective
764360c497dSPeter Brune 
765360c497dSPeter Brune    Input Parameter:
766360c497dSPeter Brune .  snes - SNES context
767360c497dSPeter Brune .  iter - iteration number
768360c497dSPeter Brune 
769360c497dSPeter Brune    Level: developer
770360c497dSPeter Brune 
771360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number,
772360c497dSPeter Brune 
773360c497dSPeter Brune .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
774360c497dSPeter Brune @*/
775360c497dSPeter Brune PetscErrorCode  SNESSetIterationNumber(SNES snes,PetscInt iter)
776360c497dSPeter Brune {
777360c497dSPeter Brune   PetscErrorCode ierr;
778360c497dSPeter Brune 
779360c497dSPeter Brune   PetscFunctionBegin;
780360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
781360c497dSPeter Brune   ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr);
782360c497dSPeter Brune   snes->iter = iter;
783360c497dSPeter Brune   ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr);
784360c497dSPeter Brune   PetscFunctionReturn(0);
785360c497dSPeter Brune }
786360c497dSPeter Brune 
787360c497dSPeter Brune #undef __FUNCT__
7884a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm"
7899b94acceSBarry Smith /*@
7909b94acceSBarry Smith    SNESGetFunctionNorm - Gets the norm of the current function that was set
7919b94acceSBarry Smith    with SNESSSetFunction().
7929b94acceSBarry Smith 
793c7afd0dbSLois Curfman McInnes    Collective on SNES
794c7afd0dbSLois Curfman McInnes 
7959b94acceSBarry Smith    Input Parameter:
7969b94acceSBarry Smith .  snes - SNES context
7979b94acceSBarry Smith 
7989b94acceSBarry Smith    Output Parameter:
7999b94acceSBarry Smith .  fnorm - 2-norm of function
8009b94acceSBarry Smith 
80136851e7fSLois Curfman McInnes    Level: intermediate
80236851e7fSLois Curfman McInnes 
8039b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm
804a86d99e1SLois Curfman McInnes 
805b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations()
8069b94acceSBarry Smith @*/
8077087cfbeSBarry Smith PetscErrorCode  SNESGetFunctionNorm(SNES snes,PetscReal *fnorm)
8089b94acceSBarry Smith {
8093a40ed3dSBarry Smith   PetscFunctionBegin;
8100700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
8114482741eSBarry Smith   PetscValidScalarPointer(fnorm,2);
8129b94acceSBarry Smith   *fnorm = snes->norm;
8133a40ed3dSBarry Smith   PetscFunctionReturn(0);
8149b94acceSBarry Smith }
81574679c65SBarry Smith 
816360c497dSPeter Brune 
817360c497dSPeter Brune #undef __FUNCT__
818360c497dSPeter Brune #define __FUNCT__ "SNESSetFunctionNorm"
819360c497dSPeter Brune /*@
820360c497dSPeter Brune    SNESSetFunctionNorm - Sets the 2-norm of the current function computed using VecNorm().
821360c497dSPeter Brune 
822360c497dSPeter Brune    Collective on SNES
823360c497dSPeter Brune 
824360c497dSPeter Brune    Input Parameter:
825360c497dSPeter Brune .  snes - SNES context
826360c497dSPeter Brune .  fnorm - 2-norm of function
827360c497dSPeter Brune 
828360c497dSPeter Brune    Level: developer
829360c497dSPeter Brune 
830360c497dSPeter Brune .keywords: SNES, nonlinear, set, function, norm
831360c497dSPeter Brune 
832360c497dSPeter Brune .seealso: SNESSetFunction(), SNESSetIterationNumber(), VecNorm().
833360c497dSPeter Brune @*/
834360c497dSPeter Brune PetscErrorCode  SNESSetFunctionNorm(SNES snes,PetscReal fnorm)
835360c497dSPeter Brune {
836360c497dSPeter Brune 
837360c497dSPeter Brune   PetscErrorCode ierr;
838360c497dSPeter Brune 
839360c497dSPeter Brune   PetscFunctionBegin;
840360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
841360c497dSPeter Brune   ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr);
842360c497dSPeter Brune   snes->norm = fnorm;
843360c497dSPeter Brune   ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr);
844360c497dSPeter Brune   PetscFunctionReturn(0);
845360c497dSPeter Brune }
846360c497dSPeter Brune 
8474a2ae208SSatish Balay #undef __FUNCT__
848b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures"
8499b94acceSBarry Smith /*@
850b850b91aSLisandro Dalcin    SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
8519b94acceSBarry Smith    attempted by the nonlinear solver.
8529b94acceSBarry Smith 
853c7afd0dbSLois Curfman McInnes    Not Collective
854c7afd0dbSLois Curfman McInnes 
8559b94acceSBarry Smith    Input Parameter:
8569b94acceSBarry Smith .  snes - SNES context
8579b94acceSBarry Smith 
8589b94acceSBarry Smith    Output Parameter:
8599b94acceSBarry Smith .  nfails - number of unsuccessful steps attempted
8609b94acceSBarry Smith 
861c96a6f78SLois Curfman McInnes    Notes:
862c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
863c96a6f78SLois Curfman McInnes 
86436851e7fSLois Curfman McInnes    Level: intermediate
86536851e7fSLois Curfman McInnes 
8669b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
86758ebbce7SBarry Smith 
868e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
86958ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures()
8709b94acceSBarry Smith @*/
8717087cfbeSBarry Smith PetscErrorCode  SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails)
8729b94acceSBarry Smith {
8733a40ed3dSBarry Smith   PetscFunctionBegin;
8740700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
8754482741eSBarry Smith   PetscValidIntPointer(nfails,2);
87650ffb88aSMatthew Knepley   *nfails = snes->numFailures;
87750ffb88aSMatthew Knepley   PetscFunctionReturn(0);
87850ffb88aSMatthew Knepley }
87950ffb88aSMatthew Knepley 
88050ffb88aSMatthew Knepley #undef __FUNCT__
881b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures"
88250ffb88aSMatthew Knepley /*@
883b850b91aSLisandro Dalcin    SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
88450ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
88550ffb88aSMatthew Knepley 
88650ffb88aSMatthew Knepley    Not Collective
88750ffb88aSMatthew Knepley 
88850ffb88aSMatthew Knepley    Input Parameters:
88950ffb88aSMatthew Knepley +  snes     - SNES context
89050ffb88aSMatthew Knepley -  maxFails - maximum of unsuccessful steps
89150ffb88aSMatthew Knepley 
89250ffb88aSMatthew Knepley    Level: intermediate
89350ffb88aSMatthew Knepley 
89450ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
89558ebbce7SBarry Smith 
896e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
89758ebbce7SBarry Smith           SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
89850ffb88aSMatthew Knepley @*/
8997087cfbeSBarry Smith PetscErrorCode  SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
90050ffb88aSMatthew Knepley {
90150ffb88aSMatthew Knepley   PetscFunctionBegin;
9020700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
90350ffb88aSMatthew Knepley   snes->maxFailures = maxFails;
90450ffb88aSMatthew Knepley   PetscFunctionReturn(0);
90550ffb88aSMatthew Knepley }
90650ffb88aSMatthew Knepley 
90750ffb88aSMatthew Knepley #undef __FUNCT__
908b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures"
90950ffb88aSMatthew Knepley /*@
910b850b91aSLisandro Dalcin    SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
91150ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
91250ffb88aSMatthew Knepley 
91350ffb88aSMatthew Knepley    Not Collective
91450ffb88aSMatthew Knepley 
91550ffb88aSMatthew Knepley    Input Parameter:
91650ffb88aSMatthew Knepley .  snes     - SNES context
91750ffb88aSMatthew Knepley 
91850ffb88aSMatthew Knepley    Output Parameter:
91950ffb88aSMatthew Knepley .  maxFails - maximum of unsuccessful steps
92050ffb88aSMatthew Knepley 
92150ffb88aSMatthew Knepley    Level: intermediate
92250ffb88aSMatthew Knepley 
92350ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
92458ebbce7SBarry Smith 
925e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
92658ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
92758ebbce7SBarry Smith 
92850ffb88aSMatthew Knepley @*/
9297087cfbeSBarry Smith PetscErrorCode  SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
93050ffb88aSMatthew Knepley {
93150ffb88aSMatthew Knepley   PetscFunctionBegin;
9320700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9334482741eSBarry Smith   PetscValidIntPointer(maxFails,2);
93450ffb88aSMatthew Knepley   *maxFails = snes->maxFailures;
9353a40ed3dSBarry Smith   PetscFunctionReturn(0);
9369b94acceSBarry Smith }
937a847f771SSatish Balay 
9384a2ae208SSatish Balay #undef __FUNCT__
9392541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals"
9402541af92SBarry Smith /*@
9412541af92SBarry Smith    SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations
9422541af92SBarry Smith      done by SNES.
9432541af92SBarry Smith 
9442541af92SBarry Smith    Not Collective
9452541af92SBarry Smith 
9462541af92SBarry Smith    Input Parameter:
9472541af92SBarry Smith .  snes     - SNES context
9482541af92SBarry Smith 
9492541af92SBarry Smith    Output Parameter:
9502541af92SBarry Smith .  nfuncs - number of evaluations
9512541af92SBarry Smith 
9522541af92SBarry Smith    Level: intermediate
9532541af92SBarry Smith 
9542541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
95558ebbce7SBarry Smith 
956e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures()
9572541af92SBarry Smith @*/
9587087cfbeSBarry Smith PetscErrorCode  SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs)
9592541af92SBarry Smith {
9602541af92SBarry Smith   PetscFunctionBegin;
9610700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9622541af92SBarry Smith   PetscValidIntPointer(nfuncs,2);
9632541af92SBarry Smith   *nfuncs = snes->nfuncs;
9642541af92SBarry Smith   PetscFunctionReturn(0);
9652541af92SBarry Smith }
9662541af92SBarry Smith 
9672541af92SBarry Smith #undef __FUNCT__
9683d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures"
9693d4c4710SBarry Smith /*@
9703d4c4710SBarry Smith    SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
9713d4c4710SBarry Smith    linear solvers.
9723d4c4710SBarry Smith 
9733d4c4710SBarry Smith    Not Collective
9743d4c4710SBarry Smith 
9753d4c4710SBarry Smith    Input Parameter:
9763d4c4710SBarry Smith .  snes - SNES context
9773d4c4710SBarry Smith 
9783d4c4710SBarry Smith    Output Parameter:
9793d4c4710SBarry Smith .  nfails - number of failed solves
9803d4c4710SBarry Smith 
9813d4c4710SBarry Smith    Notes:
9823d4c4710SBarry Smith    This counter is reset to zero for each successive call to SNESSolve().
9833d4c4710SBarry Smith 
9843d4c4710SBarry Smith    Level: intermediate
9853d4c4710SBarry Smith 
9863d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
98758ebbce7SBarry Smith 
988e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures()
9893d4c4710SBarry Smith @*/
9907087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails)
9913d4c4710SBarry Smith {
9923d4c4710SBarry Smith   PetscFunctionBegin;
9930700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9943d4c4710SBarry Smith   PetscValidIntPointer(nfails,2);
9953d4c4710SBarry Smith   *nfails = snes->numLinearSolveFailures;
9963d4c4710SBarry Smith   PetscFunctionReturn(0);
9973d4c4710SBarry Smith }
9983d4c4710SBarry Smith 
9993d4c4710SBarry Smith #undef __FUNCT__
10003d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures"
10013d4c4710SBarry Smith /*@
10023d4c4710SBarry Smith    SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
10033d4c4710SBarry Smith    allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE
10043d4c4710SBarry Smith 
10053f9fe445SBarry Smith    Logically Collective on SNES
10063d4c4710SBarry Smith 
10073d4c4710SBarry Smith    Input Parameters:
10083d4c4710SBarry Smith +  snes     - SNES context
10093d4c4710SBarry Smith -  maxFails - maximum allowed linear solve failures
10103d4c4710SBarry Smith 
10113d4c4710SBarry Smith    Level: intermediate
10123d4c4710SBarry Smith 
1013a6796414SBarry Smith    Notes: By default this is 0; that is SNES returns on the first failed linear solve
10143d4c4710SBarry Smith 
10153d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
10163d4c4710SBarry Smith 
101758ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations()
10183d4c4710SBarry Smith @*/
10197087cfbeSBarry Smith PetscErrorCode  SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
10203d4c4710SBarry Smith {
10213d4c4710SBarry Smith   PetscFunctionBegin;
10220700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1023c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxFails,2);
10243d4c4710SBarry Smith   snes->maxLinearSolveFailures = maxFails;
10253d4c4710SBarry Smith   PetscFunctionReturn(0);
10263d4c4710SBarry Smith }
10273d4c4710SBarry Smith 
10283d4c4710SBarry Smith #undef __FUNCT__
10293d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures"
10303d4c4710SBarry Smith /*@
10313d4c4710SBarry Smith    SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
10323d4c4710SBarry Smith      are allowed before SNES terminates
10333d4c4710SBarry Smith 
10343d4c4710SBarry Smith    Not Collective
10353d4c4710SBarry Smith 
10363d4c4710SBarry Smith    Input Parameter:
10373d4c4710SBarry Smith .  snes     - SNES context
10383d4c4710SBarry Smith 
10393d4c4710SBarry Smith    Output Parameter:
10403d4c4710SBarry Smith .  maxFails - maximum of unsuccessful solves allowed
10413d4c4710SBarry Smith 
10423d4c4710SBarry Smith    Level: intermediate
10433d4c4710SBarry Smith 
10443d4c4710SBarry Smith    Notes: By default this is 1; that is SNES returns on the first failed linear solve
10453d4c4710SBarry Smith 
10463d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
10473d4c4710SBarry Smith 
1048e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(),
10493d4c4710SBarry Smith @*/
10507087cfbeSBarry Smith PetscErrorCode  SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
10513d4c4710SBarry Smith {
10523d4c4710SBarry Smith   PetscFunctionBegin;
10530700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10543d4c4710SBarry Smith   PetscValidIntPointer(maxFails,2);
10553d4c4710SBarry Smith   *maxFails = snes->maxLinearSolveFailures;
10563d4c4710SBarry Smith   PetscFunctionReturn(0);
10573d4c4710SBarry Smith }
10583d4c4710SBarry Smith 
10593d4c4710SBarry Smith #undef __FUNCT__
1060b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations"
1061c96a6f78SLois Curfman McInnes /*@
1062b850b91aSLisandro Dalcin    SNESGetLinearSolveIterations - Gets the total number of linear iterations
1063c96a6f78SLois Curfman McInnes    used by the nonlinear solver.
1064c96a6f78SLois Curfman McInnes 
1065c7afd0dbSLois Curfman McInnes    Not Collective
1066c7afd0dbSLois Curfman McInnes 
1067c96a6f78SLois Curfman McInnes    Input Parameter:
1068c96a6f78SLois Curfman McInnes .  snes - SNES context
1069c96a6f78SLois Curfman McInnes 
1070c96a6f78SLois Curfman McInnes    Output Parameter:
1071c96a6f78SLois Curfman McInnes .  lits - number of linear iterations
1072c96a6f78SLois Curfman McInnes 
1073c96a6f78SLois Curfman McInnes    Notes:
1074c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
1075c96a6f78SLois Curfman McInnes 
107636851e7fSLois Curfman McInnes    Level: intermediate
107736851e7fSLois Curfman McInnes 
1078c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations
10792b668275SBarry Smith 
10808c7482ecSBarry Smith .seealso:  SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures()
1081c96a6f78SLois Curfman McInnes @*/
10827087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveIterations(SNES snes,PetscInt* lits)
1083c96a6f78SLois Curfman McInnes {
10843a40ed3dSBarry Smith   PetscFunctionBegin;
10850700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10864482741eSBarry Smith   PetscValidIntPointer(lits,2);
1087c96a6f78SLois Curfman McInnes   *lits = snes->linear_its;
10883a40ed3dSBarry Smith   PetscFunctionReturn(0);
1089c96a6f78SLois Curfman McInnes }
1090c96a6f78SLois Curfman McInnes 
10914a2ae208SSatish Balay #undef __FUNCT__
109294b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP"
109352baeb72SSatish Balay /*@
109494b7f48cSBarry Smith    SNESGetKSP - Returns the KSP context for a SNES solver.
10959b94acceSBarry Smith 
109694b7f48cSBarry Smith    Not Collective, but if SNES object is parallel, then KSP object is parallel
1097c7afd0dbSLois Curfman McInnes 
10989b94acceSBarry Smith    Input Parameter:
10999b94acceSBarry Smith .  snes - the SNES context
11009b94acceSBarry Smith 
11019b94acceSBarry Smith    Output Parameter:
110294b7f48cSBarry Smith .  ksp - the KSP context
11039b94acceSBarry Smith 
11049b94acceSBarry Smith    Notes:
110594b7f48cSBarry Smith    The user can then directly manipulate the KSP context to set various
11069b94acceSBarry Smith    options, etc.  Likewise, the user can then extract and manipulate the
11072999313aSBarry Smith    PC contexts as well.
11089b94acceSBarry Smith 
110936851e7fSLois Curfman McInnes    Level: beginner
111036851e7fSLois Curfman McInnes 
111194b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
11129b94acceSBarry Smith 
11132999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
11149b94acceSBarry Smith @*/
11157087cfbeSBarry Smith PetscErrorCode  SNESGetKSP(SNES snes,KSP *ksp)
11169b94acceSBarry Smith {
11171cee3971SBarry Smith   PetscErrorCode ierr;
11181cee3971SBarry Smith 
11193a40ed3dSBarry Smith   PetscFunctionBegin;
11200700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11214482741eSBarry Smith   PetscValidPointer(ksp,2);
11221cee3971SBarry Smith 
11231cee3971SBarry Smith   if (!snes->ksp) {
11241cee3971SBarry Smith     ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr);
11251cee3971SBarry Smith     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr);
11261cee3971SBarry Smith     ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr);
11271cee3971SBarry Smith   }
112894b7f48cSBarry Smith   *ksp = snes->ksp;
11293a40ed3dSBarry Smith   PetscFunctionReturn(0);
11309b94acceSBarry Smith }
113182bf6240SBarry Smith 
11324a2ae208SSatish Balay #undef __FUNCT__
11332999313aSBarry Smith #define __FUNCT__ "SNESSetKSP"
11342999313aSBarry Smith /*@
11352999313aSBarry Smith    SNESSetKSP - Sets a KSP context for the SNES object to use
11362999313aSBarry Smith 
11372999313aSBarry Smith    Not Collective, but the SNES and KSP objects must live on the same MPI_Comm
11382999313aSBarry Smith 
11392999313aSBarry Smith    Input Parameters:
11402999313aSBarry Smith +  snes - the SNES context
11412999313aSBarry Smith -  ksp - the KSP context
11422999313aSBarry Smith 
11432999313aSBarry Smith    Notes:
11442999313aSBarry Smith    The SNES object already has its KSP object, you can obtain with SNESGetKSP()
11452999313aSBarry Smith    so this routine is rarely needed.
11462999313aSBarry Smith 
11472999313aSBarry Smith    The KSP object that is already in the SNES object has its reference count
11482999313aSBarry Smith    decreased by one.
11492999313aSBarry Smith 
11502999313aSBarry Smith    Level: developer
11512999313aSBarry Smith 
11522999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
11532999313aSBarry Smith 
11542999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
11552999313aSBarry Smith @*/
11567087cfbeSBarry Smith PetscErrorCode  SNESSetKSP(SNES snes,KSP ksp)
11572999313aSBarry Smith {
11582999313aSBarry Smith   PetscErrorCode ierr;
11592999313aSBarry Smith 
11602999313aSBarry Smith   PetscFunctionBegin;
11610700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11620700a824SBarry Smith   PetscValidHeaderSpecific(ksp,KSP_CLASSID,2);
11632999313aSBarry Smith   PetscCheckSameComm(snes,1,ksp,2);
11647dcf0eaaSdalcinl   ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr);
1165906ed7ccSBarry Smith   if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);}
11662999313aSBarry Smith   snes->ksp = ksp;
11672999313aSBarry Smith   PetscFunctionReturn(0);
11682999313aSBarry Smith }
11692999313aSBarry Smith 
11707adad957SLisandro Dalcin #if 0
11712999313aSBarry Smith #undef __FUNCT__
11724a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc"
11736849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj)
1174e24b481bSBarry Smith {
1175e24b481bSBarry Smith   PetscFunctionBegin;
1176e24b481bSBarry Smith   PetscFunctionReturn(0);
1177e24b481bSBarry Smith }
11787adad957SLisandro Dalcin #endif
1179e24b481bSBarry Smith 
11809b94acceSBarry Smith /* -----------------------------------------------------------*/
11814a2ae208SSatish Balay #undef __FUNCT__
11824a2ae208SSatish Balay #define __FUNCT__ "SNESCreate"
118352baeb72SSatish Balay /*@
11849b94acceSBarry Smith    SNESCreate - Creates a nonlinear solver context.
11859b94acceSBarry Smith 
1186c7afd0dbSLois Curfman McInnes    Collective on MPI_Comm
1187c7afd0dbSLois Curfman McInnes 
1188c7afd0dbSLois Curfman McInnes    Input Parameters:
1189906ed7ccSBarry Smith .  comm - MPI communicator
11909b94acceSBarry Smith 
11919b94acceSBarry Smith    Output Parameter:
11929b94acceSBarry Smith .  outsnes - the new SNES context
11939b94acceSBarry Smith 
1194c7afd0dbSLois Curfman McInnes    Options Database Keys:
1195c7afd0dbSLois Curfman McInnes +   -snes_mf - Activates default matrix-free Jacobian-vector products,
1196c7afd0dbSLois Curfman McInnes                and no preconditioning matrix
1197c7afd0dbSLois Curfman McInnes .   -snes_mf_operator - Activates default matrix-free Jacobian-vector
1198c7afd0dbSLois Curfman McInnes                products, and a user-provided preconditioning matrix
1199c7afd0dbSLois Curfman McInnes                as set by SNESSetJacobian()
1200c7afd0dbSLois Curfman McInnes -   -snes_fd - Uses (slow!) finite differences to compute Jacobian
1201c1f60f51SBarry Smith 
120236851e7fSLois Curfman McInnes    Level: beginner
120336851e7fSLois Curfman McInnes 
12049b94acceSBarry Smith .keywords: SNES, nonlinear, create, context
12059b94acceSBarry Smith 
1206a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner()
1207a8054027SBarry Smith 
12089b94acceSBarry Smith @*/
12097087cfbeSBarry Smith PetscErrorCode  SNESCreate(MPI_Comm comm,SNES *outsnes)
12109b94acceSBarry Smith {
1211dfbe8321SBarry Smith   PetscErrorCode      ierr;
12129b94acceSBarry Smith   SNES                snes;
1213fa9f3622SBarry Smith   SNESKSPEW           *kctx;
121437fcc0dbSBarry Smith 
12153a40ed3dSBarry Smith   PetscFunctionBegin;
1216ed1caa07SMatthew Knepley   PetscValidPointer(outsnes,2);
12178ba1e511SMatthew Knepley   *outsnes = PETSC_NULL;
12188ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES
12198ba1e511SMatthew Knepley   ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr);
12208ba1e511SMatthew Knepley #endif
12218ba1e511SMatthew Knepley 
12223194b578SJed Brown   ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr);
12237adad957SLisandro Dalcin 
122485385478SLisandro Dalcin   snes->ops->converged    = SNESDefaultConverged;
12252c155ee1SBarry Smith   snes->usesksp           = PETSC_TRUE;
12269b94acceSBarry Smith   snes->max_its           = 50;
12279750a799SBarry Smith   snes->max_funcs	  = 10000;
12289b94acceSBarry Smith   snes->norm		  = 0.0;
1229b4874afaSBarry Smith   snes->rtol		  = 1.e-8;
1230b4874afaSBarry Smith   snes->ttol              = 0.0;
123170441072SBarry Smith   snes->abstol		  = 1.e-50;
12329b94acceSBarry Smith   snes->xtol		  = 1.e-8;
12334b27c08aSLois Curfman McInnes   snes->deltatol	  = 1.e-12;
12349b94acceSBarry Smith   snes->nfuncs            = 0;
123550ffb88aSMatthew Knepley   snes->numFailures       = 0;
123650ffb88aSMatthew Knepley   snes->maxFailures       = 1;
12377a00f4a9SLois Curfman McInnes   snes->linear_its        = 0;
1238e35cf81dSBarry Smith   snes->lagjacobian       = 1;
1239a8054027SBarry Smith   snes->lagpreconditioner = 1;
1240639f9d9dSBarry Smith   snes->numbermonitors    = 0;
12419b94acceSBarry Smith   snes->data              = 0;
12424dc4c822SBarry Smith   snes->setupcalled       = PETSC_FALSE;
1243186905e3SBarry Smith   snes->ksp_ewconv        = PETSC_FALSE;
12446f24a144SLois Curfman McInnes   snes->nwork             = 0;
124558c9b817SLisandro Dalcin   snes->work              = 0;
124658c9b817SLisandro Dalcin   snes->nvwork            = 0;
124758c9b817SLisandro Dalcin   snes->vwork             = 0;
1248758f92a0SBarry Smith   snes->conv_hist_len     = 0;
1249758f92a0SBarry Smith   snes->conv_hist_max     = 0;
1250758f92a0SBarry Smith   snes->conv_hist         = PETSC_NULL;
1251758f92a0SBarry Smith   snes->conv_hist_its     = PETSC_NULL;
1252758f92a0SBarry Smith   snes->conv_hist_reset   = PETSC_TRUE;
1253184914b5SBarry Smith   snes->reason            = SNES_CONVERGED_ITERATING;
125489b92e6fSPeter Brune   snes->gssweeps          = 1;
12559b94acceSBarry Smith 
1256ea630c6eSPeter Brune   /* initialize the line search options */
1257ea630c6eSPeter Brune   snes->ls_type           = SNES_LS_BASIC;
1258af60355fSPeter Brune   snes->ls_its            = 1;
1259ea630c6eSPeter Brune   snes->damping           = 1.0;
1260ea630c6eSPeter Brune   snes->maxstep           = 1e8;
1261ea630c6eSPeter Brune   snes->steptol           = 1e-12;
1262ea630c6eSPeter Brune   snes->ls_alpha          = 1e-4;
1263ea630c6eSPeter Brune   snes->ls_monitor        = PETSC_NULL;
1264ea630c6eSPeter Brune 
1265ea630c6eSPeter Brune   snes->ops->linesearch   = PETSC_NULL;
1266ea630c6eSPeter Brune   snes->precheck          = PETSC_NULL;
1267ea630c6eSPeter Brune   snes->ops->precheckstep = PETSC_NULL;
1268ea630c6eSPeter Brune   snes->postcheck         = PETSC_NULL;
1269ea630c6eSPeter Brune   snes->ops->postcheckstep= PETSC_NULL;
1270ea630c6eSPeter Brune 
12713d4c4710SBarry Smith   snes->numLinearSolveFailures = 0;
12723d4c4710SBarry Smith   snes->maxLinearSolveFailures = 1;
12733d4c4710SBarry Smith 
12749b94acceSBarry Smith   /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
127538f2d2fdSLisandro Dalcin   ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr);
12769b94acceSBarry Smith   snes->kspconvctx  = (void*)kctx;
12779b94acceSBarry Smith   kctx->version     = 2;
12789b94acceSBarry Smith   kctx->rtol_0      = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
12799b94acceSBarry Smith                              this was too large for some test cases */
128075567043SBarry Smith   kctx->rtol_last   = 0.0;
12819b94acceSBarry Smith   kctx->rtol_max    = .9;
12829b94acceSBarry Smith   kctx->gamma       = 1.0;
128362d1f40fSBarry Smith   kctx->alpha       = .5*(1.0 + PetscSqrtReal(5.0));
128471f87433Sdalcinl   kctx->alpha2      = kctx->alpha;
12859b94acceSBarry Smith   kctx->threshold   = .1;
128675567043SBarry Smith   kctx->lresid_last = 0.0;
128775567043SBarry Smith   kctx->norm_last   = 0.0;
12889b94acceSBarry Smith 
12899b94acceSBarry Smith   *outsnes = snes;
12903a40ed3dSBarry Smith   PetscFunctionReturn(0);
12919b94acceSBarry Smith }
12929b94acceSBarry Smith 
12934a2ae208SSatish Balay #undef __FUNCT__
12944a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction"
12959b94acceSBarry Smith /*@C
12969b94acceSBarry Smith    SNESSetFunction - Sets the function evaluation routine and function
12979b94acceSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
12989b94acceSBarry Smith    equations.
12999b94acceSBarry Smith 
13003f9fe445SBarry Smith    Logically Collective on SNES
1301fee21e36SBarry Smith 
1302c7afd0dbSLois Curfman McInnes    Input Parameters:
1303c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1304c7afd0dbSLois Curfman McInnes .  r - vector to store function value
1305de044059SHong Zhang .  func - function evaluation routine
1306c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
1307c7afd0dbSLois Curfman McInnes          function evaluation routine (may be PETSC_NULL)
13089b94acceSBarry Smith 
1309c7afd0dbSLois Curfman McInnes    Calling sequence of func:
13108d76a1e5SLois Curfman McInnes $    func (SNES snes,Vec x,Vec f,void *ctx);
1311c7afd0dbSLois Curfman McInnes 
1312313e4042SLois Curfman McInnes .  f - function vector
1313c7afd0dbSLois Curfman McInnes -  ctx - optional user-defined function context
13149b94acceSBarry Smith 
13159b94acceSBarry Smith    Notes:
13169b94acceSBarry Smith    The Newton-like methods typically solve linear systems of the form
13179b94acceSBarry Smith $      f'(x) x = -f(x),
1318c7afd0dbSLois Curfman McInnes    where f'(x) denotes the Jacobian matrix and f(x) is the function.
13199b94acceSBarry Smith 
132036851e7fSLois Curfman McInnes    Level: beginner
132136851e7fSLois Curfman McInnes 
13229b94acceSBarry Smith .keywords: SNES, nonlinear, set, function
13239b94acceSBarry Smith 
13248b0a5094SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard()
13259b94acceSBarry Smith @*/
13267087cfbeSBarry Smith PetscErrorCode  SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx)
13279b94acceSBarry Smith {
132885385478SLisandro Dalcin   PetscErrorCode ierr;
1329*6cab3a1bSJed Brown   DM             dm;
1330*6cab3a1bSJed Brown 
13313a40ed3dSBarry Smith   PetscFunctionBegin;
13320700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1333d2a683ecSLisandro Dalcin   if (r) {
1334d2a683ecSLisandro Dalcin     PetscValidHeaderSpecific(r,VEC_CLASSID,2);
1335d2a683ecSLisandro Dalcin     PetscCheckSameComm(snes,1,r,2);
133685385478SLisandro Dalcin     ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr);
13376bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
133885385478SLisandro Dalcin     snes->vec_func = r;
1339d2a683ecSLisandro Dalcin   } else if (!snes->vec_func && snes->dm) {
1340d2a683ecSLisandro Dalcin     ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr);
1341d2a683ecSLisandro Dalcin   }
1342*6cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
1343*6cab3a1bSJed Brown   ierr = DMSNESSetFunction(dm,func,ctx);CHKERRQ(ierr);
13443a40ed3dSBarry Smith   PetscFunctionReturn(0);
13459b94acceSBarry Smith }
13469b94acceSBarry Smith 
1347646217ecSPeter Brune 
1348646217ecSPeter Brune #undef __FUNCT__
1349646217ecSPeter Brune #define __FUNCT__ "SNESSetGS"
1350c79ef259SPeter Brune /*@C
1351c79ef259SPeter Brune    SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for
1352c79ef259SPeter Brune    use with composed nonlinear solvers.
1353c79ef259SPeter Brune 
1354c79ef259SPeter Brune    Input Parameters:
1355c79ef259SPeter Brune +  snes   - the SNES context
1356c79ef259SPeter Brune .  gsfunc - function evaluation routine
1357c79ef259SPeter Brune -  ctx    - [optional] user-defined context for private data for the
1358c79ef259SPeter Brune             smoother evaluation routine (may be PETSC_NULL)
1359c79ef259SPeter Brune 
1360c79ef259SPeter Brune    Calling sequence of func:
1361c79ef259SPeter Brune $    func (SNES snes,Vec x,Vec b,void *ctx);
1362c79ef259SPeter Brune 
1363c79ef259SPeter Brune +  X   - solution vector
1364c79ef259SPeter Brune .  B   - RHS vector
1365d28543b3SPeter Brune -  ctx - optional user-defined Gauss-Seidel context
1366c79ef259SPeter Brune 
1367c79ef259SPeter Brune    Notes:
1368c79ef259SPeter Brune    The GS routines are used by the composed nonlinear solver to generate
1369c79ef259SPeter Brune     a problem appropriate update to the solution, particularly FAS.
1370c79ef259SPeter Brune 
1371d28543b3SPeter Brune    Level: intermediate
1372c79ef259SPeter Brune 
1373d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel
1374c79ef259SPeter Brune 
1375c79ef259SPeter Brune .seealso: SNESGetFunction(), SNESComputeGS()
1376c79ef259SPeter Brune @*/
1377*6cab3a1bSJed Brown PetscErrorCode SNESSetGS(SNES snes,PetscErrorCode (*gsfunc)(SNES,Vec,Vec,void*),void *ctx)
1378*6cab3a1bSJed Brown {
1379*6cab3a1bSJed Brown   PetscErrorCode ierr;
1380*6cab3a1bSJed Brown   DM dm;
1381*6cab3a1bSJed Brown 
1382646217ecSPeter Brune   PetscFunctionBegin;
1383*6cab3a1bSJed Brown   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1384*6cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
1385*6cab3a1bSJed Brown   ierr = DMSNESSetGS(dm,gsfunc,ctx);CHKERRQ(ierr);
1386646217ecSPeter Brune   PetscFunctionReturn(0);
1387646217ecSPeter Brune }
1388646217ecSPeter Brune 
1389d25893d9SBarry Smith #undef __FUNCT__
139089b92e6fSPeter Brune #define __FUNCT__ "SNESSetGSSweeps"
139189b92e6fSPeter Brune /*@
139289b92e6fSPeter Brune    SNESSetGSSweeps - Sets the number of sweeps of GS to use.
139389b92e6fSPeter Brune 
139489b92e6fSPeter Brune    Input Parameters:
139589b92e6fSPeter Brune +  snes   - the SNES context
139689b92e6fSPeter Brune -  sweeps  - the number of sweeps of GS to perform.
139789b92e6fSPeter Brune 
139889b92e6fSPeter Brune    Level: intermediate
139989b92e6fSPeter Brune 
140089b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel
140189b92e6fSPeter Brune 
140289b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGetGSSweeps()
140389b92e6fSPeter Brune @*/
140489b92e6fSPeter Brune 
140589b92e6fSPeter Brune PetscErrorCode SNESSetGSSweeps(SNES snes, PetscInt sweeps) {
140689b92e6fSPeter Brune   PetscFunctionBegin;
140789b92e6fSPeter Brune   snes->gssweeps = sweeps;
140889b92e6fSPeter Brune   PetscFunctionReturn(0);
140989b92e6fSPeter Brune }
141089b92e6fSPeter Brune 
141189b92e6fSPeter Brune 
141289b92e6fSPeter Brune #undef __FUNCT__
141389b92e6fSPeter Brune #define __FUNCT__ "SNESGetGSSweeps"
141489b92e6fSPeter Brune /*@
141589b92e6fSPeter Brune    SNESGetGSSweeps - Gets the number of sweeps GS will use.
141689b92e6fSPeter Brune 
141789b92e6fSPeter Brune    Input Parameters:
141889b92e6fSPeter Brune .  snes   - the SNES context
141989b92e6fSPeter Brune 
142089b92e6fSPeter Brune    Output Parameters:
142189b92e6fSPeter Brune .  sweeps  - the number of sweeps of GS to perform.
142289b92e6fSPeter Brune 
142389b92e6fSPeter Brune    Level: intermediate
142489b92e6fSPeter Brune 
142589b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel
142689b92e6fSPeter Brune 
142789b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESSetGSSweeps()
142889b92e6fSPeter Brune @*/
142989b92e6fSPeter Brune PetscErrorCode SNESGetGSSweeps(SNES snes, PetscInt * sweeps) {
143089b92e6fSPeter Brune   PetscFunctionBegin;
143189b92e6fSPeter Brune   *sweeps = snes->gssweeps;
143289b92e6fSPeter Brune   PetscFunctionReturn(0);
143389b92e6fSPeter Brune }
143489b92e6fSPeter Brune 
143589b92e6fSPeter Brune #undef __FUNCT__
14368b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction"
14378b0a5094SBarry Smith PetscErrorCode  SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx)
14388b0a5094SBarry Smith {
14398b0a5094SBarry Smith   PetscErrorCode ierr;
1440*6cab3a1bSJed Brown   void *functx,*jacctx;
1441*6cab3a1bSJed Brown 
14428b0a5094SBarry Smith   PetscFunctionBegin;
1443*6cab3a1bSJed Brown   ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
1444*6cab3a1bSJed Brown   ierr = SNESGetJacobian(snes,PETSC_NULL,PETSC_NULL,PETSC_NULL,&jacctx);CHKERRQ(ierr);
14458b0a5094SBarry Smith   /*  A(x)*x - b(x) */
1446*6cab3a1bSJed Brown   ierr = (*snes->ops->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,jacctx);CHKERRQ(ierr);
1447*6cab3a1bSJed Brown   ierr = (*snes->ops->computepfunction)(snes,x,f,functx);CHKERRQ(ierr);
14488b0a5094SBarry Smith   ierr = VecView(x,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr);
14498b0a5094SBarry Smith   ierr = VecView(f,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr);
14508b0a5094SBarry Smith   ierr = VecScale(f,-1.0);CHKERRQ(ierr);
14518b0a5094SBarry Smith   ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr);
14528b0a5094SBarry Smith   PetscFunctionReturn(0);
14538b0a5094SBarry Smith }
14548b0a5094SBarry Smith 
14558b0a5094SBarry Smith #undef __FUNCT__
14568b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian"
14578b0a5094SBarry Smith PetscErrorCode  SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx)
14588b0a5094SBarry Smith {
14598b0a5094SBarry Smith   PetscFunctionBegin;
14608b0a5094SBarry Smith   *flag = snes->matstruct;
14618b0a5094SBarry Smith   PetscFunctionReturn(0);
14628b0a5094SBarry Smith }
14638b0a5094SBarry Smith 
14648b0a5094SBarry Smith #undef __FUNCT__
14658b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard"
14668b0a5094SBarry Smith /*@C
14670d04baf8SBarry Smith    SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization)
14688b0a5094SBarry Smith 
14698b0a5094SBarry Smith    Logically Collective on SNES
14708b0a5094SBarry Smith 
14718b0a5094SBarry Smith    Input Parameters:
14728b0a5094SBarry Smith +  snes - the SNES context
14738b0a5094SBarry Smith .  r - vector to store function value
14748b0a5094SBarry Smith .  func - function evaluation routine
14758b0a5094SBarry 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)
14768b0a5094SBarry Smith .  mat - matrix to store A
14778b0a5094SBarry Smith .  mfunc  - function to compute matrix value
14788b0a5094SBarry Smith -  ctx - [optional] user-defined context for private data for the
14798b0a5094SBarry Smith          function evaluation routine (may be PETSC_NULL)
14808b0a5094SBarry Smith 
14818b0a5094SBarry Smith    Calling sequence of func:
14828b0a5094SBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
14838b0a5094SBarry Smith 
14848b0a5094SBarry Smith +  f - function vector
14858b0a5094SBarry Smith -  ctx - optional user-defined function context
14868b0a5094SBarry Smith 
14878b0a5094SBarry Smith    Calling sequence of mfunc:
14888b0a5094SBarry Smith $     mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx);
14898b0a5094SBarry Smith 
14908b0a5094SBarry Smith +  x - input vector
14918b0a5094SBarry 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(),
14928b0a5094SBarry Smith           normally just pass mat in this location
14938b0a5094SBarry Smith .  mat - form A(x) matrix
14948b0a5094SBarry Smith .  flag - flag indicating information about the preconditioner matrix
14958b0a5094SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
14968b0a5094SBarry Smith -  ctx - [optional] user-defined Jacobian context
14978b0a5094SBarry Smith 
14988b0a5094SBarry Smith    Notes:
14998b0a5094SBarry Smith     One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both
15008b0a5094SBarry Smith 
15018b0a5094SBarry 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}
15028b0a5094SBarry 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.
15038b0a5094SBarry Smith 
15048b0a5094SBarry Smith      Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner.
15058b0a5094SBarry Smith 
15060d04baf8SBarry Smith    We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then
15070d04baf8SBarry Smith    the direct Picard iteration A(x^n) x^{n+1} = b(x^n)
15088b0a5094SBarry Smith 
15098b0a5094SBarry 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
15108b0a5094SBarry 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
15118b0a5094SBarry Smith    different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-).
15128b0a5094SBarry Smith 
15138b0a5094SBarry Smith    Level: beginner
15148b0a5094SBarry Smith 
15158b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function
15168b0a5094SBarry Smith 
15170d04baf8SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard()
15188b0a5094SBarry Smith @*/
15198b0a5094SBarry 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)
15208b0a5094SBarry Smith {
15218b0a5094SBarry Smith   PetscErrorCode ierr;
15228b0a5094SBarry Smith   PetscFunctionBegin;
15238b0a5094SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
15248b0a5094SBarry Smith   snes->ops->computepfunction = func;
15258b0a5094SBarry Smith   snes->ops->computepjacobian = mfunc;
15268b0a5094SBarry Smith   ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr);
15278b0a5094SBarry Smith   ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr);
15288b0a5094SBarry Smith   PetscFunctionReturn(0);
15298b0a5094SBarry Smith }
15308b0a5094SBarry Smith 
15318b0a5094SBarry Smith #undef __FUNCT__
1532d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess"
1533d25893d9SBarry Smith /*@C
1534d25893d9SBarry Smith    SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem
1535d25893d9SBarry Smith 
1536d25893d9SBarry Smith    Logically Collective on SNES
1537d25893d9SBarry Smith 
1538d25893d9SBarry Smith    Input Parameters:
1539d25893d9SBarry Smith +  snes - the SNES context
1540d25893d9SBarry Smith .  func - function evaluation routine
1541d25893d9SBarry Smith -  ctx - [optional] user-defined context for private data for the
1542d25893d9SBarry Smith          function evaluation routine (may be PETSC_NULL)
1543d25893d9SBarry Smith 
1544d25893d9SBarry Smith    Calling sequence of func:
1545d25893d9SBarry Smith $    func (SNES snes,Vec x,void *ctx);
1546d25893d9SBarry Smith 
1547d25893d9SBarry Smith .  f - function vector
1548d25893d9SBarry Smith -  ctx - optional user-defined function context
1549d25893d9SBarry Smith 
1550d25893d9SBarry Smith    Level: intermediate
1551d25893d9SBarry Smith 
1552d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function
1553d25893d9SBarry Smith 
1554d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
1555d25893d9SBarry Smith @*/
1556d25893d9SBarry Smith PetscErrorCode  SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx)
1557d25893d9SBarry Smith {
1558d25893d9SBarry Smith   PetscFunctionBegin;
1559d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1560d25893d9SBarry Smith   if (func) snes->ops->computeinitialguess = func;
1561d25893d9SBarry Smith   if (ctx)  snes->initialguessP            = ctx;
1562d25893d9SBarry Smith   PetscFunctionReturn(0);
1563d25893d9SBarry Smith }
1564d25893d9SBarry Smith 
15653ab0aad5SBarry Smith /* --------------------------------------------------------------- */
15663ab0aad5SBarry Smith #undef __FUNCT__
15671096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs"
15681096aae1SMatthew Knepley /*@C
15691096aae1SMatthew Knepley    SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
15701096aae1SMatthew Knepley    it assumes a zero right hand side.
15711096aae1SMatthew Knepley 
15723f9fe445SBarry Smith    Logically Collective on SNES
15731096aae1SMatthew Knepley 
15741096aae1SMatthew Knepley    Input Parameter:
15751096aae1SMatthew Knepley .  snes - the SNES context
15761096aae1SMatthew Knepley 
15771096aae1SMatthew Knepley    Output Parameter:
1578bc08b0f1SBarry Smith .  rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null
15791096aae1SMatthew Knepley 
15801096aae1SMatthew Knepley    Level: intermediate
15811096aae1SMatthew Knepley 
15821096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side
15831096aae1SMatthew Knepley 
158485385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
15851096aae1SMatthew Knepley @*/
15867087cfbeSBarry Smith PetscErrorCode  SNESGetRhs(SNES snes,Vec *rhs)
15871096aae1SMatthew Knepley {
15881096aae1SMatthew Knepley   PetscFunctionBegin;
15890700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
15901096aae1SMatthew Knepley   PetscValidPointer(rhs,2);
159185385478SLisandro Dalcin   *rhs = snes->vec_rhs;
15921096aae1SMatthew Knepley   PetscFunctionReturn(0);
15931096aae1SMatthew Knepley }
15941096aae1SMatthew Knepley 
15951096aae1SMatthew Knepley #undef __FUNCT__
15964a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction"
15979b94acceSBarry Smith /*@
159836851e7fSLois Curfman McInnes    SNESComputeFunction - Calls the function that has been set with
15999b94acceSBarry Smith                          SNESSetFunction().
16009b94acceSBarry Smith 
1601c7afd0dbSLois Curfman McInnes    Collective on SNES
1602c7afd0dbSLois Curfman McInnes 
16039b94acceSBarry Smith    Input Parameters:
1604c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1605c7afd0dbSLois Curfman McInnes -  x - input vector
16069b94acceSBarry Smith 
16079b94acceSBarry Smith    Output Parameter:
16083638b69dSLois Curfman McInnes .  y - function vector, as set by SNESSetFunction()
16099b94acceSBarry Smith 
16101bffabb2SLois Curfman McInnes    Notes:
161136851e7fSLois Curfman McInnes    SNESComputeFunction() is typically used within nonlinear solvers
161236851e7fSLois Curfman McInnes    implementations, so most users would not generally call this routine
161336851e7fSLois Curfman McInnes    themselves.
161436851e7fSLois Curfman McInnes 
161536851e7fSLois Curfman McInnes    Level: developer
161636851e7fSLois Curfman McInnes 
16179b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function
16189b94acceSBarry Smith 
1619a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction()
16209b94acceSBarry Smith @*/
16217087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction(SNES snes,Vec x,Vec y)
16229b94acceSBarry Smith {
1623dfbe8321SBarry Smith   PetscErrorCode ierr;
1624*6cab3a1bSJed Brown   DM             dm;
1625*6cab3a1bSJed Brown   SNESDM         sdm;
16269b94acceSBarry Smith 
16273a40ed3dSBarry Smith   PetscFunctionBegin;
16280700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
16290700a824SBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
16300700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
1631c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,x,2);
1632c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,3);
16334ec14c9cSBarry Smith   VecValidValues(x,2,PETSC_TRUE);
1634184914b5SBarry Smith 
1635*6cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
1636*6cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
1637d5ba7fb7SMatthew Knepley   ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
1638*6cab3a1bSJed Brown   if (sdm->computefunction) {
1639d64ed03dSBarry Smith     PetscStackPush("SNES user function");
1640*6cab3a1bSJed Brown     ierr = (*sdm->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr);
1641d64ed03dSBarry Smith     PetscStackPop;
164273250ac0SBarry Smith   } else if (snes->dm) {
1643644e2e5bSBarry Smith     ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr);
1644c90fad12SPeter Brune   } else if (snes->vec_rhs) {
1645c90fad12SPeter Brune     ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr);
1646644e2e5bSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve().");
164785385478SLisandro Dalcin   if (snes->vec_rhs) {
164885385478SLisandro Dalcin     ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr);
16493ab0aad5SBarry Smith   }
1650ae3c334cSLois Curfman McInnes   snes->nfuncs++;
1651d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
16524ec14c9cSBarry Smith   VecValidValues(y,3,PETSC_FALSE);
16533a40ed3dSBarry Smith   PetscFunctionReturn(0);
16549b94acceSBarry Smith }
16559b94acceSBarry Smith 
16564a2ae208SSatish Balay #undef __FUNCT__
1657646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS"
1658c79ef259SPeter Brune /*@
1659c79ef259SPeter Brune    SNESComputeGS - Calls the Gauss-Seidel function that has been set with
1660c79ef259SPeter Brune                    SNESSetGS().
1661c79ef259SPeter Brune 
1662c79ef259SPeter Brune    Collective on SNES
1663c79ef259SPeter Brune 
1664c79ef259SPeter Brune    Input Parameters:
1665c79ef259SPeter Brune +  snes - the SNES context
1666c79ef259SPeter Brune .  x - input vector
1667c79ef259SPeter Brune -  b - rhs vector
1668c79ef259SPeter Brune 
1669c79ef259SPeter Brune    Output Parameter:
1670c79ef259SPeter Brune .  x - new solution vector
1671c79ef259SPeter Brune 
1672c79ef259SPeter Brune    Notes:
1673c79ef259SPeter Brune    SNESComputeGS() is typically used within composed nonlinear solver
1674c79ef259SPeter Brune    implementations, so most users would not generally call this routine
1675c79ef259SPeter Brune    themselves.
1676c79ef259SPeter Brune 
1677c79ef259SPeter Brune    Level: developer
1678c79ef259SPeter Brune 
1679c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function
1680c79ef259SPeter Brune 
1681c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction()
1682c79ef259SPeter Brune @*/
1683646217ecSPeter Brune PetscErrorCode  SNESComputeGS(SNES snes,Vec b,Vec x)
1684646217ecSPeter Brune {
1685646217ecSPeter Brune   PetscErrorCode ierr;
168689b92e6fSPeter Brune   PetscInt i;
1687*6cab3a1bSJed Brown   DM dm;
1688*6cab3a1bSJed Brown   SNESDM sdm;
1689646217ecSPeter Brune 
1690646217ecSPeter Brune   PetscFunctionBegin;
1691646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1692646217ecSPeter Brune   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
1693646217ecSPeter Brune   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3);
1694646217ecSPeter Brune   PetscCheckSameComm(snes,1,x,2);
1695646217ecSPeter Brune   if(b) PetscCheckSameComm(snes,1,b,3);
16964ec14c9cSBarry Smith   if (b) VecValidValues(b,2,PETSC_TRUE);
1697701cf23dSPeter Brune   ierr = PetscLogEventBegin(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr);
1698*6cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
1699*6cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
1700*6cab3a1bSJed Brown   if (sdm->computegs) {
170189b92e6fSPeter Brune     for (i = 0; i < snes->gssweeps; i++) {
1702646217ecSPeter Brune       PetscStackPush("SNES user GS");
1703*6cab3a1bSJed Brown       ierr = (*sdm->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr);
1704646217ecSPeter Brune       PetscStackPop;
170589b92e6fSPeter Brune     }
1706646217ecSPeter Brune   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve().");
1707701cf23dSPeter Brune   ierr = PetscLogEventEnd(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr);
17084ec14c9cSBarry Smith   VecValidValues(x,3,PETSC_FALSE);
1709646217ecSPeter Brune   PetscFunctionReturn(0);
1710646217ecSPeter Brune }
1711646217ecSPeter Brune 
1712646217ecSPeter Brune 
1713646217ecSPeter Brune #undef __FUNCT__
17144a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian"
171562fef451SLois Curfman McInnes /*@
171662fef451SLois Curfman McInnes    SNESComputeJacobian - Computes the Jacobian matrix that has been
171762fef451SLois Curfman McInnes    set with SNESSetJacobian().
171862fef451SLois Curfman McInnes 
1719c7afd0dbSLois Curfman McInnes    Collective on SNES and Mat
1720c7afd0dbSLois Curfman McInnes 
172162fef451SLois Curfman McInnes    Input Parameters:
1722c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1723c7afd0dbSLois Curfman McInnes -  x - input vector
172462fef451SLois Curfman McInnes 
172562fef451SLois Curfman McInnes    Output Parameters:
1726c7afd0dbSLois Curfman McInnes +  A - Jacobian matrix
172762fef451SLois Curfman McInnes .  B - optional preconditioning matrix
17282b668275SBarry Smith -  flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER)
1729fee21e36SBarry Smith 
1730e35cf81dSBarry Smith   Options Database Keys:
1731e35cf81dSBarry Smith +    -snes_lag_preconditioner <lag>
1732693365a8SJed Brown .    -snes_lag_jacobian <lag>
1733693365a8SJed Brown .    -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences
1734693365a8SJed Brown .    -snes_compare_explicit_draw  - Compare the computed Jacobian to the finite difference Jacobian and draw the result
1735693365a8SJed Brown .    -snes_compare_explicit_contour  - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result
17364c30e9fbSJed Brown .    -snes_compare_operator  - Make the comparison options above use the operator instead of the preconditioning matrix
1737c01495d3SJed Brown .    -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference
1738c01495d3SJed Brown .    -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences
1739c01495d3SJed Brown .    -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold
1740c01495d3SJed Brown .    -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
1741c01495d3SJed Brown .    -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
17424c30e9fbSJed Brown .    -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences
1743c01495d3SJed Brown -    -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences
1744c01495d3SJed Brown 
1745e35cf81dSBarry Smith 
174662fef451SLois Curfman McInnes    Notes:
174762fef451SLois Curfman McInnes    Most users should not need to explicitly call this routine, as it
174862fef451SLois Curfman McInnes    is used internally within the nonlinear solvers.
174962fef451SLois Curfman McInnes 
175094b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the
1751dc5a77f8SLois Curfman McInnes    flag parameter.
175262fef451SLois Curfman McInnes 
175336851e7fSLois Curfman McInnes    Level: developer
175436851e7fSLois Curfman McInnes 
175562fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix
175662fef451SLois Curfman McInnes 
1757e35cf81dSBarry Smith .seealso:  SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian()
175862fef451SLois Curfman McInnes @*/
17597087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg)
17609b94acceSBarry Smith {
1761dfbe8321SBarry Smith   PetscErrorCode ierr;
1762ace3abfcSBarry Smith   PetscBool      flag;
1763*6cab3a1bSJed Brown   DM             dm;
1764*6cab3a1bSJed Brown   SNESDM         sdm;
17653a40ed3dSBarry Smith 
17663a40ed3dSBarry Smith   PetscFunctionBegin;
17670700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
17680700a824SBarry Smith   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
17694482741eSBarry Smith   PetscValidPointer(flg,5);
1770c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,X,2);
17714ec14c9cSBarry Smith   VecValidValues(X,2,PETSC_TRUE);
1772*6cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
1773*6cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
1774*6cab3a1bSJed Brown   if (!sdm->computejacobian) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc");
1775ebd3b9afSBarry Smith 
1776ebd3b9afSBarry Smith   /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */
1777ebd3b9afSBarry Smith 
1778fe3ffe1eSBarry Smith   if (snes->lagjacobian == -2) {
1779fe3ffe1eSBarry Smith     snes->lagjacobian = -1;
1780fe3ffe1eSBarry Smith     ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr);
1781fe3ffe1eSBarry Smith   } else if (snes->lagjacobian == -1) {
1782e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
1783e35cf81dSBarry Smith     ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr);
1784ebd3b9afSBarry Smith     ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
1785ebd3b9afSBarry Smith     if (flag) {
1786ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1787ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1788ebd3b9afSBarry Smith     }
1789e35cf81dSBarry Smith     PetscFunctionReturn(0);
1790e35cf81dSBarry Smith   } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) {
1791e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
1792e35cf81dSBarry Smith     ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr);
1793ebd3b9afSBarry Smith     ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
1794ebd3b9afSBarry Smith     if (flag) {
1795ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1796ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1797ebd3b9afSBarry Smith     }
1798e35cf81dSBarry Smith     PetscFunctionReturn(0);
1799e35cf81dSBarry Smith   }
1800e35cf81dSBarry Smith 
1801c4fc05e7SBarry Smith   *flg = DIFFERENT_NONZERO_PATTERN;
1802e35cf81dSBarry Smith   ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
1803d64ed03dSBarry Smith   PetscStackPush("SNES user Jacobian function");
1804*6cab3a1bSJed Brown   ierr = (*sdm->computejacobian)(snes,X,A,B,flg,sdm->jacobianctx);CHKERRQ(ierr);
1805d64ed03dSBarry Smith   PetscStackPop;
1806d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
1807a8054027SBarry Smith 
18083b4f5425SBarry Smith   if (snes->lagpreconditioner == -2) {
18093b4f5425SBarry Smith     ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr);
18103b4f5425SBarry Smith     snes->lagpreconditioner = -1;
18113b4f5425SBarry Smith   } else if (snes->lagpreconditioner == -1) {
1812a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
1813a8054027SBarry Smith     ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr);
1814a8054027SBarry Smith   } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) {
1815a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
1816a8054027SBarry Smith     ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr);
1817a8054027SBarry Smith   }
1818a8054027SBarry Smith 
18196d84be18SBarry Smith   /* make sure user returned a correct Jacobian and preconditioner */
18200700a824SBarry Smith   /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3);
18210700a824SBarry Smith     PetscValidHeaderSpecific(*B,MAT_CLASSID,4);   */
1822693365a8SJed Brown   {
1823693365a8SJed Brown     PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE;
1824693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr);
1825693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr);
1826693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr);
1827693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr);
1828693365a8SJed Brown     if (flag || flag_draw || flag_contour) {
1829693365a8SJed Brown       Mat Bexp_mine = PETSC_NULL,Bexp,FDexp;
1830693365a8SJed Brown       MatStructure mstruct;
1831693365a8SJed Brown       PetscViewer vdraw,vstdout;
18326b3a5b13SJed Brown       PetscBool flg;
1833693365a8SJed Brown       if (flag_operator) {
1834693365a8SJed Brown         ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr);
1835693365a8SJed Brown         Bexp = Bexp_mine;
1836693365a8SJed Brown       } else {
1837693365a8SJed Brown         /* See if the preconditioning matrix can be viewed and added directly */
1838693365a8SJed Brown         ierr = PetscTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr);
1839693365a8SJed Brown         if (flg) Bexp = *B;
1840693365a8SJed Brown         else {
1841693365a8SJed Brown           /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */
1842693365a8SJed Brown           ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr);
1843693365a8SJed Brown           Bexp = Bexp_mine;
1844693365a8SJed Brown         }
1845693365a8SJed Brown       }
1846693365a8SJed Brown       ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr);
1847693365a8SJed Brown       ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr);
1848693365a8SJed Brown       ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr);
1849693365a8SJed Brown       if (flag_draw || flag_contour) {
1850693365a8SJed Brown         ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
1851693365a8SJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
1852693365a8SJed Brown       } else vdraw = PETSC_NULL;
1853693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr);
1854693365a8SJed Brown       if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);}
1855693365a8SJed Brown       if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);}
1856693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr);
1857693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
1858693365a8SJed Brown       if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);}
1859693365a8SJed Brown       ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
1860693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr);
1861693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
1862693365a8SJed Brown       if (vdraw) {              /* Always use contour for the difference */
1863693365a8SJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
1864693365a8SJed Brown         ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);
1865693365a8SJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
1866693365a8SJed Brown       }
1867693365a8SJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
1868693365a8SJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
1869693365a8SJed Brown       ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr);
1870693365a8SJed Brown       ierr = MatDestroy(&FDexp);CHKERRQ(ierr);
1871693365a8SJed Brown     }
1872693365a8SJed Brown   }
18734c30e9fbSJed Brown   {
18746719d8e4SJed Brown     PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE;
18756719d8e4SJed Brown     PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON;
18764c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr);
18776719d8e4SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr);
18784c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr);
18794c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr);
18806719d8e4SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr);
18816719d8e4SJed Brown     ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr);
18826719d8e4SJed Brown     ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr);
18836719d8e4SJed Brown     if (flag || flag_display || flag_draw || flag_contour || flag_threshold) {
18844c30e9fbSJed Brown       Mat Bfd;
18854c30e9fbSJed Brown       MatStructure mstruct;
18864c30e9fbSJed Brown       PetscViewer vdraw,vstdout;
18874c30e9fbSJed Brown       ISColoring iscoloring;
18884c30e9fbSJed Brown       MatFDColoring matfdcoloring;
18894c30e9fbSJed Brown       PetscErrorCode (*func)(SNES,Vec,Vec,void*);
18904c30e9fbSJed Brown       void *funcctx;
18916719d8e4SJed Brown       PetscReal norm1,norm2,normmax;
18924c30e9fbSJed Brown 
18934c30e9fbSJed Brown       ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr);
18944c30e9fbSJed Brown       ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr);
18954c30e9fbSJed Brown       ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr);
18964c30e9fbSJed Brown       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
18974c30e9fbSJed Brown 
18984c30e9fbSJed Brown       /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */
18994c30e9fbSJed Brown       ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr);
19004c30e9fbSJed Brown       ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr);
19014c30e9fbSJed Brown       ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr);
19024c30e9fbSJed Brown       ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr);
19034c30e9fbSJed Brown       ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr);
19044c30e9fbSJed Brown       ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr);
19054c30e9fbSJed Brown       ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr);
19064c30e9fbSJed Brown 
19074c30e9fbSJed Brown       ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr);
19084c30e9fbSJed Brown       if (flag_draw || flag_contour) {
19094c30e9fbSJed Brown         ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
19104c30e9fbSJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
19114c30e9fbSJed Brown       } else vdraw = PETSC_NULL;
19124c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr);
19136719d8e4SJed Brown       if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);}
19144c30e9fbSJed Brown       if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);}
19154c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr);
19166719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
19174c30e9fbSJed Brown       if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);}
19184c30e9fbSJed Brown       ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
19194c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr);
19206719d8e4SJed Brown       ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr);
19214c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr);
19226719d8e4SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr);
19236719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
19244c30e9fbSJed Brown       if (vdraw) {              /* Always use contour for the difference */
19254c30e9fbSJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
19264c30e9fbSJed Brown         ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);
19274c30e9fbSJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
19284c30e9fbSJed Brown       }
19294c30e9fbSJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
19306719d8e4SJed Brown 
19316719d8e4SJed Brown       if (flag_threshold) {
19326719d8e4SJed Brown         PetscInt bs,rstart,rend,i;
19336719d8e4SJed Brown         ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr);
19346719d8e4SJed Brown         ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr);
19356719d8e4SJed Brown         for (i=rstart; i<rend; i++) {
19366719d8e4SJed Brown           const PetscScalar *ba,*ca;
19376719d8e4SJed Brown           const PetscInt *bj,*cj;
19386719d8e4SJed Brown           PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1;
19396719d8e4SJed Brown           PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0;
19406719d8e4SJed Brown           ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr);
19416719d8e4SJed Brown           ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
19426719d8e4SJed Brown           if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold");
19436719d8e4SJed Brown           for (j=0; j<bn; j++) {
19446719d8e4SJed Brown             PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
19456719d8e4SJed Brown             if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) {
19466719d8e4SJed Brown               maxentrycol = bj[j];
19476719d8e4SJed Brown               maxentry = PetscRealPart(ba[j]);
19486719d8e4SJed Brown             }
19496719d8e4SJed Brown             if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) {
19506719d8e4SJed Brown               maxdiffcol = bj[j];
19516719d8e4SJed Brown               maxdiff = PetscRealPart(ca[j]);
19526719d8e4SJed Brown             }
19536719d8e4SJed Brown             if (rdiff > maxrdiff) {
19546719d8e4SJed Brown               maxrdiffcol = bj[j];
19556719d8e4SJed Brown               maxrdiff = rdiff;
19566719d8e4SJed Brown             }
19576719d8e4SJed Brown           }
19586719d8e4SJed Brown           if (maxrdiff > 1) {
19596719d8e4SJed 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);
19606719d8e4SJed Brown             for (j=0; j<bn; j++) {
19616719d8e4SJed Brown               PetscReal rdiff;
19626719d8e4SJed Brown               rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
19636719d8e4SJed Brown               if (rdiff > 1) {
19646719d8e4SJed Brown                 ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr);
19656719d8e4SJed Brown               }
19666719d8e4SJed Brown             }
19676719d8e4SJed Brown             ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr);
19686719d8e4SJed Brown           }
19696719d8e4SJed Brown           ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr);
19706719d8e4SJed Brown           ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
19716719d8e4SJed Brown         }
19726719d8e4SJed Brown       }
19734c30e9fbSJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
19744c30e9fbSJed Brown       ierr = MatDestroy(&Bfd);CHKERRQ(ierr);
19754c30e9fbSJed Brown     }
19764c30e9fbSJed Brown   }
19773a40ed3dSBarry Smith   PetscFunctionReturn(0);
19789b94acceSBarry Smith }
19799b94acceSBarry Smith 
19804a2ae208SSatish Balay #undef __FUNCT__
19814a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian"
19829b94acceSBarry Smith /*@C
19839b94acceSBarry Smith    SNESSetJacobian - Sets the function to compute Jacobian as well as the
1984044dda88SLois Curfman McInnes    location to store the matrix.
19859b94acceSBarry Smith 
19863f9fe445SBarry Smith    Logically Collective on SNES and Mat
1987c7afd0dbSLois Curfman McInnes 
19889b94acceSBarry Smith    Input Parameters:
1989c7afd0dbSLois Curfman McInnes +  snes - the SNES context
19909b94acceSBarry Smith .  A - Jacobian matrix
19919b94acceSBarry Smith .  B - preconditioner matrix (usually same as the Jacobian)
1992efd51863SBarry Smith .  func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value)
1993c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
1994efd51863SBarry Smith          Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value)
19959b94acceSBarry Smith 
19969b94acceSBarry Smith    Calling sequence of func:
19978d76a1e5SLois Curfman McInnes $     func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx);
19989b94acceSBarry Smith 
1999c7afd0dbSLois Curfman McInnes +  x - input vector
20009b94acceSBarry Smith .  A - Jacobian matrix
20019b94acceSBarry Smith .  B - preconditioner matrix, usually the same as A
2002ac21db08SLois Curfman McInnes .  flag - flag indicating information about the preconditioner matrix
20032b668275SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
2004c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined Jacobian context
20059b94acceSBarry Smith 
20069b94acceSBarry Smith    Notes:
200794b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the flag
20082cd2dfdcSLois Curfman McInnes    output parameter in the routine func().  Be sure to read this information!
2009ac21db08SLois Curfman McInnes 
2010ac21db08SLois Curfman McInnes    The routine func() takes Mat * as the matrix arguments rather than Mat.
20119b94acceSBarry Smith    This allows the Jacobian evaluation routine to replace A and/or B with a
20129b94acceSBarry Smith    completely new new matrix structure (not just different matrix elements)
20139b94acceSBarry Smith    when appropriate, for instance, if the nonzero structure is changing
20149b94acceSBarry Smith    throughout the global iterations.
20159b94acceSBarry Smith 
201616913363SBarry Smith    If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on
201716913363SBarry Smith    each matrix.
201816913363SBarry Smith 
2019a8a26c1eSJed Brown    If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument
2020a8a26c1eSJed Brown    must be a MatFDColoring.
2021a8a26c1eSJed Brown 
2022c3cc8fd1SJed Brown    Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian.  One common
2023c3cc8fd1SJed Brown    example is to use the "Picard linearization" which only differentiates through the highest order parts of each term.
2024c3cc8fd1SJed Brown 
202536851e7fSLois Curfman McInnes    Level: beginner
202636851e7fSLois Curfman McInnes 
20279b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix
20289b94acceSBarry Smith 
20293ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure
20309b94acceSBarry Smith @*/
20317087cfbeSBarry Smith PetscErrorCode  SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
20329b94acceSBarry Smith {
2033dfbe8321SBarry Smith   PetscErrorCode ierr;
2034*6cab3a1bSJed Brown   DM             dm;
20353a7fca6bSBarry Smith 
20363a40ed3dSBarry Smith   PetscFunctionBegin;
20370700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
20380700a824SBarry Smith   if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2);
20390700a824SBarry Smith   if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3);
2040c9780b6fSBarry Smith   if (A) PetscCheckSameComm(snes,1,A,2);
204106975374SJed Brown   if (B) PetscCheckSameComm(snes,1,B,3);
2042*6cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2043*6cab3a1bSJed Brown   ierr = DMSNESSetJacobian(dm,func,ctx);CHKERRQ(ierr);
20443a7fca6bSBarry Smith   if (A) {
20457dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
20466bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
20479b94acceSBarry Smith     snes->jacobian = A;
20483a7fca6bSBarry Smith   }
20493a7fca6bSBarry Smith   if (B) {
20507dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr);
20516bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
20529b94acceSBarry Smith     snes->jacobian_pre = B;
20533a7fca6bSBarry Smith   }
20543a40ed3dSBarry Smith   PetscFunctionReturn(0);
20559b94acceSBarry Smith }
205662fef451SLois Curfman McInnes 
20574a2ae208SSatish Balay #undef __FUNCT__
20584a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian"
2059c2aafc4cSSatish Balay /*@C
2060b4fd4287SBarry Smith    SNESGetJacobian - Returns the Jacobian matrix and optionally the user
2061b4fd4287SBarry Smith    provided context for evaluating the Jacobian.
2062b4fd4287SBarry Smith 
2063c7afd0dbSLois Curfman McInnes    Not Collective, but Mat object will be parallel if SNES object is
2064c7afd0dbSLois Curfman McInnes 
2065b4fd4287SBarry Smith    Input Parameter:
2066b4fd4287SBarry Smith .  snes - the nonlinear solver context
2067b4fd4287SBarry Smith 
2068b4fd4287SBarry Smith    Output Parameters:
2069c7afd0dbSLois Curfman McInnes +  A - location to stash Jacobian matrix (or PETSC_NULL)
2070b4fd4287SBarry Smith .  B - location to stash preconditioner matrix (or PETSC_NULL)
207170e92668SMatthew Knepley .  func - location to put Jacobian function (or PETSC_NULL)
207270e92668SMatthew Knepley -  ctx - location to stash Jacobian ctx (or PETSC_NULL)
2073fee21e36SBarry Smith 
207436851e7fSLois Curfman McInnes    Level: advanced
207536851e7fSLois Curfman McInnes 
2076b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian()
2077b4fd4287SBarry Smith @*/
20787087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
2079b4fd4287SBarry Smith {
2080*6cab3a1bSJed Brown   PetscErrorCode ierr;
2081*6cab3a1bSJed Brown   DM             dm;
2082*6cab3a1bSJed Brown   SNESDM         sdm;
2083*6cab3a1bSJed Brown 
20843a40ed3dSBarry Smith   PetscFunctionBegin;
20850700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2086b4fd4287SBarry Smith   if (A)    *A    = snes->jacobian;
2087b4fd4287SBarry Smith   if (B)    *B    = snes->jacobian_pre;
2088*6cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2089*6cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
2090*6cab3a1bSJed Brown   if (func) *func = sdm->computejacobian;
2091*6cab3a1bSJed Brown   if (ctx)  *ctx  = sdm->jacobianctx;
20923a40ed3dSBarry Smith   PetscFunctionReturn(0);
2093b4fd4287SBarry Smith }
2094b4fd4287SBarry Smith 
20959b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */
20969b94acceSBarry Smith 
20974a2ae208SSatish Balay #undef __FUNCT__
20984a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp"
20999b94acceSBarry Smith /*@
21009b94acceSBarry Smith    SNESSetUp - Sets up the internal data structures for the later use
2101272ac6f2SLois Curfman McInnes    of a nonlinear solver.
21029b94acceSBarry Smith 
2103fee21e36SBarry Smith    Collective on SNES
2104fee21e36SBarry Smith 
2105c7afd0dbSLois Curfman McInnes    Input Parameters:
210670e92668SMatthew Knepley .  snes - the SNES context
2107c7afd0dbSLois Curfman McInnes 
2108272ac6f2SLois Curfman McInnes    Notes:
2109272ac6f2SLois Curfman McInnes    For basic use of the SNES solvers the user need not explicitly call
2110272ac6f2SLois Curfman McInnes    SNESSetUp(), since these actions will automatically occur during
2111272ac6f2SLois Curfman McInnes    the call to SNESSolve().  However, if one wishes to control this
2112272ac6f2SLois Curfman McInnes    phase separately, SNESSetUp() should be called after SNESCreate()
2113272ac6f2SLois Curfman McInnes    and optional routines of the form SNESSetXXX(), but before SNESSolve().
2114272ac6f2SLois Curfman McInnes 
211536851e7fSLois Curfman McInnes    Level: advanced
211636851e7fSLois Curfman McInnes 
21179b94acceSBarry Smith .keywords: SNES, nonlinear, setup
21189b94acceSBarry Smith 
21199b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
21209b94acceSBarry Smith @*/
21217087cfbeSBarry Smith PetscErrorCode  SNESSetUp(SNES snes)
21229b94acceSBarry Smith {
2123dfbe8321SBarry Smith   PetscErrorCode ierr;
2124*6cab3a1bSJed Brown   DM             dm;
2125*6cab3a1bSJed Brown   SNESDM         sdm;
21263a40ed3dSBarry Smith 
21273a40ed3dSBarry Smith   PetscFunctionBegin;
21280700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
21294dc4c822SBarry Smith   if (snes->setupcalled) PetscFunctionReturn(0);
21309b94acceSBarry Smith 
21317adad957SLisandro Dalcin   if (!((PetscObject)snes)->type_name) {
213285385478SLisandro Dalcin     ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr);
213385385478SLisandro Dalcin   }
213485385478SLisandro Dalcin 
2135a63bb30eSJed Brown   ierr = SNESGetFunction(snes,&snes->vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
213617186662SBarry Smith   if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
213758c9b817SLisandro Dalcin   if (snes->vec_rhs  == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector");
213858c9b817SLisandro Dalcin 
213958c9b817SLisandro Dalcin   if (!snes->vec_sol_update /* && snes->vec_sol */) {
214058c9b817SLisandro Dalcin     ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr);
214158c9b817SLisandro Dalcin     ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr);
214258c9b817SLisandro Dalcin   }
214358c9b817SLisandro Dalcin 
2144*6cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2145*6cab3a1bSJed Brown   ierr = DMSNESSetUpLegacy(dm);CHKERRQ(ierr); /* To be removed when function routines are taken out of the DM package */
2146*6cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
2147*6cab3a1bSJed Brown   if (!sdm->computefunction) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction(), DMSNESSetFunction(), DMDASNESSetFunctionLocal(), etc");
2148*6cab3a1bSJed Brown   if (!snes->vec_func) {
2149*6cab3a1bSJed Brown     ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr);
2150214df951SJed Brown   }
2151efd51863SBarry Smith 
2152b710008aSBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);}
2153b710008aSBarry Smith 
2154d25893d9SBarry Smith   if (snes->ops->usercompute && !snes->user) {
2155d25893d9SBarry Smith     ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr);
2156d25893d9SBarry Smith   }
2157d25893d9SBarry Smith 
2158410397dcSLisandro Dalcin   if (snes->ops->setup) {
2159410397dcSLisandro Dalcin     ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr);
2160410397dcSLisandro Dalcin   }
216158c9b817SLisandro Dalcin 
21627aaed0d8SBarry Smith   snes->setupcalled = PETSC_TRUE;
21633a40ed3dSBarry Smith   PetscFunctionReturn(0);
21649b94acceSBarry Smith }
21659b94acceSBarry Smith 
21664a2ae208SSatish Balay #undef __FUNCT__
216737596af1SLisandro Dalcin #define __FUNCT__ "SNESReset"
216837596af1SLisandro Dalcin /*@
216937596af1SLisandro Dalcin    SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats
217037596af1SLisandro Dalcin 
217137596af1SLisandro Dalcin    Collective on SNES
217237596af1SLisandro Dalcin 
217337596af1SLisandro Dalcin    Input Parameter:
217437596af1SLisandro Dalcin .  snes - iterative context obtained from SNESCreate()
217537596af1SLisandro Dalcin 
2176d25893d9SBarry Smith    Level: intermediate
2177d25893d9SBarry Smith 
2178d25893d9SBarry Smith    Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext()
217937596af1SLisandro Dalcin 
218037596af1SLisandro Dalcin .keywords: SNES, destroy
218137596af1SLisandro Dalcin 
218237596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve()
218337596af1SLisandro Dalcin @*/
218437596af1SLisandro Dalcin PetscErrorCode  SNESReset(SNES snes)
218537596af1SLisandro Dalcin {
218637596af1SLisandro Dalcin   PetscErrorCode ierr;
218737596af1SLisandro Dalcin 
218837596af1SLisandro Dalcin   PetscFunctionBegin;
218937596af1SLisandro Dalcin   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2190d25893d9SBarry Smith   if (snes->ops->userdestroy && snes->user) {
2191d25893d9SBarry Smith     ierr       = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr);
2192d25893d9SBarry Smith     snes->user = PETSC_NULL;
2193d25893d9SBarry Smith   }
21948a23116dSBarry Smith   if (snes->pc) {
21958a23116dSBarry Smith     ierr = SNESReset(snes->pc);CHKERRQ(ierr);
21968a23116dSBarry Smith   }
21978a23116dSBarry Smith 
219837596af1SLisandro Dalcin   if (snes->ops->reset) {
219937596af1SLisandro Dalcin     ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr);
220037596af1SLisandro Dalcin   }
220137596af1SLisandro Dalcin   if (snes->ksp) {ierr = KSPReset(snes->ksp);CHKERRQ(ierr);}
22026bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
22036bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
22046bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr);
22056bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
22066bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
22076bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
2208c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);
2209c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);
221037596af1SLisandro Dalcin   snes->nwork = snes->nvwork = 0;
221137596af1SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
221237596af1SLisandro Dalcin   PetscFunctionReturn(0);
221337596af1SLisandro Dalcin }
221437596af1SLisandro Dalcin 
221537596af1SLisandro Dalcin #undef __FUNCT__
22164a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy"
221752baeb72SSatish Balay /*@
22189b94acceSBarry Smith    SNESDestroy - Destroys the nonlinear solver context that was created
22199b94acceSBarry Smith    with SNESCreate().
22209b94acceSBarry Smith 
2221c7afd0dbSLois Curfman McInnes    Collective on SNES
2222c7afd0dbSLois Curfman McInnes 
22239b94acceSBarry Smith    Input Parameter:
22249b94acceSBarry Smith .  snes - the SNES context
22259b94acceSBarry Smith 
222636851e7fSLois Curfman McInnes    Level: beginner
222736851e7fSLois Curfman McInnes 
22289b94acceSBarry Smith .keywords: SNES, nonlinear, destroy
22299b94acceSBarry Smith 
223063a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve()
22319b94acceSBarry Smith @*/
22326bf464f9SBarry Smith PetscErrorCode  SNESDestroy(SNES *snes)
22339b94acceSBarry Smith {
22346849ba73SBarry Smith   PetscErrorCode ierr;
22353a40ed3dSBarry Smith 
22363a40ed3dSBarry Smith   PetscFunctionBegin;
22376bf464f9SBarry Smith   if (!*snes) PetscFunctionReturn(0);
22386bf464f9SBarry Smith   PetscValidHeaderSpecific((*snes),SNES_CLASSID,1);
22396bf464f9SBarry Smith   if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);}
2240d4bb536fSBarry Smith 
22416bf464f9SBarry Smith   ierr = SNESReset((*snes));CHKERRQ(ierr);
22428a23116dSBarry Smith   ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr);
22436b8b9a38SLisandro Dalcin 
2244be0abb6dSBarry Smith   /* if memory was published with AMS then destroy it */
22456bf464f9SBarry Smith   ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr);
22466bf464f9SBarry Smith   if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);}
22476d4c513bSLisandro Dalcin 
22486bf464f9SBarry Smith   ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr);
22496bf464f9SBarry Smith   ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr);
22506b8b9a38SLisandro Dalcin 
22516bf464f9SBarry Smith   ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr);
22526bf464f9SBarry Smith   if ((*snes)->ops->convergeddestroy) {
22536bf464f9SBarry Smith     ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr);
22546b8b9a38SLisandro Dalcin   }
22556bf464f9SBarry Smith   if ((*snes)->conv_malloc) {
22566bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr);
22576bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr);
225858c9b817SLisandro Dalcin   }
2259ea630c6eSPeter Brune   ierr = PetscViewerDestroy(&(*snes)->ls_monitor);CHKERRQ(ierr);
22606bf464f9SBarry Smith   ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr);
2261a79aaaedSSatish Balay   ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr);
22623a40ed3dSBarry Smith  PetscFunctionReturn(0);
22639b94acceSBarry Smith }
22649b94acceSBarry Smith 
22659b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */
22669b94acceSBarry Smith 
22674a2ae208SSatish Balay #undef __FUNCT__
2268a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner"
2269a8054027SBarry Smith /*@
2270a8054027SBarry Smith    SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.
2271a8054027SBarry Smith 
22723f9fe445SBarry Smith    Logically Collective on SNES
2273a8054027SBarry Smith 
2274a8054027SBarry Smith    Input Parameters:
2275a8054027SBarry Smith +  snes - the SNES context
2276a8054027SBarry 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
22773b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2278a8054027SBarry Smith 
2279a8054027SBarry Smith    Options Database Keys:
2280a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2281a8054027SBarry Smith 
2282a8054027SBarry Smith    Notes:
2283a8054027SBarry Smith    The default is 1
2284a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2285a8054027SBarry Smith    If  -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use
2286a8054027SBarry Smith 
2287a8054027SBarry Smith    Level: intermediate
2288a8054027SBarry Smith 
2289a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2290a8054027SBarry Smith 
2291e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2292a8054027SBarry Smith 
2293a8054027SBarry Smith @*/
22947087cfbeSBarry Smith PetscErrorCode  SNESSetLagPreconditioner(SNES snes,PetscInt lag)
2295a8054027SBarry Smith {
2296a8054027SBarry Smith   PetscFunctionBegin;
22970700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2298e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2299e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2300c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2301a8054027SBarry Smith   snes->lagpreconditioner = lag;
2302a8054027SBarry Smith   PetscFunctionReturn(0);
2303a8054027SBarry Smith }
2304a8054027SBarry Smith 
2305a8054027SBarry Smith #undef __FUNCT__
2306efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence"
2307efd51863SBarry Smith /*@
2308efd51863SBarry Smith    SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does
2309efd51863SBarry Smith 
2310efd51863SBarry Smith    Logically Collective on SNES
2311efd51863SBarry Smith 
2312efd51863SBarry Smith    Input Parameters:
2313efd51863SBarry Smith +  snes - the SNES context
2314efd51863SBarry Smith -  steps - the number of refinements to do, defaults to 0
2315efd51863SBarry Smith 
2316efd51863SBarry Smith    Options Database Keys:
2317efd51863SBarry Smith .    -snes_grid_sequence <steps>
2318efd51863SBarry Smith 
2319efd51863SBarry Smith    Level: intermediate
2320efd51863SBarry Smith 
2321c0df2a02SJed Brown    Notes:
2322c0df2a02SJed Brown    Use SNESGetSolution() to extract the fine grid solution after grid sequencing.
2323c0df2a02SJed Brown 
2324efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2325efd51863SBarry Smith 
2326efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2327efd51863SBarry Smith 
2328efd51863SBarry Smith @*/
2329efd51863SBarry Smith PetscErrorCode  SNESSetGridSequence(SNES snes,PetscInt steps)
2330efd51863SBarry Smith {
2331efd51863SBarry Smith   PetscFunctionBegin;
2332efd51863SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2333efd51863SBarry Smith   PetscValidLogicalCollectiveInt(snes,steps,2);
2334efd51863SBarry Smith   snes->gridsequence = steps;
2335efd51863SBarry Smith   PetscFunctionReturn(0);
2336efd51863SBarry Smith }
2337efd51863SBarry Smith 
2338efd51863SBarry Smith #undef __FUNCT__
2339a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner"
2340a8054027SBarry Smith /*@
2341a8054027SBarry Smith    SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt
2342a8054027SBarry Smith 
23433f9fe445SBarry Smith    Not Collective
2344a8054027SBarry Smith 
2345a8054027SBarry Smith    Input Parameter:
2346a8054027SBarry Smith .  snes - the SNES context
2347a8054027SBarry Smith 
2348a8054027SBarry Smith    Output Parameter:
2349a8054027SBarry 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
23503b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2351a8054027SBarry Smith 
2352a8054027SBarry Smith    Options Database Keys:
2353a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2354a8054027SBarry Smith 
2355a8054027SBarry Smith    Notes:
2356a8054027SBarry Smith    The default is 1
2357a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2358a8054027SBarry Smith 
2359a8054027SBarry Smith    Level: intermediate
2360a8054027SBarry Smith 
2361a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2362a8054027SBarry Smith 
2363a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner()
2364a8054027SBarry Smith 
2365a8054027SBarry Smith @*/
23667087cfbeSBarry Smith PetscErrorCode  SNESGetLagPreconditioner(SNES snes,PetscInt *lag)
2367a8054027SBarry Smith {
2368a8054027SBarry Smith   PetscFunctionBegin;
23690700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2370a8054027SBarry Smith   *lag = snes->lagpreconditioner;
2371a8054027SBarry Smith   PetscFunctionReturn(0);
2372a8054027SBarry Smith }
2373a8054027SBarry Smith 
2374a8054027SBarry Smith #undef __FUNCT__
2375e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian"
2376e35cf81dSBarry Smith /*@
2377e35cf81dSBarry Smith    SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how
2378e35cf81dSBarry Smith      often the preconditioner is rebuilt.
2379e35cf81dSBarry Smith 
23803f9fe445SBarry Smith    Logically Collective on SNES
2381e35cf81dSBarry Smith 
2382e35cf81dSBarry Smith    Input Parameters:
2383e35cf81dSBarry Smith +  snes - the SNES context
2384e35cf81dSBarry 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
2385fe3ffe1eSBarry Smith          the Jacobian is built etc. -2 means rebuild at next chance but then never again
2386e35cf81dSBarry Smith 
2387e35cf81dSBarry Smith    Options Database Keys:
2388e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2389e35cf81dSBarry Smith 
2390e35cf81dSBarry Smith    Notes:
2391e35cf81dSBarry Smith    The default is 1
2392e35cf81dSBarry Smith    The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2393fe3ffe1eSBarry 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
2394fe3ffe1eSBarry Smith    at the next Newton step but never again (unless it is reset to another value)
2395e35cf81dSBarry Smith 
2396e35cf81dSBarry Smith    Level: intermediate
2397e35cf81dSBarry Smith 
2398e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2399e35cf81dSBarry Smith 
2400e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian()
2401e35cf81dSBarry Smith 
2402e35cf81dSBarry Smith @*/
24037087cfbeSBarry Smith PetscErrorCode  SNESSetLagJacobian(SNES snes,PetscInt lag)
2404e35cf81dSBarry Smith {
2405e35cf81dSBarry Smith   PetscFunctionBegin;
24060700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2407e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2408e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2409c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2410e35cf81dSBarry Smith   snes->lagjacobian = lag;
2411e35cf81dSBarry Smith   PetscFunctionReturn(0);
2412e35cf81dSBarry Smith }
2413e35cf81dSBarry Smith 
2414e35cf81dSBarry Smith #undef __FUNCT__
2415e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian"
2416e35cf81dSBarry Smith /*@
2417e35cf81dSBarry Smith    SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt
2418e35cf81dSBarry Smith 
24193f9fe445SBarry Smith    Not Collective
2420e35cf81dSBarry Smith 
2421e35cf81dSBarry Smith    Input Parameter:
2422e35cf81dSBarry Smith .  snes - the SNES context
2423e35cf81dSBarry Smith 
2424e35cf81dSBarry Smith    Output Parameter:
2425e35cf81dSBarry 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
2426e35cf81dSBarry Smith          the Jacobian is built etc.
2427e35cf81dSBarry Smith 
2428e35cf81dSBarry Smith    Options Database Keys:
2429e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2430e35cf81dSBarry Smith 
2431e35cf81dSBarry Smith    Notes:
2432e35cf81dSBarry Smith    The default is 1
2433e35cf81dSBarry Smith    The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2434e35cf81dSBarry Smith 
2435e35cf81dSBarry Smith    Level: intermediate
2436e35cf81dSBarry Smith 
2437e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2438e35cf81dSBarry Smith 
2439e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner()
2440e35cf81dSBarry Smith 
2441e35cf81dSBarry Smith @*/
24427087cfbeSBarry Smith PetscErrorCode  SNESGetLagJacobian(SNES snes,PetscInt *lag)
2443e35cf81dSBarry Smith {
2444e35cf81dSBarry Smith   PetscFunctionBegin;
24450700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2446e35cf81dSBarry Smith   *lag = snes->lagjacobian;
2447e35cf81dSBarry Smith   PetscFunctionReturn(0);
2448e35cf81dSBarry Smith }
2449e35cf81dSBarry Smith 
2450e35cf81dSBarry Smith #undef __FUNCT__
24514a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances"
24529b94acceSBarry Smith /*@
2453d7a720efSLois Curfman McInnes    SNESSetTolerances - Sets various parameters used in convergence tests.
24549b94acceSBarry Smith 
24553f9fe445SBarry Smith    Logically Collective on SNES
2456c7afd0dbSLois Curfman McInnes 
24579b94acceSBarry Smith    Input Parameters:
2458c7afd0dbSLois Curfman McInnes +  snes - the SNES context
245970441072SBarry Smith .  abstol - absolute convergence tolerance
246033174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
246133174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
246233174efeSLois Curfman McInnes            of the change in the solution between steps
246333174efeSLois Curfman McInnes .  maxit - maximum number of iterations
2464c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
2465fee21e36SBarry Smith 
246633174efeSLois Curfman McInnes    Options Database Keys:
246770441072SBarry Smith +    -snes_atol <abstol> - Sets abstol
2468c7afd0dbSLois Curfman McInnes .    -snes_rtol <rtol> - Sets rtol
2469c7afd0dbSLois Curfman McInnes .    -snes_stol <stol> - Sets stol
2470c7afd0dbSLois Curfman McInnes .    -snes_max_it <maxit> - Sets maxit
2471c7afd0dbSLois Curfman McInnes -    -snes_max_funcs <maxf> - Sets maxf
24729b94acceSBarry Smith 
2473d7a720efSLois Curfman McInnes    Notes:
24749b94acceSBarry Smith    The default maximum number of iterations is 50.
24759b94acceSBarry Smith    The default maximum number of function evaluations is 1000.
24769b94acceSBarry Smith 
247736851e7fSLois Curfman McInnes    Level: intermediate
247836851e7fSLois Curfman McInnes 
247933174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances
24809b94acceSBarry Smith 
24812492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance()
24829b94acceSBarry Smith @*/
24837087cfbeSBarry Smith PetscErrorCode  SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
24849b94acceSBarry Smith {
24853a40ed3dSBarry Smith   PetscFunctionBegin;
24860700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2487c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,abstol,2);
2488c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol,3);
2489c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,stol,4);
2490c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxit,5);
2491c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxf,6);
2492c5eb9154SBarry Smith 
2493ab54825eSJed Brown   if (abstol != PETSC_DEFAULT) {
2494ab54825eSJed Brown     if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol);
2495ab54825eSJed Brown     snes->abstol = abstol;
2496ab54825eSJed Brown   }
2497ab54825eSJed Brown   if (rtol != PETSC_DEFAULT) {
2498ab54825eSJed 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);
2499ab54825eSJed Brown     snes->rtol = rtol;
2500ab54825eSJed Brown   }
2501ab54825eSJed Brown   if (stol != PETSC_DEFAULT) {
2502ab54825eSJed Brown     if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol);
2503ab54825eSJed Brown     snes->xtol = stol;
2504ab54825eSJed Brown   }
2505ab54825eSJed Brown   if (maxit != PETSC_DEFAULT) {
2506ab54825eSJed Brown     if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit);
2507ab54825eSJed Brown     snes->max_its = maxit;
2508ab54825eSJed Brown   }
2509ab54825eSJed Brown   if (maxf != PETSC_DEFAULT) {
2510ab54825eSJed Brown     if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf);
2511ab54825eSJed Brown     snes->max_funcs = maxf;
2512ab54825eSJed Brown   }
25133a40ed3dSBarry Smith   PetscFunctionReturn(0);
25149b94acceSBarry Smith }
25159b94acceSBarry Smith 
25164a2ae208SSatish Balay #undef __FUNCT__
25174a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances"
25189b94acceSBarry Smith /*@
251933174efeSLois Curfman McInnes    SNESGetTolerances - Gets various parameters used in convergence tests.
252033174efeSLois Curfman McInnes 
2521c7afd0dbSLois Curfman McInnes    Not Collective
2522c7afd0dbSLois Curfman McInnes 
252333174efeSLois Curfman McInnes    Input Parameters:
2524c7afd0dbSLois Curfman McInnes +  snes - the SNES context
252585385478SLisandro Dalcin .  atol - absolute convergence tolerance
252633174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
252733174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
252833174efeSLois Curfman McInnes            of the change in the solution between steps
252933174efeSLois Curfman McInnes .  maxit - maximum number of iterations
2530c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
2531fee21e36SBarry Smith 
253233174efeSLois Curfman McInnes    Notes:
253333174efeSLois Curfman McInnes    The user can specify PETSC_NULL for any parameter that is not needed.
253433174efeSLois Curfman McInnes 
253536851e7fSLois Curfman McInnes    Level: intermediate
253636851e7fSLois Curfman McInnes 
253733174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances
253833174efeSLois Curfman McInnes 
253933174efeSLois Curfman McInnes .seealso: SNESSetTolerances()
254033174efeSLois Curfman McInnes @*/
25417087cfbeSBarry Smith PetscErrorCode  SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
254233174efeSLois Curfman McInnes {
25433a40ed3dSBarry Smith   PetscFunctionBegin;
25440700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
254585385478SLisandro Dalcin   if (atol)  *atol  = snes->abstol;
254633174efeSLois Curfman McInnes   if (rtol)  *rtol  = snes->rtol;
254733174efeSLois Curfman McInnes   if (stol)  *stol  = snes->xtol;
254833174efeSLois Curfman McInnes   if (maxit) *maxit = snes->max_its;
254933174efeSLois Curfman McInnes   if (maxf)  *maxf  = snes->max_funcs;
25503a40ed3dSBarry Smith   PetscFunctionReturn(0);
255133174efeSLois Curfman McInnes }
255233174efeSLois Curfman McInnes 
25534a2ae208SSatish Balay #undef __FUNCT__
25544a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance"
255533174efeSLois Curfman McInnes /*@
25569b94acceSBarry Smith    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
25579b94acceSBarry Smith 
25583f9fe445SBarry Smith    Logically Collective on SNES
2559fee21e36SBarry Smith 
2560c7afd0dbSLois Curfman McInnes    Input Parameters:
2561c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2562c7afd0dbSLois Curfman McInnes -  tol - tolerance
2563c7afd0dbSLois Curfman McInnes 
25649b94acceSBarry Smith    Options Database Key:
2565c7afd0dbSLois Curfman McInnes .  -snes_trtol <tol> - Sets tol
25669b94acceSBarry Smith 
256736851e7fSLois Curfman McInnes    Level: intermediate
256836851e7fSLois Curfman McInnes 
25699b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance
25709b94acceSBarry Smith 
25712492ecdbSBarry Smith .seealso: SNESSetTolerances()
25729b94acceSBarry Smith @*/
25737087cfbeSBarry Smith PetscErrorCode  SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
25749b94acceSBarry Smith {
25753a40ed3dSBarry Smith   PetscFunctionBegin;
25760700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2577c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,tol,2);
25789b94acceSBarry Smith   snes->deltatol = tol;
25793a40ed3dSBarry Smith   PetscFunctionReturn(0);
25809b94acceSBarry Smith }
25819b94acceSBarry Smith 
2582df9fa365SBarry Smith /*
2583df9fa365SBarry Smith    Duplicate the lg monitors for SNES from KSP; for some reason with
2584df9fa365SBarry Smith    dynamic libraries things don't work under Sun4 if we just use
2585df9fa365SBarry Smith    macros instead of functions
2586df9fa365SBarry Smith */
25874a2ae208SSatish Balay #undef __FUNCT__
2588a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG"
25897087cfbeSBarry Smith PetscErrorCode  SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx)
2590ce1608b8SBarry Smith {
2591dfbe8321SBarry Smith   PetscErrorCode ierr;
2592ce1608b8SBarry Smith 
2593ce1608b8SBarry Smith   PetscFunctionBegin;
25940700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2595a6570f20SBarry Smith   ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr);
2596ce1608b8SBarry Smith   PetscFunctionReturn(0);
2597ce1608b8SBarry Smith }
2598ce1608b8SBarry Smith 
25994a2ae208SSatish Balay #undef __FUNCT__
2600a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate"
26017087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2602df9fa365SBarry Smith {
2603dfbe8321SBarry Smith   PetscErrorCode ierr;
2604df9fa365SBarry Smith 
2605df9fa365SBarry Smith   PetscFunctionBegin;
2606a6570f20SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2607df9fa365SBarry Smith   PetscFunctionReturn(0);
2608df9fa365SBarry Smith }
2609df9fa365SBarry Smith 
26104a2ae208SSatish Balay #undef __FUNCT__
2611a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy"
26126bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGDestroy(PetscDrawLG *draw)
2613df9fa365SBarry Smith {
2614dfbe8321SBarry Smith   PetscErrorCode ierr;
2615df9fa365SBarry Smith 
2616df9fa365SBarry Smith   PetscFunctionBegin;
2617a6570f20SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2618df9fa365SBarry Smith   PetscFunctionReturn(0);
2619df9fa365SBarry Smith }
2620df9fa365SBarry Smith 
26217087cfbeSBarry Smith extern PetscErrorCode  SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
2622b271bb04SBarry Smith #undef __FUNCT__
2623b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange"
26247087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx)
2625b271bb04SBarry Smith {
2626b271bb04SBarry Smith   PetscDrawLG      lg;
2627b271bb04SBarry Smith   PetscErrorCode   ierr;
2628b271bb04SBarry Smith   PetscReal        x,y,per;
2629b271bb04SBarry Smith   PetscViewer      v = (PetscViewer)monctx;
2630b271bb04SBarry Smith   static PetscReal prev; /* should be in the context */
2631b271bb04SBarry Smith   PetscDraw        draw;
2632b271bb04SBarry Smith   PetscFunctionBegin;
2633b271bb04SBarry Smith   if (!monctx) {
2634b271bb04SBarry Smith     MPI_Comm    comm;
2635b271bb04SBarry Smith 
2636b271bb04SBarry Smith     ierr   = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
2637b271bb04SBarry Smith     v      = PETSC_VIEWER_DRAW_(comm);
2638b271bb04SBarry Smith   }
2639b271bb04SBarry Smith   ierr   = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr);
2640b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2641b271bb04SBarry Smith   ierr   = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2642b271bb04SBarry Smith   ierr   = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr);
2643b271bb04SBarry Smith   x = (PetscReal) n;
2644b271bb04SBarry Smith   if (rnorm > 0.0) y = log10(rnorm); else y = -15.0;
2645b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2646b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2647b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2648b271bb04SBarry Smith   }
2649b271bb04SBarry Smith 
2650b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr);
2651b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2652b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2653b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr);
2654b271bb04SBarry Smith   ierr =  SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr);
2655b271bb04SBarry Smith   x = (PetscReal) n;
2656b271bb04SBarry Smith   y = 100.0*per;
2657b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2658b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2659b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2660b271bb04SBarry Smith   }
2661b271bb04SBarry Smith 
2662b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr);
2663b271bb04SBarry Smith   if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2664b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2665b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr);
2666b271bb04SBarry Smith   x = (PetscReal) n;
2667b271bb04SBarry Smith   y = (prev - rnorm)/prev;
2668b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2669b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2670b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2671b271bb04SBarry Smith   }
2672b271bb04SBarry Smith 
2673b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr);
2674b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2675b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2676b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr);
2677b271bb04SBarry Smith   x = (PetscReal) n;
2678b271bb04SBarry Smith   y = (prev - rnorm)/(prev*per);
2679b271bb04SBarry Smith   if (n > 2) { /*skip initial crazy value */
2680b271bb04SBarry Smith     ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2681b271bb04SBarry Smith   }
2682b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2683b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2684b271bb04SBarry Smith   }
2685b271bb04SBarry Smith   prev = rnorm;
2686b271bb04SBarry Smith   PetscFunctionReturn(0);
2687b271bb04SBarry Smith }
2688b271bb04SBarry Smith 
2689b271bb04SBarry Smith #undef __FUNCT__
2690b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate"
26917087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2692b271bb04SBarry Smith {
2693b271bb04SBarry Smith   PetscErrorCode ierr;
2694b271bb04SBarry Smith 
2695b271bb04SBarry Smith   PetscFunctionBegin;
2696b271bb04SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2697b271bb04SBarry Smith   PetscFunctionReturn(0);
2698b271bb04SBarry Smith }
2699b271bb04SBarry Smith 
2700b271bb04SBarry Smith #undef __FUNCT__
2701b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy"
27026bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGRangeDestroy(PetscDrawLG *draw)
2703b271bb04SBarry Smith {
2704b271bb04SBarry Smith   PetscErrorCode ierr;
2705b271bb04SBarry Smith 
2706b271bb04SBarry Smith   PetscFunctionBegin;
2707b271bb04SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2708b271bb04SBarry Smith   PetscFunctionReturn(0);
2709b271bb04SBarry Smith }
2710b271bb04SBarry Smith 
27117a03ce2fSLisandro Dalcin #undef __FUNCT__
27127a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor"
2713228d79bcSJed Brown /*@
2714228d79bcSJed Brown    SNESMonitor - runs the user provided monitor routines, if they exist
2715228d79bcSJed Brown 
2716228d79bcSJed Brown    Collective on SNES
2717228d79bcSJed Brown 
2718228d79bcSJed Brown    Input Parameters:
2719228d79bcSJed Brown +  snes - nonlinear solver context obtained from SNESCreate()
2720228d79bcSJed Brown .  iter - iteration number
2721228d79bcSJed Brown -  rnorm - relative norm of the residual
2722228d79bcSJed Brown 
2723228d79bcSJed Brown    Notes:
2724228d79bcSJed Brown    This routine is called by the SNES implementations.
2725228d79bcSJed Brown    It does not typically need to be called by the user.
2726228d79bcSJed Brown 
2727228d79bcSJed Brown    Level: developer
2728228d79bcSJed Brown 
2729228d79bcSJed Brown .seealso: SNESMonitorSet()
2730228d79bcSJed Brown @*/
27317a03ce2fSLisandro Dalcin PetscErrorCode  SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm)
27327a03ce2fSLisandro Dalcin {
27337a03ce2fSLisandro Dalcin   PetscErrorCode ierr;
27347a03ce2fSLisandro Dalcin   PetscInt       i,n = snes->numbermonitors;
27357a03ce2fSLisandro Dalcin 
27367a03ce2fSLisandro Dalcin   PetscFunctionBegin;
27377a03ce2fSLisandro Dalcin   for (i=0; i<n; i++) {
27387a03ce2fSLisandro Dalcin     ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr);
27397a03ce2fSLisandro Dalcin   }
27407a03ce2fSLisandro Dalcin   PetscFunctionReturn(0);
27417a03ce2fSLisandro Dalcin }
27427a03ce2fSLisandro Dalcin 
27439b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */
27449b94acceSBarry Smith 
27454a2ae208SSatish Balay #undef __FUNCT__
2746a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet"
27479b94acceSBarry Smith /*@C
2748a6570f20SBarry Smith    SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
27499b94acceSBarry Smith    iteration of the nonlinear solver to display the iteration's
27509b94acceSBarry Smith    progress.
27519b94acceSBarry Smith 
27523f9fe445SBarry Smith    Logically Collective on SNES
2753fee21e36SBarry Smith 
2754c7afd0dbSLois Curfman McInnes    Input Parameters:
2755c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2756c7afd0dbSLois Curfman McInnes .  func - monitoring routine
2757b8a78c4aSBarry Smith .  mctx - [optional] user-defined context for private data for the
2758e8105e01SRichard Katz           monitor routine (use PETSC_NULL if no context is desired)
2759b3006f0bSLois Curfman McInnes -  monitordestroy - [optional] routine that frees monitor context
2760b3006f0bSLois Curfman McInnes           (may be PETSC_NULL)
27619b94acceSBarry Smith 
2762c7afd0dbSLois Curfman McInnes    Calling sequence of func:
2763a7cc72afSBarry Smith $     int func(SNES snes,PetscInt its, PetscReal norm,void *mctx)
2764c7afd0dbSLois Curfman McInnes 
2765c7afd0dbSLois Curfman McInnes +    snes - the SNES context
2766c7afd0dbSLois Curfman McInnes .    its - iteration number
2767c7afd0dbSLois Curfman McInnes .    norm - 2-norm function value (may be estimated)
276840a0c1c6SLois Curfman McInnes -    mctx - [optional] monitoring context
27699b94acceSBarry Smith 
27709665c990SLois Curfman McInnes    Options Database Keys:
2771a6570f20SBarry Smith +    -snes_monitor        - sets SNESMonitorDefault()
2772a6570f20SBarry Smith .    -snes_monitor_draw    - sets line graph monitor,
2773a6570f20SBarry Smith                             uses SNESMonitorLGCreate()
2774cca6129bSJed Brown -    -snes_monitor_cancel - cancels all monitors that have
2775c7afd0dbSLois Curfman McInnes                             been hardwired into a code by
2776a6570f20SBarry Smith                             calls to SNESMonitorSet(), but
2777c7afd0dbSLois Curfman McInnes                             does not cancel those set via
2778c7afd0dbSLois Curfman McInnes                             the options database.
27799665c990SLois Curfman McInnes 
2780639f9d9dSBarry Smith    Notes:
27816bc08f3fSLois Curfman McInnes    Several different monitoring routines may be set by calling
2782a6570f20SBarry Smith    SNESMonitorSet() multiple times; all will be called in the
27836bc08f3fSLois Curfman McInnes    order in which they were set.
2784639f9d9dSBarry Smith 
2785025f1a04SBarry Smith    Fortran notes: Only a single monitor function can be set for each SNES object
2786025f1a04SBarry Smith 
278736851e7fSLois Curfman McInnes    Level: intermediate
278836851e7fSLois Curfman McInnes 
27899b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor
27909b94acceSBarry Smith 
2791a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel()
27929b94acceSBarry Smith @*/
2793c2efdce3SBarry Smith PetscErrorCode  SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
27949b94acceSBarry Smith {
2795b90d0a6eSBarry Smith   PetscInt       i;
2796649052a6SBarry Smith   PetscErrorCode ierr;
2797b90d0a6eSBarry Smith 
27983a40ed3dSBarry Smith   PetscFunctionBegin;
27990700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
280017186662SBarry Smith   if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
2801b90d0a6eSBarry Smith   for (i=0; i<snes->numbermonitors;i++) {
2802649052a6SBarry Smith     if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) {
2803649052a6SBarry Smith       if (monitordestroy) {
2804c2efdce3SBarry Smith         ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr);
2805649052a6SBarry Smith       }
2806b90d0a6eSBarry Smith       PetscFunctionReturn(0);
2807b90d0a6eSBarry Smith     }
2808b90d0a6eSBarry Smith   }
2809b90d0a6eSBarry Smith   snes->monitor[snes->numbermonitors]           = monitor;
2810b8a78c4aSBarry Smith   snes->monitordestroy[snes->numbermonitors]    = monitordestroy;
2811639f9d9dSBarry Smith   snes->monitorcontext[snes->numbermonitors++]  = (void*)mctx;
28123a40ed3dSBarry Smith   PetscFunctionReturn(0);
28139b94acceSBarry Smith }
28149b94acceSBarry Smith 
28154a2ae208SSatish Balay #undef __FUNCT__
2816a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel"
28175cd90555SBarry Smith /*@C
2818a6570f20SBarry Smith    SNESMonitorCancel - Clears all the monitor functions for a SNES object.
28195cd90555SBarry Smith 
28203f9fe445SBarry Smith    Logically Collective on SNES
2821c7afd0dbSLois Curfman McInnes 
28225cd90555SBarry Smith    Input Parameters:
28235cd90555SBarry Smith .  snes - the SNES context
28245cd90555SBarry Smith 
28251a480d89SAdministrator    Options Database Key:
2826a6570f20SBarry Smith .  -snes_monitor_cancel - cancels all monitors that have been hardwired
2827a6570f20SBarry Smith     into a code by calls to SNESMonitorSet(), but does not cancel those
2828c7afd0dbSLois Curfman McInnes     set via the options database
28295cd90555SBarry Smith 
28305cd90555SBarry Smith    Notes:
28315cd90555SBarry Smith    There is no way to clear one specific monitor from a SNES object.
28325cd90555SBarry Smith 
283336851e7fSLois Curfman McInnes    Level: intermediate
283436851e7fSLois Curfman McInnes 
28355cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor
28365cd90555SBarry Smith 
2837a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet()
28385cd90555SBarry Smith @*/
28397087cfbeSBarry Smith PetscErrorCode  SNESMonitorCancel(SNES snes)
28405cd90555SBarry Smith {
2841d952e501SBarry Smith   PetscErrorCode ierr;
2842d952e501SBarry Smith   PetscInt       i;
2843d952e501SBarry Smith 
28445cd90555SBarry Smith   PetscFunctionBegin;
28450700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2846d952e501SBarry Smith   for (i=0; i<snes->numbermonitors; i++) {
2847d952e501SBarry Smith     if (snes->monitordestroy[i]) {
28483c4aec1bSBarry Smith       ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr);
2849d952e501SBarry Smith     }
2850d952e501SBarry Smith   }
28515cd90555SBarry Smith   snes->numbermonitors = 0;
28525cd90555SBarry Smith   PetscFunctionReturn(0);
28535cd90555SBarry Smith }
28545cd90555SBarry Smith 
28554a2ae208SSatish Balay #undef __FUNCT__
28564a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest"
28579b94acceSBarry Smith /*@C
28589b94acceSBarry Smith    SNESSetConvergenceTest - Sets the function that is to be used
28599b94acceSBarry Smith    to test for convergence of the nonlinear iterative solution.
28609b94acceSBarry Smith 
28613f9fe445SBarry Smith    Logically Collective on SNES
2862fee21e36SBarry Smith 
2863c7afd0dbSLois Curfman McInnes    Input Parameters:
2864c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2865c7afd0dbSLois Curfman McInnes .  func - routine to test for convergence
28667f7931b9SBarry Smith .  cctx - [optional] context for private data for the convergence routine  (may be PETSC_NULL)
28677f7931b9SBarry Smith -  destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran)
28689b94acceSBarry Smith 
2869c7afd0dbSLois Curfman McInnes    Calling sequence of func:
287006ee9f85SBarry Smith $     PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
2871c7afd0dbSLois Curfman McInnes 
2872c7afd0dbSLois Curfman McInnes +    snes - the SNES context
287306ee9f85SBarry Smith .    it - current iteration (0 is the first and is before any Newton step)
2874c7afd0dbSLois Curfman McInnes .    cctx - [optional] convergence context
2875184914b5SBarry Smith .    reason - reason for convergence/divergence
2876c7afd0dbSLois Curfman McInnes .    xnorm - 2-norm of current iterate
28774b27c08aSLois Curfman McInnes .    gnorm - 2-norm of current step
28784b27c08aSLois Curfman McInnes -    f - 2-norm of function
28799b94acceSBarry Smith 
288036851e7fSLois Curfman McInnes    Level: advanced
288136851e7fSLois Curfman McInnes 
28829b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test
28839b94acceSBarry Smith 
288485385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged()
28859b94acceSBarry Smith @*/
28867087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
28879b94acceSBarry Smith {
28887f7931b9SBarry Smith   PetscErrorCode ierr;
28897f7931b9SBarry Smith 
28903a40ed3dSBarry Smith   PetscFunctionBegin;
28910700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
289285385478SLisandro Dalcin   if (!func) func = SNESSkipConverged;
28937f7931b9SBarry Smith   if (snes->ops->convergeddestroy) {
28947f7931b9SBarry Smith     ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr);
28957f7931b9SBarry Smith   }
289685385478SLisandro Dalcin   snes->ops->converged        = func;
28977f7931b9SBarry Smith   snes->ops->convergeddestroy = destroy;
289885385478SLisandro Dalcin   snes->cnvP                  = cctx;
28993a40ed3dSBarry Smith   PetscFunctionReturn(0);
29009b94acceSBarry Smith }
29019b94acceSBarry Smith 
29024a2ae208SSatish Balay #undef __FUNCT__
29034a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason"
290452baeb72SSatish Balay /*@
2905184914b5SBarry Smith    SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
2906184914b5SBarry Smith 
2907184914b5SBarry Smith    Not Collective
2908184914b5SBarry Smith 
2909184914b5SBarry Smith    Input Parameter:
2910184914b5SBarry Smith .  snes - the SNES context
2911184914b5SBarry Smith 
2912184914b5SBarry Smith    Output Parameter:
29134d0a8057SBarry Smith .  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
2914184914b5SBarry Smith             manual pages for the individual convergence tests for complete lists
2915184914b5SBarry Smith 
2916184914b5SBarry Smith    Level: intermediate
2917184914b5SBarry Smith 
2918184914b5SBarry Smith    Notes: Can only be called after the call the SNESSolve() is complete.
2919184914b5SBarry Smith 
2920184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test
2921184914b5SBarry Smith 
292285385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason
2923184914b5SBarry Smith @*/
29247087cfbeSBarry Smith PetscErrorCode  SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
2925184914b5SBarry Smith {
2926184914b5SBarry Smith   PetscFunctionBegin;
29270700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
29284482741eSBarry Smith   PetscValidPointer(reason,2);
2929184914b5SBarry Smith   *reason = snes->reason;
2930184914b5SBarry Smith   PetscFunctionReturn(0);
2931184914b5SBarry Smith }
2932184914b5SBarry Smith 
29334a2ae208SSatish Balay #undef __FUNCT__
29344a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory"
2935c9005455SLois Curfman McInnes /*@
2936c9005455SLois Curfman McInnes    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
2937c9005455SLois Curfman McInnes 
29383f9fe445SBarry Smith    Logically Collective on SNES
2939fee21e36SBarry Smith 
2940c7afd0dbSLois Curfman McInnes    Input Parameters:
2941c7afd0dbSLois Curfman McInnes +  snes - iterative context obtained from SNESCreate()
29428c7482ecSBarry Smith .  a   - array to hold history, this array will contain the function norms computed at each step
2943cd5578b5SBarry Smith .  its - integer array holds the number of linear iterations for each solve.
2944758f92a0SBarry Smith .  na  - size of a and its
294564731454SLois Curfman McInnes -  reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
2946758f92a0SBarry Smith            else it continues storing new values for new nonlinear solves after the old ones
2947c7afd0dbSLois Curfman McInnes 
2948308dcc3eSBarry Smith    Notes:
2949308dcc3eSBarry Smith    If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a
2950308dcc3eSBarry Smith    default array of length 10000 is allocated.
2951308dcc3eSBarry Smith 
2952c9005455SLois Curfman McInnes    This routine is useful, e.g., when running a code for purposes
2953c9005455SLois Curfman McInnes    of accurate performance monitoring, when no I/O should be done
2954c9005455SLois Curfman McInnes    during the section of code that is being timed.
2955c9005455SLois Curfman McInnes 
295636851e7fSLois Curfman McInnes    Level: intermediate
295736851e7fSLois Curfman McInnes 
2958c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history
2959758f92a0SBarry Smith 
296008405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory()
2961758f92a0SBarry Smith 
2962c9005455SLois Curfman McInnes @*/
29637087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool  reset)
2964c9005455SLois Curfman McInnes {
2965308dcc3eSBarry Smith   PetscErrorCode ierr;
2966308dcc3eSBarry Smith 
29673a40ed3dSBarry Smith   PetscFunctionBegin;
29680700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
29694482741eSBarry Smith   if (na)  PetscValidScalarPointer(a,2);
2970a562a398SLisandro Dalcin   if (its) PetscValidIntPointer(its,3);
2971308dcc3eSBarry Smith   if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) {
2972308dcc3eSBarry Smith     if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
2973308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr);
2974308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr);
2975308dcc3eSBarry Smith     snes->conv_malloc   = PETSC_TRUE;
2976308dcc3eSBarry Smith   }
2977c9005455SLois Curfman McInnes   snes->conv_hist       = a;
2978758f92a0SBarry Smith   snes->conv_hist_its   = its;
2979758f92a0SBarry Smith   snes->conv_hist_max   = na;
2980a12bc48fSLisandro Dalcin   snes->conv_hist_len   = 0;
2981758f92a0SBarry Smith   snes->conv_hist_reset = reset;
2982758f92a0SBarry Smith   PetscFunctionReturn(0);
2983758f92a0SBarry Smith }
2984758f92a0SBarry Smith 
2985308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
2986c6db04a5SJed Brown #include <engine.h>   /* MATLAB include file */
2987c6db04a5SJed Brown #include <mex.h>      /* MATLAB include file */
2988308dcc3eSBarry Smith EXTERN_C_BEGIN
2989308dcc3eSBarry Smith #undef __FUNCT__
2990308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab"
2991308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes)
2992308dcc3eSBarry Smith {
2993308dcc3eSBarry Smith   mxArray        *mat;
2994308dcc3eSBarry Smith   PetscInt       i;
2995308dcc3eSBarry Smith   PetscReal      *ar;
2996308dcc3eSBarry Smith 
2997308dcc3eSBarry Smith   PetscFunctionBegin;
2998308dcc3eSBarry Smith   mat  = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL);
2999308dcc3eSBarry Smith   ar   = (PetscReal*) mxGetData(mat);
3000308dcc3eSBarry Smith   for (i=0; i<snes->conv_hist_len; i++) {
3001308dcc3eSBarry Smith     ar[i] = snes->conv_hist[i];
3002308dcc3eSBarry Smith   }
3003308dcc3eSBarry Smith   PetscFunctionReturn(mat);
3004308dcc3eSBarry Smith }
3005308dcc3eSBarry Smith EXTERN_C_END
3006308dcc3eSBarry Smith #endif
3007308dcc3eSBarry Smith 
3008308dcc3eSBarry Smith 
30094a2ae208SSatish Balay #undef __FUNCT__
30104a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory"
30110c4c9dddSBarry Smith /*@C
3012758f92a0SBarry Smith    SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
3013758f92a0SBarry Smith 
30143f9fe445SBarry Smith    Not Collective
3015758f92a0SBarry Smith 
3016758f92a0SBarry Smith    Input Parameter:
3017758f92a0SBarry Smith .  snes - iterative context obtained from SNESCreate()
3018758f92a0SBarry Smith 
3019758f92a0SBarry Smith    Output Parameters:
3020758f92a0SBarry Smith .  a   - array to hold history
3021758f92a0SBarry Smith .  its - integer array holds the number of linear iterations (or
3022758f92a0SBarry Smith          negative if not converged) for each solve.
3023758f92a0SBarry Smith -  na  - size of a and its
3024758f92a0SBarry Smith 
3025758f92a0SBarry Smith    Notes:
3026758f92a0SBarry Smith     The calling sequence for this routine in Fortran is
3027758f92a0SBarry Smith $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
3028758f92a0SBarry Smith 
3029758f92a0SBarry Smith    This routine is useful, e.g., when running a code for purposes
3030758f92a0SBarry Smith    of accurate performance monitoring, when no I/O should be done
3031758f92a0SBarry Smith    during the section of code that is being timed.
3032758f92a0SBarry Smith 
3033758f92a0SBarry Smith    Level: intermediate
3034758f92a0SBarry Smith 
3035758f92a0SBarry Smith .keywords: SNES, get, convergence, history
3036758f92a0SBarry Smith 
3037758f92a0SBarry Smith .seealso: SNESSetConvergencHistory()
3038758f92a0SBarry Smith 
3039758f92a0SBarry Smith @*/
30407087cfbeSBarry Smith PetscErrorCode  SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
3041758f92a0SBarry Smith {
3042758f92a0SBarry Smith   PetscFunctionBegin;
30430700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3044758f92a0SBarry Smith   if (a)   *a   = snes->conv_hist;
3045758f92a0SBarry Smith   if (its) *its = snes->conv_hist_its;
3046758f92a0SBarry Smith   if (na)  *na  = snes->conv_hist_len;
30473a40ed3dSBarry Smith   PetscFunctionReturn(0);
3048c9005455SLois Curfman McInnes }
3049c9005455SLois Curfman McInnes 
3050e74ef692SMatthew Knepley #undef __FUNCT__
3051e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate"
3052ac226902SBarry Smith /*@C
305376b2cf59SMatthew Knepley   SNESSetUpdate - Sets the general-purpose update function called
3054eec8f646SJed Brown   at the beginning of every iteration of the nonlinear solve. Specifically
30557e4bb74cSBarry Smith   it is called just before the Jacobian is "evaluated".
305676b2cf59SMatthew Knepley 
30573f9fe445SBarry Smith   Logically Collective on SNES
305876b2cf59SMatthew Knepley 
305976b2cf59SMatthew Knepley   Input Parameters:
306076b2cf59SMatthew Knepley . snes - The nonlinear solver context
306176b2cf59SMatthew Knepley . func - The function
306276b2cf59SMatthew Knepley 
306376b2cf59SMatthew Knepley   Calling sequence of func:
3064b5d30489SBarry Smith . func (SNES snes, PetscInt step);
306576b2cf59SMatthew Knepley 
306676b2cf59SMatthew Knepley . step - The current step of the iteration
306776b2cf59SMatthew Knepley 
3068fe97e370SBarry Smith   Level: advanced
3069fe97e370SBarry Smith 
3070fe97e370SBarry 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()
3071fe97e370SBarry Smith         This is not used by most users.
307276b2cf59SMatthew Knepley 
307376b2cf59SMatthew Knepley .keywords: SNES, update
3074b5d30489SBarry Smith 
307585385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve()
307676b2cf59SMatthew Knepley @*/
30777087cfbeSBarry Smith PetscErrorCode  SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
307876b2cf59SMatthew Knepley {
307976b2cf59SMatthew Knepley   PetscFunctionBegin;
30800700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID,1);
3081e7788613SBarry Smith   snes->ops->update = func;
308276b2cf59SMatthew Knepley   PetscFunctionReturn(0);
308376b2cf59SMatthew Knepley }
308476b2cf59SMatthew Knepley 
3085e74ef692SMatthew Knepley #undef __FUNCT__
3086e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate"
308776b2cf59SMatthew Knepley /*@
308876b2cf59SMatthew Knepley   SNESDefaultUpdate - The default update function which does nothing.
308976b2cf59SMatthew Knepley 
309076b2cf59SMatthew Knepley   Not collective
309176b2cf59SMatthew Knepley 
309276b2cf59SMatthew Knepley   Input Parameters:
309376b2cf59SMatthew Knepley . snes - The nonlinear solver context
309476b2cf59SMatthew Knepley . step - The current step of the iteration
309576b2cf59SMatthew Knepley 
3096205452f4SMatthew Knepley   Level: intermediate
3097205452f4SMatthew Knepley 
309876b2cf59SMatthew Knepley .keywords: SNES, update
3099a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC()
310076b2cf59SMatthew Knepley @*/
31017087cfbeSBarry Smith PetscErrorCode  SNESDefaultUpdate(SNES snes, PetscInt step)
310276b2cf59SMatthew Knepley {
310376b2cf59SMatthew Knepley   PetscFunctionBegin;
310476b2cf59SMatthew Knepley   PetscFunctionReturn(0);
310576b2cf59SMatthew Knepley }
310676b2cf59SMatthew Knepley 
31074a2ae208SSatish Balay #undef __FUNCT__
31084a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private"
31099b94acceSBarry Smith /*
31109b94acceSBarry Smith    SNESScaleStep_Private - Scales a step so that its length is less than the
31119b94acceSBarry Smith    positive parameter delta.
31129b94acceSBarry Smith 
31139b94acceSBarry Smith     Input Parameters:
3114c7afd0dbSLois Curfman McInnes +   snes - the SNES context
31159b94acceSBarry Smith .   y - approximate solution of linear system
31169b94acceSBarry Smith .   fnorm - 2-norm of current function
3117c7afd0dbSLois Curfman McInnes -   delta - trust region size
31189b94acceSBarry Smith 
31199b94acceSBarry Smith     Output Parameters:
3120c7afd0dbSLois Curfman McInnes +   gpnorm - predicted function norm at the new point, assuming local
31219b94acceSBarry Smith     linearization.  The value is zero if the step lies within the trust
31229b94acceSBarry Smith     region, and exceeds zero otherwise.
3123c7afd0dbSLois Curfman McInnes -   ynorm - 2-norm of the step
31249b94acceSBarry Smith 
31259b94acceSBarry Smith     Note:
31264b27c08aSLois Curfman McInnes     For non-trust region methods such as SNESLS, the parameter delta
31279b94acceSBarry Smith     is set to be the maximum allowable step size.
31289b94acceSBarry Smith 
31299b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step
31309b94acceSBarry Smith */
3131dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
31329b94acceSBarry Smith {
3133064f8208SBarry Smith   PetscReal      nrm;
3134ea709b57SSatish Balay   PetscScalar    cnorm;
3135dfbe8321SBarry Smith   PetscErrorCode ierr;
31363a40ed3dSBarry Smith 
31373a40ed3dSBarry Smith   PetscFunctionBegin;
31380700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
31390700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3140c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,2);
3141184914b5SBarry Smith 
3142064f8208SBarry Smith   ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr);
3143064f8208SBarry Smith   if (nrm > *delta) {
3144064f8208SBarry Smith      nrm = *delta/nrm;
3145064f8208SBarry Smith      *gpnorm = (1.0 - nrm)*(*fnorm);
3146064f8208SBarry Smith      cnorm = nrm;
31472dcb1b2aSMatthew Knepley      ierr = VecScale(y,cnorm);CHKERRQ(ierr);
31489b94acceSBarry Smith      *ynorm = *delta;
31499b94acceSBarry Smith   } else {
31509b94acceSBarry Smith      *gpnorm = 0.0;
3151064f8208SBarry Smith      *ynorm = nrm;
31529b94acceSBarry Smith   }
31533a40ed3dSBarry Smith   PetscFunctionReturn(0);
31549b94acceSBarry Smith }
31559b94acceSBarry Smith 
31564a2ae208SSatish Balay #undef __FUNCT__
31574a2ae208SSatish Balay #define __FUNCT__ "SNESSolve"
31586ce558aeSBarry Smith /*@C
3159f69a0ea3SMatthew Knepley    SNESSolve - Solves a nonlinear system F(x) = b.
3160f69a0ea3SMatthew Knepley    Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
31619b94acceSBarry Smith 
3162c7afd0dbSLois Curfman McInnes    Collective on SNES
3163c7afd0dbSLois Curfman McInnes 
3164b2002411SLois Curfman McInnes    Input Parameters:
3165c7afd0dbSLois Curfman McInnes +  snes - the SNES context
31663cebf274SJed Brown .  b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero.
316785385478SLisandro Dalcin -  x - the solution vector.
31689b94acceSBarry Smith 
3169b2002411SLois Curfman McInnes    Notes:
31708ddd3da0SLois Curfman McInnes    The user should initialize the vector,x, with the initial guess
31718ddd3da0SLois Curfman McInnes    for the nonlinear solve prior to calling SNESSolve.  In particular,
31728ddd3da0SLois Curfman McInnes    to employ an initial guess of zero, the user should explicitly set
31738ddd3da0SLois Curfman McInnes    this vector to zero by calling VecSet().
31748ddd3da0SLois Curfman McInnes 
317536851e7fSLois Curfman McInnes    Level: beginner
317636851e7fSLois Curfman McInnes 
31779b94acceSBarry Smith .keywords: SNES, nonlinear, solve
31789b94acceSBarry Smith 
3179c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution()
31809b94acceSBarry Smith @*/
31817087cfbeSBarry Smith PetscErrorCode  SNESSolve(SNES snes,Vec b,Vec x)
31829b94acceSBarry Smith {
3183dfbe8321SBarry Smith   PetscErrorCode ierr;
3184ace3abfcSBarry Smith   PetscBool      flg;
3185eabae89aSBarry Smith   char           filename[PETSC_MAX_PATH_LEN];
3186eabae89aSBarry Smith   PetscViewer    viewer;
3187efd51863SBarry Smith   PetscInt       grid;
3188a69afd8bSBarry Smith   Vec            xcreated = PETSC_NULL;
3189052efed2SBarry Smith 
31903a40ed3dSBarry Smith   PetscFunctionBegin;
31910700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3192a69afd8bSBarry Smith   if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3193a69afd8bSBarry Smith   if (x) PetscCheckSameComm(snes,1,x,3);
31940700a824SBarry Smith   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2);
319585385478SLisandro Dalcin   if (b) PetscCheckSameComm(snes,1,b,2);
319685385478SLisandro Dalcin 
3197a69afd8bSBarry Smith   if (!x && snes->dm) {
3198a69afd8bSBarry Smith     ierr = DMCreateGlobalVector(snes->dm,&xcreated);CHKERRQ(ierr);
3199a69afd8bSBarry Smith     x    = xcreated;
3200a69afd8bSBarry Smith   }
3201a69afd8bSBarry Smith 
3202a8248277SBarry Smith   for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);}
3203efd51863SBarry Smith   for (grid=0; grid<snes->gridsequence+1; grid++) {
3204efd51863SBarry Smith 
320585385478SLisandro Dalcin     /* set solution vector */
3206efd51863SBarry Smith     if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);}
32076bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
320885385478SLisandro Dalcin     snes->vec_sol = x;
320985385478SLisandro Dalcin     /* set afine vector if provided */
321085385478SLisandro Dalcin     if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); }
32116bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
321285385478SLisandro Dalcin     snes->vec_rhs = b;
321385385478SLisandro Dalcin 
321470e92668SMatthew Knepley     ierr = SNESSetUp(snes);CHKERRQ(ierr);
32153f149594SLisandro Dalcin 
32167eee914bSBarry Smith     if (!grid) {
32177eee914bSBarry Smith       if (snes->ops->computeinitialguess) {
3218d25893d9SBarry Smith         ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr);
3219dd568438SSatish Balay       } else if (snes->dm) {
3220dd568438SSatish Balay         PetscBool ig;
3221dd568438SSatish Balay         ierr = DMHasInitialGuess(snes->dm,&ig);CHKERRQ(ierr);
3222dd568438SSatish Balay         if (ig) {
32237eee914bSBarry Smith           ierr = DMComputeInitialGuess(snes->dm,snes->vec_sol);CHKERRQ(ierr);
32247eee914bSBarry Smith         }
3225d25893d9SBarry Smith       }
3226dd568438SSatish Balay     }
3227d25893d9SBarry Smith 
3228abc0a331SBarry Smith     if (snes->conv_hist_reset) snes->conv_hist_len = 0;
322950ffb88aSMatthew Knepley     snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;
3230d5e45103SBarry Smith 
32313f149594SLisandro Dalcin     ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
32324936397dSBarry Smith     ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr);
323385385478SLisandro Dalcin     ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
32344936397dSBarry Smith     if (snes->domainerror){
32354936397dSBarry Smith       snes->reason      = SNES_DIVERGED_FUNCTION_DOMAIN;
32364936397dSBarry Smith       snes->domainerror = PETSC_FALSE;
32374936397dSBarry Smith     }
323817186662SBarry Smith     if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
32393f149594SLisandro Dalcin 
32407adad957SLisandro Dalcin     ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
3241eabae89aSBarry Smith     if (flg && !PetscPreLoadingOn) {
32427adad957SLisandro Dalcin       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr);
3243eabae89aSBarry Smith       ierr = SNESView(snes,viewer);CHKERRQ(ierr);
32446bf464f9SBarry Smith       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
3245eabae89aSBarry Smith     }
3246eabae89aSBarry Smith 
324790d69ab7SBarry Smith     flg  = PETSC_FALSE;
3248acfcf0e5SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr);
3249da9b6338SBarry Smith     if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); }
32505968eb51SBarry Smith     if (snes->printreason) {
3251a8248277SBarry Smith       ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
32525968eb51SBarry Smith       if (snes->reason > 0) {
3253a8248277SBarry Smith         ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),"Nonlinear solve converged due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr);
32545968eb51SBarry Smith       } else {
3255a8248277SBarry Smith         ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),"Nonlinear solve did not converge due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr);
32565968eb51SBarry Smith       }
3257a8248277SBarry Smith       ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
32585968eb51SBarry Smith     }
32595968eb51SBarry Smith 
32608501fc72SJed Brown     flg = PETSC_FALSE;
32618501fc72SJed Brown     ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
32628501fc72SJed Brown     if (flg) {
32638501fc72SJed Brown       PetscViewer viewer;
32648501fc72SJed Brown       ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr);
32658501fc72SJed Brown       ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr);
32668501fc72SJed Brown       ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr);
32678501fc72SJed Brown       ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr);
32688501fc72SJed Brown       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
32698501fc72SJed Brown     }
32708501fc72SJed Brown 
3271e113a28aSBarry Smith     if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged");
3272efd51863SBarry Smith     if (grid <  snes->gridsequence) {
3273efd51863SBarry Smith       DM  fine;
3274efd51863SBarry Smith       Vec xnew;
3275efd51863SBarry Smith       Mat interp;
3276efd51863SBarry Smith 
3277efd51863SBarry Smith       ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr);
3278e727c939SJed Brown       ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr);
3279efd51863SBarry Smith       ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr);
3280efd51863SBarry Smith       ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr);
3281efd51863SBarry Smith       ierr = MatDestroy(&interp);CHKERRQ(ierr);
3282efd51863SBarry Smith       x    = xnew;
3283efd51863SBarry Smith 
3284efd51863SBarry Smith       ierr = SNESReset(snes);CHKERRQ(ierr);
3285efd51863SBarry Smith       ierr = SNESSetDM(snes,fine);CHKERRQ(ierr);
3286efd51863SBarry Smith       ierr = DMDestroy(&fine);CHKERRQ(ierr);
3287a8248277SBarry Smith       ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);
3288efd51863SBarry Smith     }
3289efd51863SBarry Smith   }
3290a69afd8bSBarry Smith   ierr = VecDestroy(&xcreated);CHKERRQ(ierr);
32913a40ed3dSBarry Smith   PetscFunctionReturn(0);
32929b94acceSBarry Smith }
32939b94acceSBarry Smith 
32949b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */
32959b94acceSBarry Smith 
32964a2ae208SSatish Balay #undef __FUNCT__
32974a2ae208SSatish Balay #define __FUNCT__ "SNESSetType"
329882bf6240SBarry Smith /*@C
32994b0e389bSBarry Smith    SNESSetType - Sets the method for the nonlinear solver.
33009b94acceSBarry Smith 
3301fee21e36SBarry Smith    Collective on SNES
3302fee21e36SBarry Smith 
3303c7afd0dbSLois Curfman McInnes    Input Parameters:
3304c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3305454a90a3SBarry Smith -  type - a known method
3306c7afd0dbSLois Curfman McInnes 
3307c7afd0dbSLois Curfman McInnes    Options Database Key:
3308454a90a3SBarry Smith .  -snes_type <type> - Sets the method; use -help for a list
3309c7afd0dbSLois Curfman McInnes    of available methods (for instance, ls or tr)
3310ae12b187SLois Curfman McInnes 
33119b94acceSBarry Smith    Notes:
3312e090d566SSatish Balay    See "petsc/include/petscsnes.h" for available methods (for instance)
33134b27c08aSLois Curfman McInnes +    SNESLS - Newton's method with line search
3314c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
33154b27c08aSLois Curfman McInnes .    SNESTR - Newton's method with trust region
3316c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
33179b94acceSBarry Smith 
3318ae12b187SLois Curfman McInnes   Normally, it is best to use the SNESSetFromOptions() command and then
3319ae12b187SLois Curfman McInnes   set the SNES solver type from the options database rather than by using
3320ae12b187SLois Curfman McInnes   this routine.  Using the options database provides the user with
3321ae12b187SLois Curfman McInnes   maximum flexibility in evaluating the many nonlinear solvers.
3322ae12b187SLois Curfman McInnes   The SNESSetType() routine is provided for those situations where it
3323ae12b187SLois Curfman McInnes   is necessary to set the nonlinear solver independently of the command
3324ae12b187SLois Curfman McInnes   line or options database.  This might be the case, for example, when
3325ae12b187SLois Curfman McInnes   the choice of solver changes during the execution of the program,
3326ae12b187SLois Curfman McInnes   and the user's application is taking responsibility for choosing the
3327b0a32e0cSBarry Smith   appropriate method.
332836851e7fSLois Curfman McInnes 
332936851e7fSLois Curfman McInnes   Level: intermediate
3330a703fe33SLois Curfman McInnes 
3331454a90a3SBarry Smith .keywords: SNES, set, type
3332435da068SBarry Smith 
3333435da068SBarry Smith .seealso: SNESType, SNESCreate()
3334435da068SBarry Smith 
33359b94acceSBarry Smith @*/
33367087cfbeSBarry Smith PetscErrorCode  SNESSetType(SNES snes,const SNESType type)
33379b94acceSBarry Smith {
3338dfbe8321SBarry Smith   PetscErrorCode ierr,(*r)(SNES);
3339ace3abfcSBarry Smith   PetscBool      match;
33403a40ed3dSBarry Smith 
33413a40ed3dSBarry Smith   PetscFunctionBegin;
33420700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
33434482741eSBarry Smith   PetscValidCharPointer(type,2);
334482bf6240SBarry Smith 
33456831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr);
33460f5bd95cSBarry Smith   if (match) PetscFunctionReturn(0);
334792ff6ae8SBarry Smith 
33484b91b6eaSBarry Smith   ierr =  PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr);
3349e32f2f54SBarry Smith   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
335075396ef9SLisandro Dalcin   /* Destroy the previous private SNES context */
3351b5c23020SJed Brown   if (snes->ops->destroy) {
3352b5c23020SJed Brown     ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr);
3353b5c23020SJed Brown     snes->ops->destroy = PETSC_NULL;
3354b5c23020SJed Brown   }
335575396ef9SLisandro Dalcin   /* Reinitialize function pointers in SNESOps structure */
335675396ef9SLisandro Dalcin   snes->ops->setup          = 0;
335775396ef9SLisandro Dalcin   snes->ops->solve          = 0;
335875396ef9SLisandro Dalcin   snes->ops->view           = 0;
335975396ef9SLisandro Dalcin   snes->ops->setfromoptions = 0;
336075396ef9SLisandro Dalcin   snes->ops->destroy        = 0;
336175396ef9SLisandro Dalcin   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
336275396ef9SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
3363454a90a3SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr);
336403bfa161SLisandro Dalcin   ierr = (*r)(snes);CHKERRQ(ierr);
33659fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS)
33669fb22e1aSBarry Smith   if (PetscAMSPublishAll) {
33679fb22e1aSBarry Smith     ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr);
33689fb22e1aSBarry Smith   }
33699fb22e1aSBarry Smith #endif
33703a40ed3dSBarry Smith   PetscFunctionReturn(0);
33719b94acceSBarry Smith }
33729b94acceSBarry Smith 
3373a847f771SSatish Balay 
33749b94acceSBarry Smith /* --------------------------------------------------------------------- */
33754a2ae208SSatish Balay #undef __FUNCT__
33764a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy"
337752baeb72SSatish Balay /*@
33789b94acceSBarry Smith    SNESRegisterDestroy - Frees the list of nonlinear solvers that were
3379f1af5d2fSBarry Smith    registered by SNESRegisterDynamic().
33809b94acceSBarry Smith 
3381fee21e36SBarry Smith    Not Collective
3382fee21e36SBarry Smith 
338336851e7fSLois Curfman McInnes    Level: advanced
338436851e7fSLois Curfman McInnes 
33859b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy
33869b94acceSBarry Smith 
33879b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll()
33889b94acceSBarry Smith @*/
33897087cfbeSBarry Smith PetscErrorCode  SNESRegisterDestroy(void)
33909b94acceSBarry Smith {
3391dfbe8321SBarry Smith   PetscErrorCode ierr;
339282bf6240SBarry Smith 
33933a40ed3dSBarry Smith   PetscFunctionBegin;
33941441b1d3SBarry Smith   ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr);
33954c49b128SBarry Smith   SNESRegisterAllCalled = PETSC_FALSE;
33963a40ed3dSBarry Smith   PetscFunctionReturn(0);
33979b94acceSBarry Smith }
33989b94acceSBarry Smith 
33994a2ae208SSatish Balay #undef __FUNCT__
34004a2ae208SSatish Balay #define __FUNCT__ "SNESGetType"
34019b94acceSBarry Smith /*@C
34029a28b0a6SLois Curfman McInnes    SNESGetType - Gets the SNES method type and name (as a string).
34039b94acceSBarry Smith 
3404c7afd0dbSLois Curfman McInnes    Not Collective
3405c7afd0dbSLois Curfman McInnes 
34069b94acceSBarry Smith    Input Parameter:
34074b0e389bSBarry Smith .  snes - nonlinear solver context
34089b94acceSBarry Smith 
34099b94acceSBarry Smith    Output Parameter:
34103a7fca6bSBarry Smith .  type - SNES method (a character string)
34119b94acceSBarry Smith 
341236851e7fSLois Curfman McInnes    Level: intermediate
341336851e7fSLois Curfman McInnes 
3414454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name
34159b94acceSBarry Smith @*/
34167087cfbeSBarry Smith PetscErrorCode  SNESGetType(SNES snes,const SNESType *type)
34179b94acceSBarry Smith {
34183a40ed3dSBarry Smith   PetscFunctionBegin;
34190700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
34204482741eSBarry Smith   PetscValidPointer(type,2);
34217adad957SLisandro Dalcin   *type = ((PetscObject)snes)->type_name;
34223a40ed3dSBarry Smith   PetscFunctionReturn(0);
34239b94acceSBarry Smith }
34249b94acceSBarry Smith 
34254a2ae208SSatish Balay #undef __FUNCT__
34264a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution"
342752baeb72SSatish Balay /*@
34289b94acceSBarry Smith    SNESGetSolution - Returns the vector where the approximate solution is
3429c0df2a02SJed Brown    stored. This is the fine grid solution when using SNESSetGridSequence().
34309b94acceSBarry Smith 
3431c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3432c7afd0dbSLois Curfman McInnes 
34339b94acceSBarry Smith    Input Parameter:
34349b94acceSBarry Smith .  snes - the SNES context
34359b94acceSBarry Smith 
34369b94acceSBarry Smith    Output Parameter:
34379b94acceSBarry Smith .  x - the solution
34389b94acceSBarry Smith 
343970e92668SMatthew Knepley    Level: intermediate
344036851e7fSLois Curfman McInnes 
34419b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution
34429b94acceSBarry Smith 
344385385478SLisandro Dalcin .seealso:  SNESGetSolutionUpdate(), SNESGetFunction()
34449b94acceSBarry Smith @*/
34457087cfbeSBarry Smith PetscErrorCode  SNESGetSolution(SNES snes,Vec *x)
34469b94acceSBarry Smith {
34473a40ed3dSBarry Smith   PetscFunctionBegin;
34480700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
34494482741eSBarry Smith   PetscValidPointer(x,2);
345085385478SLisandro Dalcin   *x = snes->vec_sol;
345170e92668SMatthew Knepley   PetscFunctionReturn(0);
345270e92668SMatthew Knepley }
345370e92668SMatthew Knepley 
345470e92668SMatthew Knepley #undef __FUNCT__
34554a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate"
345652baeb72SSatish Balay /*@
34579b94acceSBarry Smith    SNESGetSolutionUpdate - Returns the vector where the solution update is
34589b94acceSBarry Smith    stored.
34599b94acceSBarry Smith 
3460c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3461c7afd0dbSLois Curfman McInnes 
34629b94acceSBarry Smith    Input Parameter:
34639b94acceSBarry Smith .  snes - the SNES context
34649b94acceSBarry Smith 
34659b94acceSBarry Smith    Output Parameter:
34669b94acceSBarry Smith .  x - the solution update
34679b94acceSBarry Smith 
346836851e7fSLois Curfman McInnes    Level: advanced
346936851e7fSLois Curfman McInnes 
34709b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update
34719b94acceSBarry Smith 
347285385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction()
34739b94acceSBarry Smith @*/
34747087cfbeSBarry Smith PetscErrorCode  SNESGetSolutionUpdate(SNES snes,Vec *x)
34759b94acceSBarry Smith {
34763a40ed3dSBarry Smith   PetscFunctionBegin;
34770700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
34784482741eSBarry Smith   PetscValidPointer(x,2);
347985385478SLisandro Dalcin   *x = snes->vec_sol_update;
34803a40ed3dSBarry Smith   PetscFunctionReturn(0);
34819b94acceSBarry Smith }
34829b94acceSBarry Smith 
34834a2ae208SSatish Balay #undef __FUNCT__
34844a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction"
34859b94acceSBarry Smith /*@C
34863638b69dSLois Curfman McInnes    SNESGetFunction - Returns the vector where the function is stored.
34879b94acceSBarry Smith 
3488a63bb30eSJed Brown    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
3489c7afd0dbSLois Curfman McInnes 
34909b94acceSBarry Smith    Input Parameter:
34919b94acceSBarry Smith .  snes - the SNES context
34929b94acceSBarry Smith 
34939b94acceSBarry Smith    Output Parameter:
34947bf4e008SBarry Smith +  r - the function (or PETSC_NULL)
349570e92668SMatthew Knepley .  func - the function (or PETSC_NULL)
349670e92668SMatthew Knepley -  ctx - the function context (or PETSC_NULL)
34979b94acceSBarry Smith 
349836851e7fSLois Curfman McInnes    Level: advanced
349936851e7fSLois Curfman McInnes 
3500a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function
35019b94acceSBarry Smith 
35024b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution()
35039b94acceSBarry Smith @*/
35047087cfbeSBarry Smith PetscErrorCode  SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
35059b94acceSBarry Smith {
3506a63bb30eSJed Brown   PetscErrorCode ierr;
3507*6cab3a1bSJed Brown   DM             dm;
3508a63bb30eSJed Brown 
35093a40ed3dSBarry Smith   PetscFunctionBegin;
35100700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3511a63bb30eSJed Brown   if (r) {
3512a63bb30eSJed Brown     if (!snes->vec_func) {
3513a63bb30eSJed Brown       if (snes->vec_rhs) {
3514a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr);
3515a63bb30eSJed Brown       } else if (snes->vec_sol) {
3516a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr);
3517a63bb30eSJed Brown       } else if (snes->dm) {
3518a63bb30eSJed Brown         ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr);
3519a63bb30eSJed Brown       }
3520a63bb30eSJed Brown     }
3521a63bb30eSJed Brown     *r = snes->vec_func;
3522a63bb30eSJed Brown   }
3523*6cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3524*6cab3a1bSJed Brown   ierr = DMSNESGetFunction(dm,func,ctx);CHKERRQ(ierr);
35253a40ed3dSBarry Smith   PetscFunctionReturn(0);
35269b94acceSBarry Smith }
35279b94acceSBarry Smith 
3528c79ef259SPeter Brune /*@C
3529c79ef259SPeter Brune    SNESGetGS - Returns the GS function and context.
3530c79ef259SPeter Brune 
3531c79ef259SPeter Brune    Input Parameter:
3532c79ef259SPeter Brune .  snes - the SNES context
3533c79ef259SPeter Brune 
3534c79ef259SPeter Brune    Output Parameter:
3535c79ef259SPeter Brune +  gsfunc - the function (or PETSC_NULL)
3536c79ef259SPeter Brune -  ctx    - the function context (or PETSC_NULL)
3537c79ef259SPeter Brune 
3538c79ef259SPeter Brune    Level: advanced
3539c79ef259SPeter Brune 
3540c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function
3541c79ef259SPeter Brune 
3542c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction()
3543c79ef259SPeter Brune @*/
3544c79ef259SPeter Brune 
35454a2ae208SSatish Balay #undef __FUNCT__
3546646217ecSPeter Brune #define __FUNCT__ "SNESGetGS"
3547646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx)
3548646217ecSPeter Brune {
3549*6cab3a1bSJed Brown   PetscErrorCode ierr;
3550*6cab3a1bSJed Brown   DM             dm;
3551*6cab3a1bSJed Brown 
3552646217ecSPeter Brune   PetscFunctionBegin;
3553646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3554*6cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3555*6cab3a1bSJed Brown   ierr = DMSNESGetGS(dm,func,ctx);CHKERRQ(ierr);
3556646217ecSPeter Brune   PetscFunctionReturn(0);
3557646217ecSPeter Brune }
3558646217ecSPeter Brune 
35594a2ae208SSatish Balay #undef __FUNCT__
35604a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix"
35613c7409f5SSatish Balay /*@C
35623c7409f5SSatish Balay    SNESSetOptionsPrefix - Sets the prefix used for searching for all
3563d850072dSLois Curfman McInnes    SNES options in the database.
35643c7409f5SSatish Balay 
35653f9fe445SBarry Smith    Logically Collective on SNES
3566fee21e36SBarry Smith 
3567c7afd0dbSLois Curfman McInnes    Input Parameter:
3568c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3569c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3570c7afd0dbSLois Curfman McInnes 
3571d850072dSLois Curfman McInnes    Notes:
3572a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
3573c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
3574d850072dSLois Curfman McInnes 
357536851e7fSLois Curfman McInnes    Level: advanced
357636851e7fSLois Curfman McInnes 
35773c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database
3578a86d99e1SLois Curfman McInnes 
3579a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions()
35803c7409f5SSatish Balay @*/
35817087cfbeSBarry Smith PetscErrorCode  SNESSetOptionsPrefix(SNES snes,const char prefix[])
35823c7409f5SSatish Balay {
3583dfbe8321SBarry Smith   PetscErrorCode ierr;
35843c7409f5SSatish Balay 
35853a40ed3dSBarry Smith   PetscFunctionBegin;
35860700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3587639f9d9dSBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
35881cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
358994b7f48cSBarry Smith   ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
35903a40ed3dSBarry Smith   PetscFunctionReturn(0);
35913c7409f5SSatish Balay }
35923c7409f5SSatish Balay 
35934a2ae208SSatish Balay #undef __FUNCT__
35944a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix"
35953c7409f5SSatish Balay /*@C
3596f525115eSLois Curfman McInnes    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
3597d850072dSLois Curfman McInnes    SNES options in the database.
35983c7409f5SSatish Balay 
35993f9fe445SBarry Smith    Logically Collective on SNES
3600fee21e36SBarry Smith 
3601c7afd0dbSLois Curfman McInnes    Input Parameters:
3602c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3603c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3604c7afd0dbSLois Curfman McInnes 
3605d850072dSLois Curfman McInnes    Notes:
3606a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
3607c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
3608d850072dSLois Curfman McInnes 
360936851e7fSLois Curfman McInnes    Level: advanced
361036851e7fSLois Curfman McInnes 
36113c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database
3612a86d99e1SLois Curfman McInnes 
3613a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix()
36143c7409f5SSatish Balay @*/
36157087cfbeSBarry Smith PetscErrorCode  SNESAppendOptionsPrefix(SNES snes,const char prefix[])
36163c7409f5SSatish Balay {
3617dfbe8321SBarry Smith   PetscErrorCode ierr;
36183c7409f5SSatish Balay 
36193a40ed3dSBarry Smith   PetscFunctionBegin;
36200700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3621639f9d9dSBarry Smith   ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
36221cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
362394b7f48cSBarry Smith   ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
36243a40ed3dSBarry Smith   PetscFunctionReturn(0);
36253c7409f5SSatish Balay }
36263c7409f5SSatish Balay 
36274a2ae208SSatish Balay #undef __FUNCT__
36284a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix"
36299ab63eb5SSatish Balay /*@C
36303c7409f5SSatish Balay    SNESGetOptionsPrefix - Sets the prefix used for searching for all
36313c7409f5SSatish Balay    SNES options in the database.
36323c7409f5SSatish Balay 
3633c7afd0dbSLois Curfman McInnes    Not Collective
3634c7afd0dbSLois Curfman McInnes 
36353c7409f5SSatish Balay    Input Parameter:
36363c7409f5SSatish Balay .  snes - the SNES context
36373c7409f5SSatish Balay 
36383c7409f5SSatish Balay    Output Parameter:
36393c7409f5SSatish Balay .  prefix - pointer to the prefix string used
36403c7409f5SSatish Balay 
36414ef407dbSRichard Tran Mills    Notes: On the fortran side, the user should pass in a string 'prefix' of
36429ab63eb5SSatish Balay    sufficient length to hold the prefix.
36439ab63eb5SSatish Balay 
364436851e7fSLois Curfman McInnes    Level: advanced
364536851e7fSLois Curfman McInnes 
36463c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database
3647a86d99e1SLois Curfman McInnes 
3648a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix()
36493c7409f5SSatish Balay @*/
36507087cfbeSBarry Smith PetscErrorCode  SNESGetOptionsPrefix(SNES snes,const char *prefix[])
36513c7409f5SSatish Balay {
3652dfbe8321SBarry Smith   PetscErrorCode ierr;
36533c7409f5SSatish Balay 
36543a40ed3dSBarry Smith   PetscFunctionBegin;
36550700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3656639f9d9dSBarry Smith   ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
36573a40ed3dSBarry Smith   PetscFunctionReturn(0);
36583c7409f5SSatish Balay }
36593c7409f5SSatish Balay 
3660b2002411SLois Curfman McInnes 
36614a2ae208SSatish Balay #undef __FUNCT__
36624a2ae208SSatish Balay #define __FUNCT__ "SNESRegister"
36633cea93caSBarry Smith /*@C
36643cea93caSBarry Smith   SNESRegister - See SNESRegisterDynamic()
36653cea93caSBarry Smith 
36667f6c08e0SMatthew Knepley   Level: advanced
36673cea93caSBarry Smith @*/
36687087cfbeSBarry Smith PetscErrorCode  SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES))
3669b2002411SLois Curfman McInnes {
3670e2d1d2b7SBarry Smith   char           fullname[PETSC_MAX_PATH_LEN];
3671dfbe8321SBarry Smith   PetscErrorCode ierr;
3672b2002411SLois Curfman McInnes 
3673b2002411SLois Curfman McInnes   PetscFunctionBegin;
3674b0a32e0cSBarry Smith   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
3675c134de8dSSatish Balay   ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
3676b2002411SLois Curfman McInnes   PetscFunctionReturn(0);
3677b2002411SLois Curfman McInnes }
3678da9b6338SBarry Smith 
3679da9b6338SBarry Smith #undef __FUNCT__
3680da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin"
36817087cfbeSBarry Smith PetscErrorCode  SNESTestLocalMin(SNES snes)
3682da9b6338SBarry Smith {
3683dfbe8321SBarry Smith   PetscErrorCode ierr;
368477431f27SBarry Smith   PetscInt       N,i,j;
3685da9b6338SBarry Smith   Vec            u,uh,fh;
3686da9b6338SBarry Smith   PetscScalar    value;
3687da9b6338SBarry Smith   PetscReal      norm;
3688da9b6338SBarry Smith 
3689da9b6338SBarry Smith   PetscFunctionBegin;
3690da9b6338SBarry Smith   ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr);
3691da9b6338SBarry Smith   ierr = VecDuplicate(u,&uh);CHKERRQ(ierr);
3692da9b6338SBarry Smith   ierr = VecDuplicate(u,&fh);CHKERRQ(ierr);
3693da9b6338SBarry Smith 
3694da9b6338SBarry Smith   /* currently only works for sequential */
3695da9b6338SBarry Smith   ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");
3696da9b6338SBarry Smith   ierr = VecGetSize(u,&N);CHKERRQ(ierr);
3697da9b6338SBarry Smith   for (i=0; i<N; i++) {
3698da9b6338SBarry Smith     ierr = VecCopy(u,uh);CHKERRQ(ierr);
369977431f27SBarry Smith     ierr  = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr);
3700da9b6338SBarry Smith     for (j=-10; j<11; j++) {
3701ccae9161SBarry Smith       value = PetscSign(j)*exp(PetscAbs(j)-10.0);
3702da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
37033ab0aad5SBarry Smith       ierr  = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr);
3704da9b6338SBarry Smith       ierr  = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr);
370577431f27SBarry Smith       ierr  = PetscPrintf(PETSC_COMM_WORLD,"       j norm %D %18.16e\n",j,norm);CHKERRQ(ierr);
3706da9b6338SBarry Smith       value = -value;
3707da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
3708da9b6338SBarry Smith     }
3709da9b6338SBarry Smith   }
37106bf464f9SBarry Smith   ierr = VecDestroy(&uh);CHKERRQ(ierr);
37116bf464f9SBarry Smith   ierr = VecDestroy(&fh);CHKERRQ(ierr);
3712da9b6338SBarry Smith   PetscFunctionReturn(0);
3713da9b6338SBarry Smith }
371471f87433Sdalcinl 
371571f87433Sdalcinl #undef __FUNCT__
3716fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW"
371771f87433Sdalcinl /*@
3718fa9f3622SBarry Smith    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
371971f87433Sdalcinl    computing relative tolerance for linear solvers within an inexact
372071f87433Sdalcinl    Newton method.
372171f87433Sdalcinl 
37223f9fe445SBarry Smith    Logically Collective on SNES
372371f87433Sdalcinl 
372471f87433Sdalcinl    Input Parameters:
372571f87433Sdalcinl +  snes - SNES context
372671f87433Sdalcinl -  flag - PETSC_TRUE or PETSC_FALSE
372771f87433Sdalcinl 
372864ba62caSBarry Smith     Options Database:
372964ba62caSBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
373064ba62caSBarry Smith .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
373164ba62caSBarry Smith .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
373264ba62caSBarry Smith .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
373364ba62caSBarry Smith .  -snes_ksp_ew_gamma <gamma> - Sets gamma
373464ba62caSBarry Smith .  -snes_ksp_ew_alpha <alpha> - Sets alpha
373564ba62caSBarry Smith .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
373664ba62caSBarry Smith -  -snes_ksp_ew_threshold <threshold> - Sets threshold
373764ba62caSBarry Smith 
373871f87433Sdalcinl    Notes:
373971f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
374071f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
374171f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
374271f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
374371f87433Sdalcinl    solver.
374471f87433Sdalcinl 
374571f87433Sdalcinl    Level: advanced
374671f87433Sdalcinl 
374771f87433Sdalcinl    Reference:
374871f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
374971f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
375071f87433Sdalcinl 
375171f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
375271f87433Sdalcinl 
3753fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
375471f87433Sdalcinl @*/
37557087cfbeSBarry Smith PetscErrorCode  SNESKSPSetUseEW(SNES snes,PetscBool  flag)
375671f87433Sdalcinl {
375771f87433Sdalcinl   PetscFunctionBegin;
37580700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3759acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flag,2);
376071f87433Sdalcinl   snes->ksp_ewconv = flag;
376171f87433Sdalcinl   PetscFunctionReturn(0);
376271f87433Sdalcinl }
376371f87433Sdalcinl 
376471f87433Sdalcinl #undef __FUNCT__
3765fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW"
376671f87433Sdalcinl /*@
3767fa9f3622SBarry Smith    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
376871f87433Sdalcinl    for computing relative tolerance for linear solvers within an
376971f87433Sdalcinl    inexact Newton method.
377071f87433Sdalcinl 
377171f87433Sdalcinl    Not Collective
377271f87433Sdalcinl 
377371f87433Sdalcinl    Input Parameter:
377471f87433Sdalcinl .  snes - SNES context
377571f87433Sdalcinl 
377671f87433Sdalcinl    Output Parameter:
377771f87433Sdalcinl .  flag - PETSC_TRUE or PETSC_FALSE
377871f87433Sdalcinl 
377971f87433Sdalcinl    Notes:
378071f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
378171f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
378271f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
378371f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
378471f87433Sdalcinl    solver.
378571f87433Sdalcinl 
378671f87433Sdalcinl    Level: advanced
378771f87433Sdalcinl 
378871f87433Sdalcinl    Reference:
378971f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
379071f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
379171f87433Sdalcinl 
379271f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
379371f87433Sdalcinl 
3794fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
379571f87433Sdalcinl @*/
37967087cfbeSBarry Smith PetscErrorCode  SNESKSPGetUseEW(SNES snes, PetscBool  *flag)
379771f87433Sdalcinl {
379871f87433Sdalcinl   PetscFunctionBegin;
37990700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
380071f87433Sdalcinl   PetscValidPointer(flag,2);
380171f87433Sdalcinl   *flag = snes->ksp_ewconv;
380271f87433Sdalcinl   PetscFunctionReturn(0);
380371f87433Sdalcinl }
380471f87433Sdalcinl 
380571f87433Sdalcinl #undef __FUNCT__
3806fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW"
380771f87433Sdalcinl /*@
3808fa9f3622SBarry Smith    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
380971f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
381071f87433Sdalcinl    Newton method.
381171f87433Sdalcinl 
38123f9fe445SBarry Smith    Logically Collective on SNES
381371f87433Sdalcinl 
381471f87433Sdalcinl    Input Parameters:
381571f87433Sdalcinl +    snes - SNES context
381671f87433Sdalcinl .    version - version 1, 2 (default is 2) or 3
381771f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
381871f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
381971f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
382071f87433Sdalcinl              (0 <= gamma2 <= 1)
382171f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
382271f87433Sdalcinl .    alpha2 - power for safeguard
382371f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
382471f87433Sdalcinl 
382571f87433Sdalcinl    Note:
382671f87433Sdalcinl    Version 3 was contributed by Luis Chacon, June 2006.
382771f87433Sdalcinl 
382871f87433Sdalcinl    Use PETSC_DEFAULT to retain the default for any of the parameters.
382971f87433Sdalcinl 
383071f87433Sdalcinl    Level: advanced
383171f87433Sdalcinl 
383271f87433Sdalcinl    Reference:
383371f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
383471f87433Sdalcinl    inexact Newton method", Utah State University Math. Stat. Dept. Res.
383571f87433Sdalcinl    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
383671f87433Sdalcinl 
383771f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
383871f87433Sdalcinl 
3839fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
384071f87433Sdalcinl @*/
38417087cfbeSBarry Smith PetscErrorCode  SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,
384271f87433Sdalcinl 							    PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
384371f87433Sdalcinl {
3844fa9f3622SBarry Smith   SNESKSPEW *kctx;
384571f87433Sdalcinl   PetscFunctionBegin;
38460700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3847fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
3848e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
3849c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,version,2);
3850c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_0,3);
3851c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_max,4);
3852c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,gamma,5);
3853c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha,6);
3854c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha2,7);
3855c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,threshold,8);
385671f87433Sdalcinl 
385771f87433Sdalcinl   if (version != PETSC_DEFAULT)   kctx->version   = version;
385871f87433Sdalcinl   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
385971f87433Sdalcinl   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
386071f87433Sdalcinl   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
386171f87433Sdalcinl   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
386271f87433Sdalcinl   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
386371f87433Sdalcinl   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
386471f87433Sdalcinl 
386571f87433Sdalcinl   if (kctx->version < 1 || kctx->version > 3) {
3866e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version);
386771f87433Sdalcinl   }
386871f87433Sdalcinl   if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
3869e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0);
387071f87433Sdalcinl   }
387171f87433Sdalcinl   if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
3872e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max);
387371f87433Sdalcinl   }
387471f87433Sdalcinl   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
3875e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma);
387671f87433Sdalcinl   }
387771f87433Sdalcinl   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
3878e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha);
387971f87433Sdalcinl   }
388071f87433Sdalcinl   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
3881e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold);
388271f87433Sdalcinl   }
388371f87433Sdalcinl   PetscFunctionReturn(0);
388471f87433Sdalcinl }
388571f87433Sdalcinl 
388671f87433Sdalcinl #undef __FUNCT__
3887fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW"
388871f87433Sdalcinl /*@
3889fa9f3622SBarry Smith    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
389071f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
389171f87433Sdalcinl    Newton method.
389271f87433Sdalcinl 
389371f87433Sdalcinl    Not Collective
389471f87433Sdalcinl 
389571f87433Sdalcinl    Input Parameters:
389671f87433Sdalcinl      snes - SNES context
389771f87433Sdalcinl 
389871f87433Sdalcinl    Output Parameters:
389971f87433Sdalcinl +    version - version 1, 2 (default is 2) or 3
390071f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
390171f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
390271f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
390371f87433Sdalcinl              (0 <= gamma2 <= 1)
390471f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
390571f87433Sdalcinl .    alpha2 - power for safeguard
390671f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
390771f87433Sdalcinl 
390871f87433Sdalcinl    Level: advanced
390971f87433Sdalcinl 
391071f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters
391171f87433Sdalcinl 
3912fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
391371f87433Sdalcinl @*/
39147087cfbeSBarry Smith PetscErrorCode  SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,
391571f87433Sdalcinl 							    PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
391671f87433Sdalcinl {
3917fa9f3622SBarry Smith   SNESKSPEW *kctx;
391871f87433Sdalcinl   PetscFunctionBegin;
39190700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3920fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
3921e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
392271f87433Sdalcinl   if(version)   *version   = kctx->version;
392371f87433Sdalcinl   if(rtol_0)    *rtol_0    = kctx->rtol_0;
392471f87433Sdalcinl   if(rtol_max)  *rtol_max  = kctx->rtol_max;
392571f87433Sdalcinl   if(gamma)     *gamma     = kctx->gamma;
392671f87433Sdalcinl   if(alpha)     *alpha     = kctx->alpha;
392771f87433Sdalcinl   if(alpha2)    *alpha2    = kctx->alpha2;
392871f87433Sdalcinl   if(threshold) *threshold = kctx->threshold;
392971f87433Sdalcinl   PetscFunctionReturn(0);
393071f87433Sdalcinl }
393171f87433Sdalcinl 
393271f87433Sdalcinl #undef __FUNCT__
3933fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve"
3934fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x)
393571f87433Sdalcinl {
393671f87433Sdalcinl   PetscErrorCode ierr;
3937fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
393871f87433Sdalcinl   PetscReal      rtol=PETSC_DEFAULT,stol;
393971f87433Sdalcinl 
394071f87433Sdalcinl   PetscFunctionBegin;
3941e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
394271f87433Sdalcinl   if (!snes->iter) { /* first time in, so use the original user rtol */
394371f87433Sdalcinl     rtol = kctx->rtol_0;
394471f87433Sdalcinl   } else {
394571f87433Sdalcinl     if (kctx->version == 1) {
394671f87433Sdalcinl       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
394771f87433Sdalcinl       if (rtol < 0.0) rtol = -rtol;
394871f87433Sdalcinl       stol = pow(kctx->rtol_last,kctx->alpha2);
394971f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
395071f87433Sdalcinl     } else if (kctx->version == 2) {
395171f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
395271f87433Sdalcinl       stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
395371f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
395471f87433Sdalcinl     } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */
395571f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
395671f87433Sdalcinl       /* safeguard: avoid sharp decrease of rtol */
395771f87433Sdalcinl       stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha);
395871f87433Sdalcinl       stol = PetscMax(rtol,stol);
395971f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
396071f87433Sdalcinl       /* safeguard: avoid oversolving */
396171f87433Sdalcinl       stol = kctx->gamma*(snes->ttol)/snes->norm;
396271f87433Sdalcinl       stol = PetscMax(rtol,stol);
396371f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
3964e32f2f54SBarry Smith     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
396571f87433Sdalcinl   }
396671f87433Sdalcinl   /* safeguard: avoid rtol greater than one */
396771f87433Sdalcinl   rtol = PetscMin(rtol,kctx->rtol_max);
396871f87433Sdalcinl   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
396971f87433Sdalcinl   ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr);
397071f87433Sdalcinl   PetscFunctionReturn(0);
397171f87433Sdalcinl }
397271f87433Sdalcinl 
397371f87433Sdalcinl #undef __FUNCT__
3974fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve"
3975fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x)
397671f87433Sdalcinl {
397771f87433Sdalcinl   PetscErrorCode ierr;
3978fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
397971f87433Sdalcinl   PCSide         pcside;
398071f87433Sdalcinl   Vec            lres;
398171f87433Sdalcinl 
398271f87433Sdalcinl   PetscFunctionBegin;
3983e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
398471f87433Sdalcinl   ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr);
398571f87433Sdalcinl   ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr);
398671f87433Sdalcinl   if (kctx->version == 1) {
3987b037da10SBarry Smith     ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr);
398871f87433Sdalcinl     if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
398971f87433Sdalcinl       /* KSP residual is true linear residual */
399071f87433Sdalcinl       ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr);
399171f87433Sdalcinl     } else {
399271f87433Sdalcinl       /* KSP residual is preconditioned residual */
399371f87433Sdalcinl       /* compute true linear residual norm */
399471f87433Sdalcinl       ierr = VecDuplicate(b,&lres);CHKERRQ(ierr);
399571f87433Sdalcinl       ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr);
399671f87433Sdalcinl       ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr);
399771f87433Sdalcinl       ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr);
39986bf464f9SBarry Smith       ierr = VecDestroy(&lres);CHKERRQ(ierr);
399971f87433Sdalcinl     }
400071f87433Sdalcinl   }
400171f87433Sdalcinl   PetscFunctionReturn(0);
400271f87433Sdalcinl }
400371f87433Sdalcinl 
400471f87433Sdalcinl #undef __FUNCT__
400571f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve"
400671f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x)
400771f87433Sdalcinl {
400871f87433Sdalcinl   PetscErrorCode ierr;
400971f87433Sdalcinl 
401071f87433Sdalcinl   PetscFunctionBegin;
4011fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr);  }
401271f87433Sdalcinl   ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr);
4013fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); }
401471f87433Sdalcinl   PetscFunctionReturn(0);
401571f87433Sdalcinl }
40166c699258SBarry Smith 
40176c699258SBarry Smith #undef __FUNCT__
40186c699258SBarry Smith #define __FUNCT__ "SNESSetDM"
40196c699258SBarry Smith /*@
40206c699258SBarry Smith    SNESSetDM - Sets the DM that may be used by some preconditioners
40216c699258SBarry Smith 
40223f9fe445SBarry Smith    Logically Collective on SNES
40236c699258SBarry Smith 
40246c699258SBarry Smith    Input Parameters:
40256c699258SBarry Smith +  snes - the preconditioner context
40266c699258SBarry Smith -  dm - the dm
40276c699258SBarry Smith 
40286c699258SBarry Smith    Level: intermediate
40296c699258SBarry Smith 
40306c699258SBarry Smith 
40316c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM()
40326c699258SBarry Smith @*/
40337087cfbeSBarry Smith PetscErrorCode  SNESSetDM(SNES snes,DM dm)
40346c699258SBarry Smith {
40356c699258SBarry Smith   PetscErrorCode ierr;
4036345fed2cSBarry Smith   KSP            ksp;
4037*6cab3a1bSJed Brown   SNESDM         sdm;
40386c699258SBarry Smith 
40396c699258SBarry Smith   PetscFunctionBegin;
40400700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4041d0660788SBarry Smith   if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);}
4042*6cab3a1bSJed Brown   if (snes->dm) {               /* Move the SNESDM context over to the new DM unless the new DM already has one */
4043*6cab3a1bSJed Brown     PetscContainer oldcontainer,container;
4044*6cab3a1bSJed Brown     ierr = PetscObjectQuery((PetscObject)snes->dm,"SNESDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr);
4045*6cab3a1bSJed Brown     ierr = PetscObjectQuery((PetscObject)dm,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr);
4046*6cab3a1bSJed Brown     if (oldcontainer && !container) {
4047*6cab3a1bSJed Brown       ierr = DMSNESCopyContext(snes->dm,dm);CHKERRQ(ierr);
4048*6cab3a1bSJed Brown       ierr = DMSNESGetContext(snes->dm,&sdm);CHKERRQ(ierr);
4049*6cab3a1bSJed Brown       if (sdm->originaldm == snes->dm) { /* Grant write privileges to the replacement DM */
4050*6cab3a1bSJed Brown         sdm->originaldm = dm;
4051*6cab3a1bSJed Brown       }
4052*6cab3a1bSJed Brown     }
40536bf464f9SBarry Smith     ierr = DMDestroy(&snes->dm);CHKERRQ(ierr);
4054*6cab3a1bSJed Brown   }
40556c699258SBarry Smith   snes->dm = dm;
4056345fed2cSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
4057345fed2cSBarry Smith   ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr);
4058f22f69f0SBarry Smith   ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr);
40592c155ee1SBarry Smith   if (snes->pc) {
40602c155ee1SBarry Smith     ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr);
40612c155ee1SBarry Smith   }
40626c699258SBarry Smith   PetscFunctionReturn(0);
40636c699258SBarry Smith }
40646c699258SBarry Smith 
40656c699258SBarry Smith #undef __FUNCT__
40666c699258SBarry Smith #define __FUNCT__ "SNESGetDM"
40676c699258SBarry Smith /*@
40686c699258SBarry Smith    SNESGetDM - Gets the DM that may be used by some preconditioners
40696c699258SBarry Smith 
40703f9fe445SBarry Smith    Not Collective but DM obtained is parallel on SNES
40716c699258SBarry Smith 
40726c699258SBarry Smith    Input Parameter:
40736c699258SBarry Smith . snes - the preconditioner context
40746c699258SBarry Smith 
40756c699258SBarry Smith    Output Parameter:
40766c699258SBarry Smith .  dm - the dm
40776c699258SBarry Smith 
40786c699258SBarry Smith    Level: intermediate
40796c699258SBarry Smith 
40806c699258SBarry Smith 
40816c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM()
40826c699258SBarry Smith @*/
40837087cfbeSBarry Smith PetscErrorCode  SNESGetDM(SNES snes,DM *dm)
40846c699258SBarry Smith {
4085*6cab3a1bSJed Brown   PetscErrorCode ierr;
4086*6cab3a1bSJed Brown 
40876c699258SBarry Smith   PetscFunctionBegin;
40880700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4089*6cab3a1bSJed Brown   if (!snes->dm) {
4090*6cab3a1bSJed Brown     ierr = DMShellCreate(((PetscObject)snes)->comm,&snes->dm);CHKERRQ(ierr);
4091*6cab3a1bSJed Brown   }
40926c699258SBarry Smith   *dm = snes->dm;
40936c699258SBarry Smith   PetscFunctionReturn(0);
40946c699258SBarry Smith }
40950807856dSBarry Smith 
409631823bd8SMatthew G Knepley #undef __FUNCT__
409731823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC"
409831823bd8SMatthew G Knepley /*@
4099fd4b34e9SJed Brown   SNESSetPC - Sets the nonlinear preconditioner to be used.
410031823bd8SMatthew G Knepley 
410131823bd8SMatthew G Knepley   Collective on SNES
410231823bd8SMatthew G Knepley 
410331823bd8SMatthew G Knepley   Input Parameters:
410431823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate()
410531823bd8SMatthew G Knepley - pc   - the preconditioner object
410631823bd8SMatthew G Knepley 
410731823bd8SMatthew G Knepley   Notes:
410831823bd8SMatthew G Knepley   Use SNESGetPC() to retrieve the preconditioner context (for example,
410931823bd8SMatthew G Knepley   to configure it using the API).
411031823bd8SMatthew G Knepley 
411131823bd8SMatthew G Knepley   Level: developer
411231823bd8SMatthew G Knepley 
411331823bd8SMatthew G Knepley .keywords: SNES, set, precondition
411431823bd8SMatthew G Knepley .seealso: SNESGetPC()
411531823bd8SMatthew G Knepley @*/
411631823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc)
411731823bd8SMatthew G Knepley {
411831823bd8SMatthew G Knepley   PetscErrorCode ierr;
411931823bd8SMatthew G Knepley 
412031823bd8SMatthew G Knepley   PetscFunctionBegin;
412131823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
412231823bd8SMatthew G Knepley   PetscValidHeaderSpecific(pc, SNES_CLASSID, 2);
412331823bd8SMatthew G Knepley   PetscCheckSameComm(snes, 1, pc, 2);
412431823bd8SMatthew G Knepley   ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr);
4125bf11d3b6SBarry Smith   ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr);
412631823bd8SMatthew G Knepley   snes->pc = pc;
412731823bd8SMatthew G Knepley   ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr);
412831823bd8SMatthew G Knepley   PetscFunctionReturn(0);
412931823bd8SMatthew G Knepley }
413031823bd8SMatthew G Knepley 
413131823bd8SMatthew G Knepley #undef __FUNCT__
413231823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC"
413331823bd8SMatthew G Knepley /*@
4134fd4b34e9SJed Brown   SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC().
413531823bd8SMatthew G Knepley 
413631823bd8SMatthew G Knepley   Not Collective
413731823bd8SMatthew G Knepley 
413831823bd8SMatthew G Knepley   Input Parameter:
413931823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate()
414031823bd8SMatthew G Knepley 
414131823bd8SMatthew G Knepley   Output Parameter:
414231823bd8SMatthew G Knepley . pc - preconditioner context
414331823bd8SMatthew G Knepley 
414431823bd8SMatthew G Knepley   Level: developer
414531823bd8SMatthew G Knepley 
414631823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner
414731823bd8SMatthew G Knepley .seealso: SNESSetPC()
414831823bd8SMatthew G Knepley @*/
414931823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc)
415031823bd8SMatthew G Knepley {
415131823bd8SMatthew G Knepley   PetscErrorCode ierr;
415231823bd8SMatthew G Knepley 
415331823bd8SMatthew G Knepley   PetscFunctionBegin;
415431823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
415531823bd8SMatthew G Knepley   PetscValidPointer(pc, 2);
415631823bd8SMatthew G Knepley   if (!snes->pc) {
415731823bd8SMatthew G Knepley     ierr = SNESCreate(((PetscObject) snes)->comm, &snes->pc);CHKERRQ(ierr);
41584a0c5b0cSMatthew G Knepley     ierr = PetscObjectIncrementTabLevel((PetscObject) snes->pc, (PetscObject) snes, 1);CHKERRQ(ierr);
415931823bd8SMatthew G Knepley     ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr);
416031823bd8SMatthew G Knepley   }
416131823bd8SMatthew G Knepley   *pc = snes->pc;
416231823bd8SMatthew G Knepley   PetscFunctionReturn(0);
416331823bd8SMatthew G Knepley }
416431823bd8SMatthew G Knepley 
416569b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
4166c6db04a5SJed Brown #include <mex.h>
416769b4f73cSBarry Smith 
41688f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext;
41698f6e6473SBarry Smith 
41700807856dSBarry Smith #undef __FUNCT__
41710807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab"
41720807856dSBarry Smith /*
41730807856dSBarry Smith    SNESComputeFunction_Matlab - Calls the function that has been set with
41740807856dSBarry Smith                          SNESSetFunctionMatlab().
41750807856dSBarry Smith 
41760807856dSBarry Smith    Collective on SNES
41770807856dSBarry Smith 
41780807856dSBarry Smith    Input Parameters:
41790807856dSBarry Smith +  snes - the SNES context
41800807856dSBarry Smith -  x - input vector
41810807856dSBarry Smith 
41820807856dSBarry Smith    Output Parameter:
41830807856dSBarry Smith .  y - function vector, as set by SNESSetFunction()
41840807856dSBarry Smith 
41850807856dSBarry Smith    Notes:
41860807856dSBarry Smith    SNESComputeFunction() is typically used within nonlinear solvers
41870807856dSBarry Smith    implementations, so most users would not generally call this routine
41880807856dSBarry Smith    themselves.
41890807856dSBarry Smith 
41900807856dSBarry Smith    Level: developer
41910807856dSBarry Smith 
41920807856dSBarry Smith .keywords: SNES, nonlinear, compute, function
41930807856dSBarry Smith 
41940807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
419561b2408cSBarry Smith */
41967087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx)
41970807856dSBarry Smith {
4198e650e774SBarry Smith   PetscErrorCode    ierr;
41998f6e6473SBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
42008f6e6473SBarry Smith   int               nlhs = 1,nrhs = 5;
42018f6e6473SBarry Smith   mxArray	    *plhs[1],*prhs[5];
420291621f2eSBarry Smith   long long int     lx = 0,ly = 0,ls = 0;
4203e650e774SBarry Smith 
42040807856dSBarry Smith   PetscFunctionBegin;
42050807856dSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
42060807856dSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
42070807856dSBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
42080807856dSBarry Smith   PetscCheckSameComm(snes,1,x,2);
42090807856dSBarry Smith   PetscCheckSameComm(snes,1,y,3);
42100807856dSBarry Smith 
42110807856dSBarry Smith   /* call Matlab function in ctx with arguments x and y */
4212e650e774SBarry Smith 
421391621f2eSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4214e650e774SBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4215e650e774SBarry Smith   ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr);
421691621f2eSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
421791621f2eSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
421891621f2eSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)ly);
42198f6e6473SBarry Smith   prhs[3] =  mxCreateString(sctx->funcname);
42208f6e6473SBarry Smith   prhs[4] =  sctx->ctx;
4221b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr);
4222e650e774SBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4223e650e774SBarry Smith   mxDestroyArray(prhs[0]);
4224e650e774SBarry Smith   mxDestroyArray(prhs[1]);
4225e650e774SBarry Smith   mxDestroyArray(prhs[2]);
42268f6e6473SBarry Smith   mxDestroyArray(prhs[3]);
4227e650e774SBarry Smith   mxDestroyArray(plhs[0]);
42280807856dSBarry Smith   PetscFunctionReturn(0);
42290807856dSBarry Smith }
42300807856dSBarry Smith 
42310807856dSBarry Smith 
42320807856dSBarry Smith #undef __FUNCT__
42330807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab"
423461b2408cSBarry Smith /*
42350807856dSBarry Smith    SNESSetFunctionMatlab - Sets the function evaluation routine and function
42360807856dSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4237e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
42380807856dSBarry Smith 
42390807856dSBarry Smith    Logically Collective on SNES
42400807856dSBarry Smith 
42410807856dSBarry Smith    Input Parameters:
42420807856dSBarry Smith +  snes - the SNES context
42430807856dSBarry Smith .  r - vector to store function value
42440807856dSBarry Smith -  func - function evaluation routine
42450807856dSBarry Smith 
42460807856dSBarry Smith    Calling sequence of func:
424761b2408cSBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
42480807856dSBarry Smith 
42490807856dSBarry Smith 
42500807856dSBarry Smith    Notes:
42510807856dSBarry Smith    The Newton-like methods typically solve linear systems of the form
42520807856dSBarry Smith $      f'(x) x = -f(x),
42530807856dSBarry Smith    where f'(x) denotes the Jacobian matrix and f(x) is the function.
42540807856dSBarry Smith 
42550807856dSBarry Smith    Level: beginner
42560807856dSBarry Smith 
42570807856dSBarry Smith .keywords: SNES, nonlinear, set, function
42580807856dSBarry Smith 
42590807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
426061b2408cSBarry Smith */
42617087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx)
42620807856dSBarry Smith {
42630807856dSBarry Smith   PetscErrorCode    ierr;
42648f6e6473SBarry Smith   SNESMatlabContext *sctx;
42650807856dSBarry Smith 
42660807856dSBarry Smith   PetscFunctionBegin;
42678f6e6473SBarry Smith   /* currently sctx is memory bleed */
42688f6e6473SBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
42698f6e6473SBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
42708f6e6473SBarry Smith   /*
42718f6e6473SBarry Smith      This should work, but it doesn't
42728f6e6473SBarry Smith   sctx->ctx = ctx;
42738f6e6473SBarry Smith   mexMakeArrayPersistent(sctx->ctx);
42748f6e6473SBarry Smith   */
42758f6e6473SBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
42768f6e6473SBarry Smith   ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr);
42770807856dSBarry Smith   PetscFunctionReturn(0);
42780807856dSBarry Smith }
427969b4f73cSBarry Smith 
428061b2408cSBarry Smith #undef __FUNCT__
428161b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab"
428261b2408cSBarry Smith /*
428361b2408cSBarry Smith    SNESComputeJacobian_Matlab - Calls the function that has been set with
428461b2408cSBarry Smith                          SNESSetJacobianMatlab().
428561b2408cSBarry Smith 
428661b2408cSBarry Smith    Collective on SNES
428761b2408cSBarry Smith 
428861b2408cSBarry Smith    Input Parameters:
428961b2408cSBarry Smith +  snes - the SNES context
429061b2408cSBarry Smith .  x - input vector
429161b2408cSBarry Smith .  A, B - the matrices
429261b2408cSBarry Smith -  ctx - user context
429361b2408cSBarry Smith 
429461b2408cSBarry Smith    Output Parameter:
429561b2408cSBarry Smith .  flag - structure of the matrix
429661b2408cSBarry Smith 
429761b2408cSBarry Smith    Level: developer
429861b2408cSBarry Smith 
429961b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function
430061b2408cSBarry Smith 
430161b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
430261b2408cSBarry Smith @*/
43037087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx)
430461b2408cSBarry Smith {
430561b2408cSBarry Smith   PetscErrorCode    ierr;
430661b2408cSBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
430761b2408cSBarry Smith   int               nlhs = 2,nrhs = 6;
430861b2408cSBarry Smith   mxArray	    *plhs[2],*prhs[6];
430961b2408cSBarry Smith   long long int     lx = 0,lA = 0,ls = 0, lB = 0;
431061b2408cSBarry Smith 
431161b2408cSBarry Smith   PetscFunctionBegin;
431261b2408cSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
431361b2408cSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
431461b2408cSBarry Smith 
431561b2408cSBarry Smith   /* call Matlab function in ctx with arguments x and y */
431661b2408cSBarry Smith 
431761b2408cSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
431861b2408cSBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
431961b2408cSBarry Smith   ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr);
432061b2408cSBarry Smith   ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr);
432161b2408cSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
432261b2408cSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
432361b2408cSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)lA);
432461b2408cSBarry Smith   prhs[3] =  mxCreateDoubleScalar((double)lB);
432561b2408cSBarry Smith   prhs[4] =  mxCreateString(sctx->funcname);
432661b2408cSBarry Smith   prhs[5] =  sctx->ctx;
4327b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr);
432861b2408cSBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
432961b2408cSBarry Smith   *flag   =  (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr);
433061b2408cSBarry Smith   mxDestroyArray(prhs[0]);
433161b2408cSBarry Smith   mxDestroyArray(prhs[1]);
433261b2408cSBarry Smith   mxDestroyArray(prhs[2]);
433361b2408cSBarry Smith   mxDestroyArray(prhs[3]);
433461b2408cSBarry Smith   mxDestroyArray(prhs[4]);
433561b2408cSBarry Smith   mxDestroyArray(plhs[0]);
433661b2408cSBarry Smith   mxDestroyArray(plhs[1]);
433761b2408cSBarry Smith   PetscFunctionReturn(0);
433861b2408cSBarry Smith }
433961b2408cSBarry Smith 
434061b2408cSBarry Smith 
434161b2408cSBarry Smith #undef __FUNCT__
434261b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab"
434361b2408cSBarry Smith /*
434461b2408cSBarry Smith    SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
434561b2408cSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4346e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
434761b2408cSBarry Smith 
434861b2408cSBarry Smith    Logically Collective on SNES
434961b2408cSBarry Smith 
435061b2408cSBarry Smith    Input Parameters:
435161b2408cSBarry Smith +  snes - the SNES context
435261b2408cSBarry Smith .  A,B - Jacobian matrices
435361b2408cSBarry Smith .  func - function evaluation routine
435461b2408cSBarry Smith -  ctx - user context
435561b2408cSBarry Smith 
435661b2408cSBarry Smith    Calling sequence of func:
435761b2408cSBarry Smith $    flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx);
435861b2408cSBarry Smith 
435961b2408cSBarry Smith 
436061b2408cSBarry Smith    Level: developer
436161b2408cSBarry Smith 
436261b2408cSBarry Smith .keywords: SNES, nonlinear, set, function
436361b2408cSBarry Smith 
436461b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
436561b2408cSBarry Smith */
43667087cfbeSBarry Smith PetscErrorCode  SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx)
436761b2408cSBarry Smith {
436861b2408cSBarry Smith   PetscErrorCode    ierr;
436961b2408cSBarry Smith   SNESMatlabContext *sctx;
437061b2408cSBarry Smith 
437161b2408cSBarry Smith   PetscFunctionBegin;
437261b2408cSBarry Smith   /* currently sctx is memory bleed */
437361b2408cSBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
437461b2408cSBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
437561b2408cSBarry Smith   /*
437661b2408cSBarry Smith      This should work, but it doesn't
437761b2408cSBarry Smith   sctx->ctx = ctx;
437861b2408cSBarry Smith   mexMakeArrayPersistent(sctx->ctx);
437961b2408cSBarry Smith   */
438061b2408cSBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
438161b2408cSBarry Smith   ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
438261b2408cSBarry Smith   PetscFunctionReturn(0);
438361b2408cSBarry Smith }
438469b4f73cSBarry Smith 
4385f9eb7ae2SShri Abhyankar #undef __FUNCT__
4386f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab"
4387f9eb7ae2SShri Abhyankar /*
4388f9eb7ae2SShri Abhyankar    SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab().
4389f9eb7ae2SShri Abhyankar 
4390f9eb7ae2SShri Abhyankar    Collective on SNES
4391f9eb7ae2SShri Abhyankar 
4392f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction()
4393f9eb7ae2SShri Abhyankar @*/
43947087cfbeSBarry Smith PetscErrorCode  SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx)
4395f9eb7ae2SShri Abhyankar {
4396f9eb7ae2SShri Abhyankar   PetscErrorCode  ierr;
439748f37e70SShri Abhyankar   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
4398f9eb7ae2SShri Abhyankar   int             nlhs = 1,nrhs = 6;
4399f9eb7ae2SShri Abhyankar   mxArray	  *plhs[1],*prhs[6];
4400f9eb7ae2SShri Abhyankar   long long int   lx = 0,ls = 0;
4401f9eb7ae2SShri Abhyankar   Vec             x=snes->vec_sol;
4402f9eb7ae2SShri Abhyankar 
4403f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4404f9eb7ae2SShri Abhyankar   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4405f9eb7ae2SShri Abhyankar 
4406f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4407f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4408f9eb7ae2SShri Abhyankar   prhs[0] =  mxCreateDoubleScalar((double)ls);
4409f9eb7ae2SShri Abhyankar   prhs[1] =  mxCreateDoubleScalar((double)it);
4410f9eb7ae2SShri Abhyankar   prhs[2] =  mxCreateDoubleScalar((double)fnorm);
4411f9eb7ae2SShri Abhyankar   prhs[3] =  mxCreateDoubleScalar((double)lx);
4412f9eb7ae2SShri Abhyankar   prhs[4] =  mxCreateString(sctx->funcname);
4413f9eb7ae2SShri Abhyankar   prhs[5] =  sctx->ctx;
4414f9eb7ae2SShri Abhyankar   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr);
4415f9eb7ae2SShri Abhyankar   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4416f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[0]);
4417f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[1]);
4418f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[2]);
4419f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[3]);
4420f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[4]);
4421f9eb7ae2SShri Abhyankar   mxDestroyArray(plhs[0]);
4422f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
4423f9eb7ae2SShri Abhyankar }
4424f9eb7ae2SShri Abhyankar 
4425f9eb7ae2SShri Abhyankar 
4426f9eb7ae2SShri Abhyankar #undef __FUNCT__
4427f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab"
4428f9eb7ae2SShri Abhyankar /*
4429e3c5b3baSBarry Smith    SNESMonitorSetMatlab - Sets the monitor function from MATLAB
4430f9eb7ae2SShri Abhyankar 
4431f9eb7ae2SShri Abhyankar    Level: developer
4432f9eb7ae2SShri Abhyankar 
4433f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function
4434f9eb7ae2SShri Abhyankar 
4435f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
4436f9eb7ae2SShri Abhyankar */
44377087cfbeSBarry Smith PetscErrorCode  SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx)
4438f9eb7ae2SShri Abhyankar {
4439f9eb7ae2SShri Abhyankar   PetscErrorCode    ierr;
4440f9eb7ae2SShri Abhyankar   SNESMatlabContext *sctx;
4441f9eb7ae2SShri Abhyankar 
4442f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4443f9eb7ae2SShri Abhyankar   /* currently sctx is memory bleed */
4444f9eb7ae2SShri Abhyankar   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
4445f9eb7ae2SShri Abhyankar   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
4446f9eb7ae2SShri Abhyankar   /*
4447f9eb7ae2SShri Abhyankar      This should work, but it doesn't
4448f9eb7ae2SShri Abhyankar   sctx->ctx = ctx;
4449f9eb7ae2SShri Abhyankar   mexMakeArrayPersistent(sctx->ctx);
4450f9eb7ae2SShri Abhyankar   */
4451f9eb7ae2SShri Abhyankar   sctx->ctx = mxDuplicateArray(ctx);
4452f9eb7ae2SShri Abhyankar   ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr);
4453f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
4454f9eb7ae2SShri Abhyankar }
4455f9eb7ae2SShri Abhyankar 
445669b4f73cSBarry Smith #endif
4457