xref: /petsc/src/snes/interface/snes.c (revision e727c939307103fe1a8059df2c7e3997499a35b0)
19b94acceSBarry Smith 
2c6db04a5SJed Brown #include <private/snesimpl.h>      /*I "petscsnes.h"  I*/
39b94acceSBarry Smith 
4ace3abfcSBarry Smith PetscBool  SNESRegisterAllCalled = PETSC_FALSE;
58ba1e511SMatthew Knepley PetscFList SNESList              = PETSC_NULL;
68ba1e511SMatthew Knepley 
78ba1e511SMatthew Knepley /* Logging support */
87087cfbeSBarry Smith PetscClassId  SNES_CLASSID;
9166c7f25SBarry Smith PetscLogEvent  SNES_Solve, SNES_LineSearch, SNES_FunctionEval, SNES_JacobianEval;
10a09944afSBarry Smith 
11a09944afSBarry Smith #undef __FUNCT__
12cab2e9ccSBarry Smith #define __FUNCT__ "SNESDMComputeJacobian"
13cab2e9ccSBarry Smith /*
14cab2e9ccSBarry Smith     Translates from a SNES call to a DM call in computing a Jacobian
15cab2e9ccSBarry Smith */
16cab2e9ccSBarry Smith PetscErrorCode SNESDMComputeJacobian(SNES snes,Vec X,Mat *J,Mat *B,MatStructure *flag,void *ptr)
17cab2e9ccSBarry Smith {
18cab2e9ccSBarry Smith   PetscErrorCode ierr;
19cab2e9ccSBarry Smith   DM             dm;
20cab2e9ccSBarry Smith 
21cab2e9ccSBarry Smith   PetscFunctionBegin;
22cab2e9ccSBarry Smith   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
23cab2e9ccSBarry Smith   ierr = DMComputeJacobian(dm,X,*J,*B,flag);CHKERRQ(ierr);
24cab2e9ccSBarry Smith   PetscFunctionReturn(0);
25cab2e9ccSBarry Smith }
26cab2e9ccSBarry Smith 
27cab2e9ccSBarry Smith #undef __FUNCT__
28e113a28aSBarry Smith #define __FUNCT__ "SNESSetErrorIfNotConverged"
29e113a28aSBarry Smith /*@
30e113a28aSBarry Smith    SNESSetErrorIfNotConverged - Causes SNESSolve() to generate an error if the solver has not converged.
31e113a28aSBarry Smith 
323f9fe445SBarry Smith    Logically Collective on SNES
33e113a28aSBarry Smith 
34e113a28aSBarry Smith    Input Parameters:
35e113a28aSBarry Smith +  snes - iterative context obtained from SNESCreate()
36e113a28aSBarry Smith -  flg - PETSC_TRUE indicates you want the error generated
37e113a28aSBarry Smith 
38e113a28aSBarry Smith    Options database keys:
39e113a28aSBarry Smith .  -snes_error_if_not_converged : this takes an optional truth value (0/1/no/yes/true/false)
40e113a28aSBarry Smith 
41e113a28aSBarry Smith    Level: intermediate
42e113a28aSBarry Smith 
43e113a28aSBarry Smith    Notes:
44e113a28aSBarry Smith     Normally PETSc continues if a linear solver fails to converge, you can call SNESGetConvergedReason() after a SNESSolve()
45e113a28aSBarry Smith     to determine if it has converged.
46e113a28aSBarry Smith 
47e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero
48e113a28aSBarry Smith 
49e113a28aSBarry Smith .seealso: SNESGetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged()
50e113a28aSBarry Smith @*/
517087cfbeSBarry Smith PetscErrorCode  SNESSetErrorIfNotConverged(SNES snes,PetscBool  flg)
52e113a28aSBarry Smith {
53e113a28aSBarry Smith   PetscFunctionBegin;
54e113a28aSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
55acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flg,2);
56e113a28aSBarry Smith   snes->errorifnotconverged = flg;
57e113a28aSBarry Smith   PetscFunctionReturn(0);
58e113a28aSBarry Smith }
59e113a28aSBarry Smith 
60e113a28aSBarry Smith #undef __FUNCT__
61e113a28aSBarry Smith #define __FUNCT__ "SNESGetErrorIfNotConverged"
62e113a28aSBarry Smith /*@
63e113a28aSBarry Smith    SNESGetErrorIfNotConverged - Will SNESSolve() generate an error if the solver does not converge?
64e113a28aSBarry Smith 
65e113a28aSBarry Smith    Not Collective
66e113a28aSBarry Smith 
67e113a28aSBarry Smith    Input Parameter:
68e113a28aSBarry Smith .  snes - iterative context obtained from SNESCreate()
69e113a28aSBarry Smith 
70e113a28aSBarry Smith    Output Parameter:
71e113a28aSBarry Smith .  flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE
72e113a28aSBarry Smith 
73e113a28aSBarry Smith    Level: intermediate
74e113a28aSBarry Smith 
75e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero
76e113a28aSBarry Smith 
77e113a28aSBarry Smith .seealso:  SNESSetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged()
78e113a28aSBarry Smith @*/
797087cfbeSBarry Smith PetscErrorCode  SNESGetErrorIfNotConverged(SNES snes,PetscBool  *flag)
80e113a28aSBarry Smith {
81e113a28aSBarry Smith   PetscFunctionBegin;
82e113a28aSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
83e113a28aSBarry Smith   PetscValidPointer(flag,2);
84e113a28aSBarry Smith   *flag = snes->errorifnotconverged;
85e113a28aSBarry Smith   PetscFunctionReturn(0);
86e113a28aSBarry Smith }
87e113a28aSBarry Smith 
88e113a28aSBarry Smith #undef __FUNCT__
894936397dSBarry Smith #define __FUNCT__ "SNESSetFunctionDomainError"
90e725d27bSBarry Smith /*@
914936397dSBarry Smith    SNESSetFunctionDomainError - tells SNES that the input vector to your FormFunction is not
924936397dSBarry Smith      in the functions domain. For example, negative pressure.
934936397dSBarry Smith 
943f9fe445SBarry Smith    Logically Collective on SNES
954936397dSBarry Smith 
964936397dSBarry Smith    Input Parameters:
974936397dSBarry Smith .  SNES - the SNES context
984936397dSBarry Smith 
9928529972SSatish Balay    Level: advanced
1004936397dSBarry Smith 
1014936397dSBarry Smith .keywords: SNES, view
1024936397dSBarry Smith 
1034936397dSBarry Smith .seealso: SNESCreate(), SNESSetFunction()
1044936397dSBarry Smith @*/
1057087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionDomainError(SNES snes)
1064936397dSBarry Smith {
1074936397dSBarry Smith   PetscFunctionBegin;
1080700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1094936397dSBarry Smith   snes->domainerror = PETSC_TRUE;
1104936397dSBarry Smith   PetscFunctionReturn(0);
1114936397dSBarry Smith }
1124936397dSBarry Smith 
1134936397dSBarry Smith #undef __FUNCT__
1144a2ae208SSatish Balay #define __FUNCT__ "SNESView"
1157e2c5f70SBarry Smith /*@C
1169b94acceSBarry Smith    SNESView - Prints the SNES data structure.
1179b94acceSBarry Smith 
1184c49b128SBarry Smith    Collective on SNES
119fee21e36SBarry Smith 
120c7afd0dbSLois Curfman McInnes    Input Parameters:
121c7afd0dbSLois Curfman McInnes +  SNES - the SNES context
122c7afd0dbSLois Curfman McInnes -  viewer - visualization context
123c7afd0dbSLois Curfman McInnes 
1249b94acceSBarry Smith    Options Database Key:
125c8a8ba5cSLois Curfman McInnes .  -snes_view - Calls SNESView() at end of SNESSolve()
1269b94acceSBarry Smith 
1279b94acceSBarry Smith    Notes:
1289b94acceSBarry Smith    The available visualization contexts include
129b0a32e0cSBarry Smith +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
130b0a32e0cSBarry Smith -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
131c8a8ba5cSLois Curfman McInnes          output where only the first processor opens
132c8a8ba5cSLois Curfman McInnes          the file.  All other processors send their
133c8a8ba5cSLois Curfman McInnes          data to the first processor to print.
1349b94acceSBarry Smith 
1353e081fefSLois Curfman McInnes    The user can open an alternative visualization context with
136b0a32e0cSBarry Smith    PetscViewerASCIIOpen() - output to a specified file.
1379b94acceSBarry Smith 
13836851e7fSLois Curfman McInnes    Level: beginner
13936851e7fSLois Curfman McInnes 
1409b94acceSBarry Smith .keywords: SNES, view
1419b94acceSBarry Smith 
142b0a32e0cSBarry Smith .seealso: PetscViewerASCIIOpen()
1439b94acceSBarry Smith @*/
1447087cfbeSBarry Smith PetscErrorCode  SNESView(SNES snes,PetscViewer viewer)
1459b94acceSBarry Smith {
146fa9f3622SBarry Smith   SNESKSPEW           *kctx;
147dfbe8321SBarry Smith   PetscErrorCode      ierr;
14894b7f48cSBarry Smith   KSP                 ksp;
149ace3abfcSBarry Smith   PetscBool           iascii,isstring;
1509b94acceSBarry Smith 
1513a40ed3dSBarry Smith   PetscFunctionBegin;
1520700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1533050cee2SBarry Smith   if (!viewer) {
1547adad957SLisandro Dalcin     ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr);
1553050cee2SBarry Smith   }
1560700a824SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
157c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,viewer,2);
15874679c65SBarry Smith 
1592692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1602692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr);
16132077d6dSBarry Smith   if (iascii) {
162317d6ea6SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer,"SNES Object");CHKERRQ(ierr);
163e7788613SBarry Smith     if (snes->ops->view) {
164b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
165e7788613SBarry Smith       ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr);
166b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1670ef38995SBarry Smith     }
16877431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);CHKERRQ(ierr);
169a83599f4SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  tolerances: relative=%G, absolute=%G, solution=%G\n",
17070441072SBarry Smith                  snes->rtol,snes->abstol,snes->xtol);CHKERRQ(ierr);
17177431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr);
17277431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr);
1739b94acceSBarry Smith     if (snes->ksp_ewconv) {
174fa9f3622SBarry Smith       kctx = (SNESKSPEW *)snes->kspconvctx;
1759b94acceSBarry Smith       if (kctx) {
17677431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"  Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr);
177a83599f4SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    rtol_0=%G, rtol_max=%G, threshold=%G\n",kctx->rtol_0,kctx->rtol_max,kctx->threshold);CHKERRQ(ierr);
178a83599f4SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    gamma=%G, alpha=%G, alpha2=%G\n",kctx->gamma,kctx->alpha,kctx->alpha2);CHKERRQ(ierr);
1799b94acceSBarry Smith       }
1809b94acceSBarry Smith     }
181eb1f6c34SBarry Smith     if (snes->lagpreconditioner == -1) {
182eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is never rebuilt\n");CHKERRQ(ierr);
183eb1f6c34SBarry Smith     } else if (snes->lagpreconditioner > 1) {
184eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr);
185eb1f6c34SBarry Smith     }
186eb1f6c34SBarry Smith     if (snes->lagjacobian == -1) {
187eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is never rebuilt\n");CHKERRQ(ierr);
188eb1f6c34SBarry Smith     } else if (snes->lagjacobian > 1) {
18942f4f86dSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian);CHKERRQ(ierr);
190eb1f6c34SBarry Smith     }
1910f5bd95cSBarry Smith   } else if (isstring) {
192317d6ea6SBarry Smith     const char *type;
193454a90a3SBarry Smith     ierr = SNESGetType(snes,&type);CHKERRQ(ierr);
194b0a32e0cSBarry Smith     ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr);
19519bcc07fSBarry Smith   }
19642f4f86dSBarry Smith   if (snes->pc && snes->usespc) {
1974a0c5b0cSMatthew G Knepley     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1984a0c5b0cSMatthew G Knepley     ierr = SNESView(snes->pc, viewer);CHKERRQ(ierr);
1994a0c5b0cSMatthew G Knepley     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2004a0c5b0cSMatthew G Knepley   }
2012c155ee1SBarry Smith   if (snes->usesksp) {
2022c155ee1SBarry Smith     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
203b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
20494b7f48cSBarry Smith     ierr = KSPView(ksp,viewer);CHKERRQ(ierr);
205b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2062c155ee1SBarry Smith   }
2073a40ed3dSBarry Smith   PetscFunctionReturn(0);
2089b94acceSBarry Smith }
2099b94acceSBarry Smith 
21076b2cf59SMatthew Knepley /*
21176b2cf59SMatthew Knepley   We retain a list of functions that also take SNES command
21276b2cf59SMatthew Knepley   line options. These are called at the end SNESSetFromOptions()
21376b2cf59SMatthew Knepley */
21476b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5
215a7cc72afSBarry Smith static PetscInt numberofsetfromoptions;
2166849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES);
21776b2cf59SMatthew Knepley 
218e74ef692SMatthew Knepley #undef __FUNCT__
219e74ef692SMatthew Knepley #define __FUNCT__ "SNESAddOptionsChecker"
220ac226902SBarry Smith /*@C
22176b2cf59SMatthew Knepley   SNESAddOptionsChecker - Adds an additional function to check for SNES options.
22276b2cf59SMatthew Knepley 
22376b2cf59SMatthew Knepley   Not Collective
22476b2cf59SMatthew Knepley 
22576b2cf59SMatthew Knepley   Input Parameter:
22676b2cf59SMatthew Knepley . snescheck - function that checks for options
22776b2cf59SMatthew Knepley 
22876b2cf59SMatthew Knepley   Level: developer
22976b2cf59SMatthew Knepley 
23076b2cf59SMatthew Knepley .seealso: SNESSetFromOptions()
23176b2cf59SMatthew Knepley @*/
2327087cfbeSBarry Smith PetscErrorCode  SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES))
23376b2cf59SMatthew Knepley {
23476b2cf59SMatthew Knepley   PetscFunctionBegin;
23576b2cf59SMatthew Knepley   if (numberofsetfromoptions >= MAXSETFROMOPTIONS) {
236e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS);
23776b2cf59SMatthew Knepley   }
23876b2cf59SMatthew Knepley   othersetfromoptions[numberofsetfromoptions++] = snescheck;
23976b2cf59SMatthew Knepley   PetscFunctionReturn(0);
24076b2cf59SMatthew Knepley }
24176b2cf59SMatthew Knepley 
2427087cfbeSBarry Smith extern PetscErrorCode  SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*);
243aa3661deSLisandro Dalcin 
244aa3661deSLisandro Dalcin #undef __FUNCT__
245aa3661deSLisandro Dalcin #define __FUNCT__ "SNESSetUpMatrixFree_Private"
246ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool  hasOperator, PetscInt version)
247aa3661deSLisandro Dalcin {
248aa3661deSLisandro Dalcin   Mat            J;
249aa3661deSLisandro Dalcin   KSP            ksp;
250aa3661deSLisandro Dalcin   PC             pc;
251ace3abfcSBarry Smith   PetscBool      match;
252aa3661deSLisandro Dalcin   PetscErrorCode ierr;
253aa3661deSLisandro Dalcin 
254aa3661deSLisandro Dalcin   PetscFunctionBegin;
2550700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
256aa3661deSLisandro Dalcin 
25798613b67SLisandro Dalcin   if(!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) {
25898613b67SLisandro Dalcin     Mat A = snes->jacobian, B = snes->jacobian_pre;
25998613b67SLisandro Dalcin     ierr = MatGetVecs(A ? A : B, PETSC_NULL,&snes->vec_func);CHKERRQ(ierr);
26098613b67SLisandro Dalcin   }
26198613b67SLisandro Dalcin 
262aa3661deSLisandro Dalcin   if (version == 1) {
263aa3661deSLisandro Dalcin     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
26498613b67SLisandro Dalcin     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
2659c6ac3b3SBarry Smith     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
266aa3661deSLisandro Dalcin   } else if (version == 2) {
267e32f2f54SBarry Smith     if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first");
26882a7e548SBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
269aa3661deSLisandro Dalcin     ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr);
270aa3661deSLisandro Dalcin #else
271e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)");
272aa3661deSLisandro Dalcin #endif
273a8248277SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2");
274aa3661deSLisandro Dalcin 
275aa3661deSLisandro Dalcin   ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr);
276d3462f78SMatthew Knepley   if (hasOperator) {
277aa3661deSLisandro Dalcin     /* This version replaces the user provided Jacobian matrix with a
278aa3661deSLisandro Dalcin        matrix-free version but still employs the user-provided preconditioner matrix. */
279aa3661deSLisandro Dalcin     ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr);
280aa3661deSLisandro Dalcin   } else {
281aa3661deSLisandro Dalcin     /* This version replaces both the user-provided Jacobian and the user-
282aa3661deSLisandro Dalcin        provided preconditioner matrix with the default matrix free version. */
283aa3661deSLisandro Dalcin     ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,snes->funP);CHKERRQ(ierr);
284aa3661deSLisandro Dalcin     /* Force no preconditioner */
285aa3661deSLisandro Dalcin     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
286aa3661deSLisandro Dalcin     ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr);
287aa3661deSLisandro Dalcin     ierr = PetscTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr);
288aa3661deSLisandro Dalcin     if (!match) {
289aa3661deSLisandro Dalcin       ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr);
290aa3661deSLisandro Dalcin       ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr);
291aa3661deSLisandro Dalcin     }
292aa3661deSLisandro Dalcin   }
2936bf464f9SBarry Smith   ierr = MatDestroy(&J);CHKERRQ(ierr);
294aa3661deSLisandro Dalcin   PetscFunctionReturn(0);
295aa3661deSLisandro Dalcin }
296aa3661deSLisandro Dalcin 
2974a2ae208SSatish Balay #undef __FUNCT__
2984a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions"
2999b94acceSBarry Smith /*@
30094b7f48cSBarry Smith    SNESSetFromOptions - Sets various SNES and KSP parameters from user options.
3019b94acceSBarry Smith 
302c7afd0dbSLois Curfman McInnes    Collective on SNES
303c7afd0dbSLois Curfman McInnes 
3049b94acceSBarry Smith    Input Parameter:
3059b94acceSBarry Smith .  snes - the SNES context
3069b94acceSBarry Smith 
30736851e7fSLois Curfman McInnes    Options Database Keys:
308ea630c6eSPeter Brune +  -snes_type <type> - ls, tr, ngmres, ncg, richardson, qn, vi, fas
30982738288SBarry Smith .  -snes_stol - convergence tolerance in terms of the norm
31082738288SBarry Smith                 of the change in the solution between steps
31170441072SBarry Smith .  -snes_atol <abstol> - absolute tolerance of residual norm
312b39c3a46SLois Curfman McInnes .  -snes_rtol <rtol> - relative decrease in tolerance norm from initial
313b39c3a46SLois Curfman McInnes .  -snes_max_it <max_it> - maximum number of iterations
314b39c3a46SLois Curfman McInnes .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
315*4839bfe8SBarry Smith .  -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none
316ddf469c8SBarry Smith .  -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops
317a8054027SBarry Smith .  -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild)
318e35cf81dSBarry Smith .  -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild)
319b39c3a46SLois Curfman McInnes .  -snes_trtol <trtol> - trust region tolerance
3202492ecdbSBarry Smith .  -snes_no_convergence_test - skip convergence test in nonlinear
32182738288SBarry Smith                                solver; hence iterations will continue until max_it
3221fbbfb26SLois Curfman McInnes                                or some other criterion is reached. Saves expense
32382738288SBarry Smith                                of convergence test
324e8105e01SRichard Katz .  -snes_monitor <optional filename> - prints residual norm at each iteration. if no
325e8105e01SRichard Katz                                        filename given prints to stdout
326a6570f20SBarry Smith .  -snes_monitor_solution - plots solution at each iteration
327a6570f20SBarry Smith .  -snes_monitor_residual - plots residual (not its norm) at each iteration
328a6570f20SBarry Smith .  -snes_monitor_solution_update - plots update to solution at each iteration
329a6570f20SBarry Smith .  -snes_monitor_draw - plots residual norm at each iteration
330e24b481bSBarry Smith .  -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
3315968eb51SBarry Smith .  -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
332fee2055bSBarry Smith -  -snes_converged_reason - print the reason for convergence/divergence after each solve
33382738288SBarry Smith 
33482738288SBarry Smith     Options Database for Eisenstat-Walker method:
335fa9f3622SBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
3364b27c08aSLois Curfman McInnes .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
33736851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
33836851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
33936851e7fSLois Curfman McInnes .  -snes_ksp_ew_gamma <gamma> - Sets gamma
34036851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha <alpha> - Sets alpha
34136851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
34236851e7fSLois Curfman McInnes -  -snes_ksp_ew_threshold <threshold> - Sets threshold
34382738288SBarry Smith 
34411ca99fdSLois Curfman McInnes    Notes:
34511ca99fdSLois Curfman McInnes    To see all options, run your program with the -help option or consult
3460598bfebSBarry Smith    the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>.
34783e2fdc7SBarry Smith 
34836851e7fSLois Curfman McInnes    Level: beginner
34936851e7fSLois Curfman McInnes 
3509b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database
3519b94acceSBarry Smith 
35269ed319cSSatish Balay .seealso: SNESSetOptionsPrefix()
3539b94acceSBarry Smith @*/
3547087cfbeSBarry Smith PetscErrorCode  SNESSetFromOptions(SNES snes)
3559b94acceSBarry Smith {
356ea630c6eSPeter Brune   PetscBool               flg,set,mf,mf_operator,pcset;
357efd51863SBarry Smith   PetscInt                i,indx,lag,mf_version,grids;
358aa3661deSLisandro Dalcin   MatStructure            matflag;
35985385478SLisandro Dalcin   const char              *deft = SNESLS;
36085385478SLisandro Dalcin   const char              *convtests[] = {"default","skip"};
36185385478SLisandro Dalcin   SNESKSPEW               *kctx = NULL;
362e8105e01SRichard Katz   char                    type[256], monfilename[PETSC_MAX_PATH_LEN];
36351e86f29SPeter Brune   const char              *optionsprefix;
364649052a6SBarry Smith   PetscViewer             monviewer;
36585385478SLisandro Dalcin   PetscErrorCode          ierr;
3669b94acceSBarry Smith 
3673a40ed3dSBarry Smith   PetscFunctionBegin;
3680700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
369ca161407SBarry Smith 
370186905e3SBarry Smith   if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
3713194b578SJed Brown   ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr);
3727adad957SLisandro Dalcin     if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; }
373b0a32e0cSBarry Smith     ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr);
374d64ed03dSBarry Smith     if (flg) {
375186905e3SBarry Smith       ierr = SNESSetType(snes,type);CHKERRQ(ierr);
3767adad957SLisandro Dalcin     } else if (!((PetscObject)snes)->type_name) {
377186905e3SBarry Smith       ierr = SNESSetType(snes,deft);CHKERRQ(ierr);
378d64ed03dSBarry Smith     }
37990d69ab7SBarry Smith     /* not used here, but called so will go into help messaage */
380909c8a9fSBarry Smith     ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr);
38193c39befSBarry Smith 
38257034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->xtol,&snes->xtol,0);CHKERRQ(ierr);
38357034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr);
384186905e3SBarry Smith 
38557034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr);
386b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr);
387b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr);
38850ffb88aSMatthew Knepley     ierr = PetscOptionsInt("-snes_max_fail","Maximum failures","SNESSetTolerances",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr);
389ddf469c8SBarry Smith     ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr);
390acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);CHKERRQ(ierr);
39185385478SLisandro Dalcin 
392a8054027SBarry Smith     ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr);
393a8054027SBarry Smith     if (flg) {
394a8054027SBarry Smith       ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr);
395a8054027SBarry Smith     }
396e35cf81dSBarry Smith     ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr);
397e35cf81dSBarry Smith     if (flg) {
398e35cf81dSBarry Smith       ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr);
399e35cf81dSBarry Smith     }
400efd51863SBarry Smith     ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr);
401efd51863SBarry Smith     if (flg) {
402efd51863SBarry Smith       ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr);
403efd51863SBarry Smith     }
404a8054027SBarry Smith 
40585385478SLisandro Dalcin     ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr);
40685385478SLisandro Dalcin     if (flg) {
40785385478SLisandro Dalcin       switch (indx) {
4087f7931b9SBarry Smith       case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break;
4097f7931b9SBarry Smith       case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);    break;
41085385478SLisandro Dalcin       }
41185385478SLisandro Dalcin     }
41285385478SLisandro Dalcin 
413acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr);
414186905e3SBarry Smith 
41585385478SLisandro Dalcin     kctx = (SNESKSPEW *)snes->kspconvctx;
41685385478SLisandro Dalcin 
417acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr);
418186905e3SBarry Smith 
419fa9f3622SBarry Smith     ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr);
420fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr);
421fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr);
422fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr);
423fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr);
424fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr);
425fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr);
426186905e3SBarry Smith 
42790d69ab7SBarry Smith     flg  = PETSC_FALSE;
428acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
429a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);}
430eabae89aSBarry Smith 
431a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
432e8105e01SRichard Katz     if (flg) {
433649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
434649052a6SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
435e8105e01SRichard Katz     }
436eabae89aSBarry Smith 
437b271bb04SBarry Smith     ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
438b271bb04SBarry Smith     if (flg) {
439b271bb04SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr);
440b271bb04SBarry Smith     }
441b271bb04SBarry Smith 
442a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
443eabae89aSBarry Smith     if (flg) {
444649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
445f1bef1bcSMatthew Knepley       ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr);
446e8105e01SRichard Katz     }
447eabae89aSBarry Smith 
448a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
449eabae89aSBarry Smith     if (flg) {
450649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
451649052a6SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
452eabae89aSBarry Smith     }
453eabae89aSBarry Smith 
4545180491cSLisandro Dalcin     ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
4555180491cSLisandro Dalcin     if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);}
4565180491cSLisandro Dalcin 
45790d69ab7SBarry Smith     flg  = PETSC_FALSE;
458acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
459a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);}
46090d69ab7SBarry Smith     flg  = PETSC_FALSE;
461acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
462a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);}
46390d69ab7SBarry Smith     flg  = PETSC_FALSE;
464acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
465a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);}
46690d69ab7SBarry Smith     flg  = PETSC_FALSE;
467acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
468a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
46990d69ab7SBarry Smith     flg  = PETSC_FALSE;
470acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
471b271bb04SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
472e24b481bSBarry Smith 
47390d69ab7SBarry Smith     flg  = PETSC_FALSE;
474acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
4754b27c08aSLois Curfman McInnes     if (flg) {
476186905e3SBarry Smith       ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,snes->funP);CHKERRQ(ierr);
477ae15b995SBarry Smith       ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr);
4789b94acceSBarry Smith     }
479639f9d9dSBarry Smith 
480aa3661deSLisandro Dalcin     mf = mf_operator = PETSC_FALSE;
481aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
482acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr);
483a8248277SBarry Smith     if (flg && mf_operator) {
484a8248277SBarry Smith       snes->mf_operator = PETSC_TRUE;
485a8248277SBarry Smith       mf = PETSC_TRUE;
486a8248277SBarry Smith     }
487aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
488acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);CHKERRQ(ierr);
489aa3661deSLisandro Dalcin     if (!flg && mf_operator) mf = PETSC_TRUE;
490aa3661deSLisandro Dalcin     mf_version = 1;
491aa3661deSLisandro Dalcin     ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);CHKERRQ(ierr);
492aa3661deSLisandro Dalcin 
493ea630c6eSPeter Brune     /* line search options */
494ea630c6eSPeter Brune     ierr = PetscOptionsReal("-snes_ls_alpha","Constant function norm must decrease by","None",snes->ls_alpha,&snes->ls_alpha,0);CHKERRQ(ierr);
495ea630c6eSPeter Brune     ierr = PetscOptionsReal("-snes_ls_maxstep","Step must be less than","None",snes->maxstep,&snes->maxstep,0);CHKERRQ(ierr);
496ea630c6eSPeter Brune     ierr = PetscOptionsReal("-snes_ls_steptol","Minimum lambda allowed","None",snes->steptol,&snes->steptol,0);CHKERRQ(ierr);
497ea630c6eSPeter Brune     ierr = PetscOptionsReal("-snes_ls_damping","Damping parameter","SNES",snes->damping,&snes->damping,&flg);CHKERRQ(ierr);
498af60355fSPeter Brune     ierr = PetscOptionsInt("-snes_ls_it"      ,"Line search iterations","SNES",snes->ls_its,&snes->ls_its,&flg);CHKERRQ(ierr);
499ea630c6eSPeter Brune     ierr = PetscOptionsBool("-snes_ls_monitor","Print progress of line searches","SNESLineSearchSetMonitor",snes->ls_monitor ? PETSC_TRUE : PETSC_FALSE,&flg,&set);CHKERRQ(ierr);
500ea630c6eSPeter Brune     if (set) {ierr = SNESLineSearchSetMonitor(snes,flg);CHKERRQ(ierr);}
50115f5eeeaSPeter Brune     ierr = PetscOptionsEnum("-snes_ls","Line search used","SNESLineSearchSet",SNESLineSearchTypes,(PetscEnum)snes->ls_type,(PetscEnum*)&indx,&flg);CHKERRQ(ierr);
50215f5eeeaSPeter Brune     if (flg) {
503ea630c6eSPeter Brune       ierr = SNESLineSearchSetType(snes,(SNESLineSearchType)indx);CHKERRQ(ierr);
50415f5eeeaSPeter Brune     }
5058e3fc8c0SJed Brown     flg = snes->ops->precheckstep == SNESLineSearchPreCheckPicard ? PETSC_TRUE : PETSC_FALSE;
5068e3fc8c0SJed Brown     ierr = PetscOptionsBool("-snes_ls_precheck_picard","Use a correction that sometimes improves convergence of Picard iteration","SNESLineSearchPreCheckPicard",flg,&flg,&set);CHKERRQ(ierr);
5078e3fc8c0SJed Brown     if (set) {
5088e3fc8c0SJed Brown       if (flg) {
5098e3fc8c0SJed Brown         snes->precheck_picard_angle = 10.; /* correction only active if angle is less than 10 degrees */
5108e3fc8c0SJed 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);
5118e3fc8c0SJed Brown         ierr = SNESLineSearchSetPreCheck(snes,SNESLineSearchPreCheckPicard,&snes->precheck_picard_angle);CHKERRQ(ierr);
5128e3fc8c0SJed Brown       } else {
5138e3fc8c0SJed Brown         ierr = SNESLineSearchSetPreCheck(snes,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
5148e3fc8c0SJed Brown       }
5158e3fc8c0SJed Brown     }
5168e3fc8c0SJed Brown 
51776b2cf59SMatthew Knepley     for(i = 0; i < numberofsetfromoptions; i++) {
51876b2cf59SMatthew Knepley       ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr);
51976b2cf59SMatthew Knepley     }
52076b2cf59SMatthew Knepley 
521e7788613SBarry Smith     if (snes->ops->setfromoptions) {
522e7788613SBarry Smith       ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr);
523639f9d9dSBarry Smith     }
5245d973c19SBarry Smith 
5255d973c19SBarry Smith     /* process any options handlers added with PetscObjectAddOptionsHandler() */
5265d973c19SBarry Smith     ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr);
527b0a32e0cSBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
5284bbc92c1SBarry Smith 
529aa3661deSLisandro Dalcin   if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); }
5301cee3971SBarry Smith 
5311cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
532aa3661deSLisandro Dalcin   ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag);
533aa3661deSLisandro Dalcin   ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr);
53485385478SLisandro Dalcin   ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr);
53593993e2dSLois Curfman McInnes 
53651e86f29SPeter Brune   /* if someone has set the SNES PC type, create it. */
53751e86f29SPeter Brune   ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
53851e86f29SPeter Brune   ierr = PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr);
53951e86f29SPeter Brune   if (pcset && (!snes->pc)) {
54051e86f29SPeter Brune     ierr = SNESGetPC(snes, &snes->pc);CHKERRQ(ierr);
54151e86f29SPeter Brune   }
54251e86f29SPeter Brune 
5434a0c5b0cSMatthew G Knepley   if (snes->pc) {
5444a0c5b0cSMatthew G Knepley     ierr = SNESSetOptionsPrefix(snes->pc, "npc_");CHKERRQ(ierr);
5454a0c5b0cSMatthew G Knepley     ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr);
546646217ecSPeter Brune     ierr = SNESSetGS(snes->pc, snes->ops->computegs, snes->gsP);CHKERRQ(ierr);
5474a0c5b0cSMatthew G Knepley     /* Should we make a duplicate vector and matrix? Leave the DM to make it? */
5484a0c5b0cSMatthew G Knepley     ierr = SNESSetFunction(snes->pc, snes->vec_func, snes->ops->computefunction, snes->funP);CHKERRQ(ierr);
5494a0c5b0cSMatthew G Knepley     ierr = SNESSetJacobian(snes->pc, snes->jacobian, snes->jacobian_pre, snes->ops->computejacobian, snes->jacP);CHKERRQ(ierr);
5504a0c5b0cSMatthew G Knepley     ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr);
5514a0c5b0cSMatthew G Knepley   }
5523a40ed3dSBarry Smith   PetscFunctionReturn(0);
5539b94acceSBarry Smith }
5549b94acceSBarry Smith 
555d25893d9SBarry Smith #undef __FUNCT__
556d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext"
557d25893d9SBarry Smith /*@
558d25893d9SBarry Smith    SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for
559d25893d9SBarry Smith    the nonlinear solvers.
560d25893d9SBarry Smith 
561d25893d9SBarry Smith    Logically Collective on SNES
562d25893d9SBarry Smith 
563d25893d9SBarry Smith    Input Parameters:
564d25893d9SBarry Smith +  snes - the SNES context
565d25893d9SBarry Smith .  compute - function to compute the context
566d25893d9SBarry Smith -  destroy - function to destroy the context
567d25893d9SBarry Smith 
568d25893d9SBarry Smith    Level: intermediate
569d25893d9SBarry Smith 
570d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context
571d25893d9SBarry Smith 
572d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext()
573d25893d9SBarry Smith @*/
574d25893d9SBarry Smith PetscErrorCode  SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**))
575d25893d9SBarry Smith {
576d25893d9SBarry Smith   PetscFunctionBegin;
577d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
578d25893d9SBarry Smith   snes->ops->usercompute = compute;
579d25893d9SBarry Smith   snes->ops->userdestroy = destroy;
580d25893d9SBarry Smith   PetscFunctionReturn(0);
581d25893d9SBarry Smith }
582a847f771SSatish Balay 
5834a2ae208SSatish Balay #undef __FUNCT__
5844a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext"
585b07ff414SBarry Smith /*@
5869b94acceSBarry Smith    SNESSetApplicationContext - Sets the optional user-defined context for
5879b94acceSBarry Smith    the nonlinear solvers.
5889b94acceSBarry Smith 
5893f9fe445SBarry Smith    Logically Collective on SNES
590fee21e36SBarry Smith 
591c7afd0dbSLois Curfman McInnes    Input Parameters:
592c7afd0dbSLois Curfman McInnes +  snes - the SNES context
593c7afd0dbSLois Curfman McInnes -  usrP - optional user context
594c7afd0dbSLois Curfman McInnes 
59536851e7fSLois Curfman McInnes    Level: intermediate
59636851e7fSLois Curfman McInnes 
5979b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context
5989b94acceSBarry Smith 
599d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetApplicationContext()
6009b94acceSBarry Smith @*/
6017087cfbeSBarry Smith PetscErrorCode  SNESSetApplicationContext(SNES snes,void *usrP)
6029b94acceSBarry Smith {
6031b2093e4SBarry Smith   PetscErrorCode ierr;
604b07ff414SBarry Smith   KSP            ksp;
6051b2093e4SBarry Smith 
6063a40ed3dSBarry Smith   PetscFunctionBegin;
6070700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
608b07ff414SBarry Smith   ierr       = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
609b07ff414SBarry Smith   ierr       = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr);
6109b94acceSBarry Smith   snes->user = usrP;
6113a40ed3dSBarry Smith   PetscFunctionReturn(0);
6129b94acceSBarry Smith }
61374679c65SBarry Smith 
6144a2ae208SSatish Balay #undef __FUNCT__
6154a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext"
616b07ff414SBarry Smith /*@
6179b94acceSBarry Smith    SNESGetApplicationContext - Gets the user-defined context for the
6189b94acceSBarry Smith    nonlinear solvers.
6199b94acceSBarry Smith 
620c7afd0dbSLois Curfman McInnes    Not Collective
621c7afd0dbSLois Curfman McInnes 
6229b94acceSBarry Smith    Input Parameter:
6239b94acceSBarry Smith .  snes - SNES context
6249b94acceSBarry Smith 
6259b94acceSBarry Smith    Output Parameter:
6269b94acceSBarry Smith .  usrP - user context
6279b94acceSBarry Smith 
62836851e7fSLois Curfman McInnes    Level: intermediate
62936851e7fSLois Curfman McInnes 
6309b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context
6319b94acceSBarry Smith 
6329b94acceSBarry Smith .seealso: SNESSetApplicationContext()
6339b94acceSBarry Smith @*/
634e71120c6SJed Brown PetscErrorCode  SNESGetApplicationContext(SNES snes,void *usrP)
6359b94acceSBarry Smith {
6363a40ed3dSBarry Smith   PetscFunctionBegin;
6370700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
638e71120c6SJed Brown   *(void**)usrP = snes->user;
6393a40ed3dSBarry Smith   PetscFunctionReturn(0);
6409b94acceSBarry Smith }
64174679c65SBarry Smith 
6424a2ae208SSatish Balay #undef __FUNCT__
6434a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber"
6449b94acceSBarry Smith /*@
645c8228a4eSBarry Smith    SNESGetIterationNumber - Gets the number of nonlinear iterations completed
646c8228a4eSBarry Smith    at this time.
6479b94acceSBarry Smith 
648c7afd0dbSLois Curfman McInnes    Not Collective
649c7afd0dbSLois Curfman McInnes 
6509b94acceSBarry Smith    Input Parameter:
6519b94acceSBarry Smith .  snes - SNES context
6529b94acceSBarry Smith 
6539b94acceSBarry Smith    Output Parameter:
6549b94acceSBarry Smith .  iter - iteration number
6559b94acceSBarry Smith 
656c8228a4eSBarry Smith    Notes:
657c8228a4eSBarry Smith    For example, during the computation of iteration 2 this would return 1.
658c8228a4eSBarry Smith 
659c8228a4eSBarry Smith    This is useful for using lagged Jacobians (where one does not recompute the
66008405cd6SLois Curfman McInnes    Jacobian at each SNES iteration). For example, the code
66108405cd6SLois Curfman McInnes .vb
66208405cd6SLois Curfman McInnes       ierr = SNESGetIterationNumber(snes,&it);
66308405cd6SLois Curfman McInnes       if (!(it % 2)) {
66408405cd6SLois Curfman McInnes         [compute Jacobian here]
66508405cd6SLois Curfman McInnes       }
66608405cd6SLois Curfman McInnes .ve
667c8228a4eSBarry Smith    can be used in your ComputeJacobian() function to cause the Jacobian to be
66808405cd6SLois Curfman McInnes    recomputed every second SNES iteration.
669c8228a4eSBarry Smith 
67036851e7fSLois Curfman McInnes    Level: intermediate
67136851e7fSLois Curfman McInnes 
6722b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number,
6732b668275SBarry Smith 
674b850b91aSLisandro Dalcin .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
6759b94acceSBarry Smith @*/
6767087cfbeSBarry Smith PetscErrorCode  SNESGetIterationNumber(SNES snes,PetscInt* iter)
6779b94acceSBarry Smith {
6783a40ed3dSBarry Smith   PetscFunctionBegin;
6790700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
6804482741eSBarry Smith   PetscValidIntPointer(iter,2);
6819b94acceSBarry Smith   *iter = snes->iter;
6823a40ed3dSBarry Smith   PetscFunctionReturn(0);
6839b94acceSBarry Smith }
68474679c65SBarry Smith 
6854a2ae208SSatish Balay #undef __FUNCT__
6864a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm"
6879b94acceSBarry Smith /*@
6889b94acceSBarry Smith    SNESGetFunctionNorm - Gets the norm of the current function that was set
6899b94acceSBarry Smith    with SNESSSetFunction().
6909b94acceSBarry Smith 
691c7afd0dbSLois Curfman McInnes    Collective on SNES
692c7afd0dbSLois Curfman McInnes 
6939b94acceSBarry Smith    Input Parameter:
6949b94acceSBarry Smith .  snes - SNES context
6959b94acceSBarry Smith 
6969b94acceSBarry Smith    Output Parameter:
6979b94acceSBarry Smith .  fnorm - 2-norm of function
6989b94acceSBarry Smith 
69936851e7fSLois Curfman McInnes    Level: intermediate
70036851e7fSLois Curfman McInnes 
7019b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm
702a86d99e1SLois Curfman McInnes 
703b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations()
7049b94acceSBarry Smith @*/
7057087cfbeSBarry Smith PetscErrorCode  SNESGetFunctionNorm(SNES snes,PetscReal *fnorm)
7069b94acceSBarry Smith {
7073a40ed3dSBarry Smith   PetscFunctionBegin;
7080700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
7094482741eSBarry Smith   PetscValidScalarPointer(fnorm,2);
7109b94acceSBarry Smith   *fnorm = snes->norm;
7113a40ed3dSBarry Smith   PetscFunctionReturn(0);
7129b94acceSBarry Smith }
71374679c65SBarry Smith 
7144a2ae208SSatish Balay #undef __FUNCT__
715b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures"
7169b94acceSBarry Smith /*@
717b850b91aSLisandro Dalcin    SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
7189b94acceSBarry Smith    attempted by the nonlinear solver.
7199b94acceSBarry Smith 
720c7afd0dbSLois Curfman McInnes    Not Collective
721c7afd0dbSLois Curfman McInnes 
7229b94acceSBarry Smith    Input Parameter:
7239b94acceSBarry Smith .  snes - SNES context
7249b94acceSBarry Smith 
7259b94acceSBarry Smith    Output Parameter:
7269b94acceSBarry Smith .  nfails - number of unsuccessful steps attempted
7279b94acceSBarry Smith 
728c96a6f78SLois Curfman McInnes    Notes:
729c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
730c96a6f78SLois Curfman McInnes 
73136851e7fSLois Curfman McInnes    Level: intermediate
73236851e7fSLois Curfman McInnes 
7339b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
73458ebbce7SBarry Smith 
735e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
73658ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures()
7379b94acceSBarry Smith @*/
7387087cfbeSBarry Smith PetscErrorCode  SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails)
7399b94acceSBarry Smith {
7403a40ed3dSBarry Smith   PetscFunctionBegin;
7410700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
7424482741eSBarry Smith   PetscValidIntPointer(nfails,2);
74350ffb88aSMatthew Knepley   *nfails = snes->numFailures;
74450ffb88aSMatthew Knepley   PetscFunctionReturn(0);
74550ffb88aSMatthew Knepley }
74650ffb88aSMatthew Knepley 
74750ffb88aSMatthew Knepley #undef __FUNCT__
748b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures"
74950ffb88aSMatthew Knepley /*@
750b850b91aSLisandro Dalcin    SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
75150ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
75250ffb88aSMatthew Knepley 
75350ffb88aSMatthew Knepley    Not Collective
75450ffb88aSMatthew Knepley 
75550ffb88aSMatthew Knepley    Input Parameters:
75650ffb88aSMatthew Knepley +  snes     - SNES context
75750ffb88aSMatthew Knepley -  maxFails - maximum of unsuccessful steps
75850ffb88aSMatthew Knepley 
75950ffb88aSMatthew Knepley    Level: intermediate
76050ffb88aSMatthew Knepley 
76150ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
76258ebbce7SBarry Smith 
763e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
76458ebbce7SBarry Smith           SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
76550ffb88aSMatthew Knepley @*/
7667087cfbeSBarry Smith PetscErrorCode  SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
76750ffb88aSMatthew Knepley {
76850ffb88aSMatthew Knepley   PetscFunctionBegin;
7690700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
77050ffb88aSMatthew Knepley   snes->maxFailures = maxFails;
77150ffb88aSMatthew Knepley   PetscFunctionReturn(0);
77250ffb88aSMatthew Knepley }
77350ffb88aSMatthew Knepley 
77450ffb88aSMatthew Knepley #undef __FUNCT__
775b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures"
77650ffb88aSMatthew Knepley /*@
777b850b91aSLisandro Dalcin    SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
77850ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
77950ffb88aSMatthew Knepley 
78050ffb88aSMatthew Knepley    Not Collective
78150ffb88aSMatthew Knepley 
78250ffb88aSMatthew Knepley    Input Parameter:
78350ffb88aSMatthew Knepley .  snes     - SNES context
78450ffb88aSMatthew Knepley 
78550ffb88aSMatthew Knepley    Output Parameter:
78650ffb88aSMatthew Knepley .  maxFails - maximum of unsuccessful steps
78750ffb88aSMatthew Knepley 
78850ffb88aSMatthew Knepley    Level: intermediate
78950ffb88aSMatthew Knepley 
79050ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
79158ebbce7SBarry Smith 
792e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
79358ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
79458ebbce7SBarry Smith 
79550ffb88aSMatthew Knepley @*/
7967087cfbeSBarry Smith PetscErrorCode  SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
79750ffb88aSMatthew Knepley {
79850ffb88aSMatthew Knepley   PetscFunctionBegin;
7990700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
8004482741eSBarry Smith   PetscValidIntPointer(maxFails,2);
80150ffb88aSMatthew Knepley   *maxFails = snes->maxFailures;
8023a40ed3dSBarry Smith   PetscFunctionReturn(0);
8039b94acceSBarry Smith }
804a847f771SSatish Balay 
8054a2ae208SSatish Balay #undef __FUNCT__
8062541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals"
8072541af92SBarry Smith /*@
8082541af92SBarry Smith    SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations
8092541af92SBarry Smith      done by SNES.
8102541af92SBarry Smith 
8112541af92SBarry Smith    Not Collective
8122541af92SBarry Smith 
8132541af92SBarry Smith    Input Parameter:
8142541af92SBarry Smith .  snes     - SNES context
8152541af92SBarry Smith 
8162541af92SBarry Smith    Output Parameter:
8172541af92SBarry Smith .  nfuncs - number of evaluations
8182541af92SBarry Smith 
8192541af92SBarry Smith    Level: intermediate
8202541af92SBarry Smith 
8212541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
82258ebbce7SBarry Smith 
823e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures()
8242541af92SBarry Smith @*/
8257087cfbeSBarry Smith PetscErrorCode  SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs)
8262541af92SBarry Smith {
8272541af92SBarry Smith   PetscFunctionBegin;
8280700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
8292541af92SBarry Smith   PetscValidIntPointer(nfuncs,2);
8302541af92SBarry Smith   *nfuncs = snes->nfuncs;
8312541af92SBarry Smith   PetscFunctionReturn(0);
8322541af92SBarry Smith }
8332541af92SBarry Smith 
8342541af92SBarry Smith #undef __FUNCT__
8353d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures"
8363d4c4710SBarry Smith /*@
8373d4c4710SBarry Smith    SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
8383d4c4710SBarry Smith    linear solvers.
8393d4c4710SBarry Smith 
8403d4c4710SBarry Smith    Not Collective
8413d4c4710SBarry Smith 
8423d4c4710SBarry Smith    Input Parameter:
8433d4c4710SBarry Smith .  snes - SNES context
8443d4c4710SBarry Smith 
8453d4c4710SBarry Smith    Output Parameter:
8463d4c4710SBarry Smith .  nfails - number of failed solves
8473d4c4710SBarry Smith 
8483d4c4710SBarry Smith    Notes:
8493d4c4710SBarry Smith    This counter is reset to zero for each successive call to SNESSolve().
8503d4c4710SBarry Smith 
8513d4c4710SBarry Smith    Level: intermediate
8523d4c4710SBarry Smith 
8533d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
85458ebbce7SBarry Smith 
855e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures()
8563d4c4710SBarry Smith @*/
8577087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails)
8583d4c4710SBarry Smith {
8593d4c4710SBarry Smith   PetscFunctionBegin;
8600700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
8613d4c4710SBarry Smith   PetscValidIntPointer(nfails,2);
8623d4c4710SBarry Smith   *nfails = snes->numLinearSolveFailures;
8633d4c4710SBarry Smith   PetscFunctionReturn(0);
8643d4c4710SBarry Smith }
8653d4c4710SBarry Smith 
8663d4c4710SBarry Smith #undef __FUNCT__
8673d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures"
8683d4c4710SBarry Smith /*@
8693d4c4710SBarry Smith    SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
8703d4c4710SBarry Smith    allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE
8713d4c4710SBarry Smith 
8723f9fe445SBarry Smith    Logically Collective on SNES
8733d4c4710SBarry Smith 
8743d4c4710SBarry Smith    Input Parameters:
8753d4c4710SBarry Smith +  snes     - SNES context
8763d4c4710SBarry Smith -  maxFails - maximum allowed linear solve failures
8773d4c4710SBarry Smith 
8783d4c4710SBarry Smith    Level: intermediate
8793d4c4710SBarry Smith 
880a6796414SBarry Smith    Notes: By default this is 0; that is SNES returns on the first failed linear solve
8813d4c4710SBarry Smith 
8823d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
8833d4c4710SBarry Smith 
88458ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations()
8853d4c4710SBarry Smith @*/
8867087cfbeSBarry Smith PetscErrorCode  SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
8873d4c4710SBarry Smith {
8883d4c4710SBarry Smith   PetscFunctionBegin;
8890700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
890c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxFails,2);
8913d4c4710SBarry Smith   snes->maxLinearSolveFailures = maxFails;
8923d4c4710SBarry Smith   PetscFunctionReturn(0);
8933d4c4710SBarry Smith }
8943d4c4710SBarry Smith 
8953d4c4710SBarry Smith #undef __FUNCT__
8963d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures"
8973d4c4710SBarry Smith /*@
8983d4c4710SBarry Smith    SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
8993d4c4710SBarry Smith      are allowed before SNES terminates
9003d4c4710SBarry Smith 
9013d4c4710SBarry Smith    Not Collective
9023d4c4710SBarry Smith 
9033d4c4710SBarry Smith    Input Parameter:
9043d4c4710SBarry Smith .  snes     - SNES context
9053d4c4710SBarry Smith 
9063d4c4710SBarry Smith    Output Parameter:
9073d4c4710SBarry Smith .  maxFails - maximum of unsuccessful solves allowed
9083d4c4710SBarry Smith 
9093d4c4710SBarry Smith    Level: intermediate
9103d4c4710SBarry Smith 
9113d4c4710SBarry Smith    Notes: By default this is 1; that is SNES returns on the first failed linear solve
9123d4c4710SBarry Smith 
9133d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
9143d4c4710SBarry Smith 
915e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(),
9163d4c4710SBarry Smith @*/
9177087cfbeSBarry Smith PetscErrorCode  SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
9183d4c4710SBarry Smith {
9193d4c4710SBarry Smith   PetscFunctionBegin;
9200700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9213d4c4710SBarry Smith   PetscValidIntPointer(maxFails,2);
9223d4c4710SBarry Smith   *maxFails = snes->maxLinearSolveFailures;
9233d4c4710SBarry Smith   PetscFunctionReturn(0);
9243d4c4710SBarry Smith }
9253d4c4710SBarry Smith 
9263d4c4710SBarry Smith #undef __FUNCT__
927b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations"
928c96a6f78SLois Curfman McInnes /*@
929b850b91aSLisandro Dalcin    SNESGetLinearSolveIterations - Gets the total number of linear iterations
930c96a6f78SLois Curfman McInnes    used by the nonlinear solver.
931c96a6f78SLois Curfman McInnes 
932c7afd0dbSLois Curfman McInnes    Not Collective
933c7afd0dbSLois Curfman McInnes 
934c96a6f78SLois Curfman McInnes    Input Parameter:
935c96a6f78SLois Curfman McInnes .  snes - SNES context
936c96a6f78SLois Curfman McInnes 
937c96a6f78SLois Curfman McInnes    Output Parameter:
938c96a6f78SLois Curfman McInnes .  lits - number of linear iterations
939c96a6f78SLois Curfman McInnes 
940c96a6f78SLois Curfman McInnes    Notes:
941c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
942c96a6f78SLois Curfman McInnes 
94336851e7fSLois Curfman McInnes    Level: intermediate
94436851e7fSLois Curfman McInnes 
945c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations
9462b668275SBarry Smith 
9478c7482ecSBarry Smith .seealso:  SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures()
948c96a6f78SLois Curfman McInnes @*/
9497087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveIterations(SNES snes,PetscInt* lits)
950c96a6f78SLois Curfman McInnes {
9513a40ed3dSBarry Smith   PetscFunctionBegin;
9520700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9534482741eSBarry Smith   PetscValidIntPointer(lits,2);
954c96a6f78SLois Curfman McInnes   *lits = snes->linear_its;
9553a40ed3dSBarry Smith   PetscFunctionReturn(0);
956c96a6f78SLois Curfman McInnes }
957c96a6f78SLois Curfman McInnes 
9584a2ae208SSatish Balay #undef __FUNCT__
95994b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP"
96052baeb72SSatish Balay /*@
96194b7f48cSBarry Smith    SNESGetKSP - Returns the KSP context for a SNES solver.
9629b94acceSBarry Smith 
96394b7f48cSBarry Smith    Not Collective, but if SNES object is parallel, then KSP object is parallel
964c7afd0dbSLois Curfman McInnes 
9659b94acceSBarry Smith    Input Parameter:
9669b94acceSBarry Smith .  snes - the SNES context
9679b94acceSBarry Smith 
9689b94acceSBarry Smith    Output Parameter:
96994b7f48cSBarry Smith .  ksp - the KSP context
9709b94acceSBarry Smith 
9719b94acceSBarry Smith    Notes:
97294b7f48cSBarry Smith    The user can then directly manipulate the KSP context to set various
9739b94acceSBarry Smith    options, etc.  Likewise, the user can then extract and manipulate the
9742999313aSBarry Smith    PC contexts as well.
9759b94acceSBarry Smith 
97636851e7fSLois Curfman McInnes    Level: beginner
97736851e7fSLois Curfman McInnes 
97894b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
9799b94acceSBarry Smith 
9802999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
9819b94acceSBarry Smith @*/
9827087cfbeSBarry Smith PetscErrorCode  SNESGetKSP(SNES snes,KSP *ksp)
9839b94acceSBarry Smith {
9841cee3971SBarry Smith   PetscErrorCode ierr;
9851cee3971SBarry Smith 
9863a40ed3dSBarry Smith   PetscFunctionBegin;
9870700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9884482741eSBarry Smith   PetscValidPointer(ksp,2);
9891cee3971SBarry Smith 
9901cee3971SBarry Smith   if (!snes->ksp) {
9911cee3971SBarry Smith     ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr);
9921cee3971SBarry Smith     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr);
9931cee3971SBarry Smith     ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr);
9941cee3971SBarry Smith   }
99594b7f48cSBarry Smith   *ksp = snes->ksp;
9963a40ed3dSBarry Smith   PetscFunctionReturn(0);
9979b94acceSBarry Smith }
99882bf6240SBarry Smith 
9994a2ae208SSatish Balay #undef __FUNCT__
10002999313aSBarry Smith #define __FUNCT__ "SNESSetKSP"
10012999313aSBarry Smith /*@
10022999313aSBarry Smith    SNESSetKSP - Sets a KSP context for the SNES object to use
10032999313aSBarry Smith 
10042999313aSBarry Smith    Not Collective, but the SNES and KSP objects must live on the same MPI_Comm
10052999313aSBarry Smith 
10062999313aSBarry Smith    Input Parameters:
10072999313aSBarry Smith +  snes - the SNES context
10082999313aSBarry Smith -  ksp - the KSP context
10092999313aSBarry Smith 
10102999313aSBarry Smith    Notes:
10112999313aSBarry Smith    The SNES object already has its KSP object, you can obtain with SNESGetKSP()
10122999313aSBarry Smith    so this routine is rarely needed.
10132999313aSBarry Smith 
10142999313aSBarry Smith    The KSP object that is already in the SNES object has its reference count
10152999313aSBarry Smith    decreased by one.
10162999313aSBarry Smith 
10172999313aSBarry Smith    Level: developer
10182999313aSBarry Smith 
10192999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
10202999313aSBarry Smith 
10212999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
10222999313aSBarry Smith @*/
10237087cfbeSBarry Smith PetscErrorCode  SNESSetKSP(SNES snes,KSP ksp)
10242999313aSBarry Smith {
10252999313aSBarry Smith   PetscErrorCode ierr;
10262999313aSBarry Smith 
10272999313aSBarry Smith   PetscFunctionBegin;
10280700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10290700a824SBarry Smith   PetscValidHeaderSpecific(ksp,KSP_CLASSID,2);
10302999313aSBarry Smith   PetscCheckSameComm(snes,1,ksp,2);
10317dcf0eaaSdalcinl   ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr);
1032906ed7ccSBarry Smith   if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);}
10332999313aSBarry Smith   snes->ksp = ksp;
10342999313aSBarry Smith   PetscFunctionReturn(0);
10352999313aSBarry Smith }
10362999313aSBarry Smith 
10377adad957SLisandro Dalcin #if 0
10382999313aSBarry Smith #undef __FUNCT__
10394a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc"
10406849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj)
1041e24b481bSBarry Smith {
1042e24b481bSBarry Smith   PetscFunctionBegin;
1043e24b481bSBarry Smith   PetscFunctionReturn(0);
1044e24b481bSBarry Smith }
10457adad957SLisandro Dalcin #endif
1046e24b481bSBarry Smith 
10479b94acceSBarry Smith /* -----------------------------------------------------------*/
10484a2ae208SSatish Balay #undef __FUNCT__
10494a2ae208SSatish Balay #define __FUNCT__ "SNESCreate"
105052baeb72SSatish Balay /*@
10519b94acceSBarry Smith    SNESCreate - Creates a nonlinear solver context.
10529b94acceSBarry Smith 
1053c7afd0dbSLois Curfman McInnes    Collective on MPI_Comm
1054c7afd0dbSLois Curfman McInnes 
1055c7afd0dbSLois Curfman McInnes    Input Parameters:
1056906ed7ccSBarry Smith .  comm - MPI communicator
10579b94acceSBarry Smith 
10589b94acceSBarry Smith    Output Parameter:
10599b94acceSBarry Smith .  outsnes - the new SNES context
10609b94acceSBarry Smith 
1061c7afd0dbSLois Curfman McInnes    Options Database Keys:
1062c7afd0dbSLois Curfman McInnes +   -snes_mf - Activates default matrix-free Jacobian-vector products,
1063c7afd0dbSLois Curfman McInnes                and no preconditioning matrix
1064c7afd0dbSLois Curfman McInnes .   -snes_mf_operator - Activates default matrix-free Jacobian-vector
1065c7afd0dbSLois Curfman McInnes                products, and a user-provided preconditioning matrix
1066c7afd0dbSLois Curfman McInnes                as set by SNESSetJacobian()
1067c7afd0dbSLois Curfman McInnes -   -snes_fd - Uses (slow!) finite differences to compute Jacobian
1068c1f60f51SBarry Smith 
106936851e7fSLois Curfman McInnes    Level: beginner
107036851e7fSLois Curfman McInnes 
10719b94acceSBarry Smith .keywords: SNES, nonlinear, create, context
10729b94acceSBarry Smith 
1073a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner()
1074a8054027SBarry Smith 
10759b94acceSBarry Smith @*/
10767087cfbeSBarry Smith PetscErrorCode  SNESCreate(MPI_Comm comm,SNES *outsnes)
10779b94acceSBarry Smith {
1078dfbe8321SBarry Smith   PetscErrorCode      ierr;
10799b94acceSBarry Smith   SNES                snes;
1080fa9f3622SBarry Smith   SNESKSPEW           *kctx;
108137fcc0dbSBarry Smith 
10823a40ed3dSBarry Smith   PetscFunctionBegin;
1083ed1caa07SMatthew Knepley   PetscValidPointer(outsnes,2);
10848ba1e511SMatthew Knepley   *outsnes = PETSC_NULL;
10858ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES
10868ba1e511SMatthew Knepley   ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr);
10878ba1e511SMatthew Knepley #endif
10888ba1e511SMatthew Knepley 
10893194b578SJed Brown   ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr);
10907adad957SLisandro Dalcin 
109185385478SLisandro Dalcin   snes->ops->converged    = SNESDefaultConverged;
10922c155ee1SBarry Smith   snes->usesksp           = PETSC_TRUE;
10939b94acceSBarry Smith   snes->max_its           = 50;
10949750a799SBarry Smith   snes->max_funcs	  = 10000;
10959b94acceSBarry Smith   snes->norm		  = 0.0;
1096b4874afaSBarry Smith   snes->rtol		  = 1.e-8;
1097b4874afaSBarry Smith   snes->ttol              = 0.0;
109870441072SBarry Smith   snes->abstol		  = 1.e-50;
10999b94acceSBarry Smith   snes->xtol		  = 1.e-8;
11004b27c08aSLois Curfman McInnes   snes->deltatol	  = 1.e-12;
11019b94acceSBarry Smith   snes->nfuncs            = 0;
110250ffb88aSMatthew Knepley   snes->numFailures       = 0;
110350ffb88aSMatthew Knepley   snes->maxFailures       = 1;
11047a00f4a9SLois Curfman McInnes   snes->linear_its        = 0;
1105e35cf81dSBarry Smith   snes->lagjacobian       = 1;
1106a8054027SBarry Smith   snes->lagpreconditioner = 1;
1107639f9d9dSBarry Smith   snes->numbermonitors    = 0;
11089b94acceSBarry Smith   snes->data              = 0;
11094dc4c822SBarry Smith   snes->setupcalled       = PETSC_FALSE;
1110186905e3SBarry Smith   snes->ksp_ewconv        = PETSC_FALSE;
11116f24a144SLois Curfman McInnes   snes->nwork             = 0;
111258c9b817SLisandro Dalcin   snes->work              = 0;
111358c9b817SLisandro Dalcin   snes->nvwork            = 0;
111458c9b817SLisandro Dalcin   snes->vwork             = 0;
1115758f92a0SBarry Smith   snes->conv_hist_len     = 0;
1116758f92a0SBarry Smith   snes->conv_hist_max     = 0;
1117758f92a0SBarry Smith   snes->conv_hist         = PETSC_NULL;
1118758f92a0SBarry Smith   snes->conv_hist_its     = PETSC_NULL;
1119758f92a0SBarry Smith   snes->conv_hist_reset   = PETSC_TRUE;
1120184914b5SBarry Smith   snes->reason            = SNES_CONVERGED_ITERATING;
11219b94acceSBarry Smith 
1122ea630c6eSPeter Brune   /* initialize the line search options */
1123ea630c6eSPeter Brune   snes->ls_type           = SNES_LS_BASIC;
1124af60355fSPeter Brune   snes->ls_its            = 1;
1125ea630c6eSPeter Brune   snes->damping           = 1.0;
1126ea630c6eSPeter Brune   snes->maxstep           = 1e8;
1127ea630c6eSPeter Brune   snes->steptol           = 1e-12;
1128ea630c6eSPeter Brune   snes->ls_alpha          = 1e-4;
1129ea630c6eSPeter Brune   snes->ls_monitor        = PETSC_NULL;
1130ea630c6eSPeter Brune 
1131ea630c6eSPeter Brune   snes->ops->linesearch   = PETSC_NULL;
1132ea630c6eSPeter Brune   snes->precheck          = PETSC_NULL;
1133ea630c6eSPeter Brune   snes->ops->precheckstep = PETSC_NULL;
1134ea630c6eSPeter Brune   snes->postcheck         = PETSC_NULL;
1135ea630c6eSPeter Brune   snes->ops->postcheckstep= PETSC_NULL;
1136ea630c6eSPeter Brune 
11373d4c4710SBarry Smith   snes->numLinearSolveFailures = 0;
11383d4c4710SBarry Smith   snes->maxLinearSolveFailures = 1;
11393d4c4710SBarry Smith 
11409b94acceSBarry Smith   /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
114138f2d2fdSLisandro Dalcin   ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr);
11429b94acceSBarry Smith   snes->kspconvctx  = (void*)kctx;
11439b94acceSBarry Smith   kctx->version     = 2;
11449b94acceSBarry Smith   kctx->rtol_0      = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
11459b94acceSBarry Smith                              this was too large for some test cases */
114675567043SBarry Smith   kctx->rtol_last   = 0.0;
11479b94acceSBarry Smith   kctx->rtol_max    = .9;
11489b94acceSBarry Smith   kctx->gamma       = 1.0;
114962d1f40fSBarry Smith   kctx->alpha       = .5*(1.0 + PetscSqrtReal(5.0));
115071f87433Sdalcinl   kctx->alpha2      = kctx->alpha;
11519b94acceSBarry Smith   kctx->threshold   = .1;
115275567043SBarry Smith   kctx->lresid_last = 0.0;
115375567043SBarry Smith   kctx->norm_last   = 0.0;
11549b94acceSBarry Smith 
11559b94acceSBarry Smith   *outsnes = snes;
11563a40ed3dSBarry Smith   PetscFunctionReturn(0);
11579b94acceSBarry Smith }
11589b94acceSBarry Smith 
11594a2ae208SSatish Balay #undef __FUNCT__
11604a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction"
11619b94acceSBarry Smith /*@C
11629b94acceSBarry Smith    SNESSetFunction - Sets the function evaluation routine and function
11639b94acceSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
11649b94acceSBarry Smith    equations.
11659b94acceSBarry Smith 
11663f9fe445SBarry Smith    Logically Collective on SNES
1167fee21e36SBarry Smith 
1168c7afd0dbSLois Curfman McInnes    Input Parameters:
1169c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1170c7afd0dbSLois Curfman McInnes .  r - vector to store function value
1171de044059SHong Zhang .  func - function evaluation routine
1172c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
1173c7afd0dbSLois Curfman McInnes          function evaluation routine (may be PETSC_NULL)
11749b94acceSBarry Smith 
1175c7afd0dbSLois Curfman McInnes    Calling sequence of func:
11768d76a1e5SLois Curfman McInnes $    func (SNES snes,Vec x,Vec f,void *ctx);
1177c7afd0dbSLois Curfman McInnes 
1178313e4042SLois Curfman McInnes .  f - function vector
1179c7afd0dbSLois Curfman McInnes -  ctx - optional user-defined function context
11809b94acceSBarry Smith 
11819b94acceSBarry Smith    Notes:
11829b94acceSBarry Smith    The Newton-like methods typically solve linear systems of the form
11839b94acceSBarry Smith $      f'(x) x = -f(x),
1184c7afd0dbSLois Curfman McInnes    where f'(x) denotes the Jacobian matrix and f(x) is the function.
11859b94acceSBarry Smith 
118636851e7fSLois Curfman McInnes    Level: beginner
118736851e7fSLois Curfman McInnes 
11889b94acceSBarry Smith .keywords: SNES, nonlinear, set, function
11899b94acceSBarry Smith 
11908b0a5094SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard()
11919b94acceSBarry Smith @*/
11927087cfbeSBarry Smith PetscErrorCode  SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx)
11939b94acceSBarry Smith {
119485385478SLisandro Dalcin   PetscErrorCode ierr;
11953a40ed3dSBarry Smith   PetscFunctionBegin;
11960700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1197d2a683ecSLisandro Dalcin   if (r) {
1198d2a683ecSLisandro Dalcin     PetscValidHeaderSpecific(r,VEC_CLASSID,2);
1199d2a683ecSLisandro Dalcin     PetscCheckSameComm(snes,1,r,2);
120085385478SLisandro Dalcin     ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr);
12016bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
120285385478SLisandro Dalcin     snes->vec_func = r;
1203d2a683ecSLisandro Dalcin   } else if (!snes->vec_func && snes->dm) {
1204d2a683ecSLisandro Dalcin     ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr);
1205d2a683ecSLisandro Dalcin   }
1206d2a683ecSLisandro Dalcin   if (func) snes->ops->computefunction = func;
1207d2a683ecSLisandro Dalcin   if (ctx)  snes->funP                 = ctx;
12083a40ed3dSBarry Smith   PetscFunctionReturn(0);
12099b94acceSBarry Smith }
12109b94acceSBarry Smith 
1211646217ecSPeter Brune 
1212646217ecSPeter Brune #undef __FUNCT__
1213646217ecSPeter Brune #define __FUNCT__ "SNESSetGS"
1214c79ef259SPeter Brune /*@C
1215c79ef259SPeter Brune    SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for
1216c79ef259SPeter Brune    use with composed nonlinear solvers.
1217c79ef259SPeter Brune 
1218c79ef259SPeter Brune    Input Parameters:
1219c79ef259SPeter Brune +  snes   - the SNES context
1220c79ef259SPeter Brune .  gsfunc - function evaluation routine
1221c79ef259SPeter Brune -  ctx    - [optional] user-defined context for private data for the
1222c79ef259SPeter Brune             smoother evaluation routine (may be PETSC_NULL)
1223c79ef259SPeter Brune 
1224c79ef259SPeter Brune    Calling sequence of func:
1225c79ef259SPeter Brune $    func (SNES snes,Vec x,Vec b,void *ctx);
1226c79ef259SPeter Brune 
1227c79ef259SPeter Brune +  X   - solution vector
1228c79ef259SPeter Brune .  B   - RHS vector
1229c79ef259SPeter Brune -  ctx - optional user-defined function context
1230c79ef259SPeter Brune 
1231c79ef259SPeter Brune    Notes:
1232c79ef259SPeter Brune    The GS routines are used by the composed nonlinear solver to generate
1233c79ef259SPeter Brune     a problem appropriate update to the solution, particularly FAS.
1234c79ef259SPeter Brune 
1235c79ef259SPeter Brune    Level: beginner
1236c79ef259SPeter Brune 
1237c79ef259SPeter Brune .keywords: SNES, nonlinear, set, function
1238c79ef259SPeter Brune 
1239c79ef259SPeter Brune .seealso: SNESGetFunction(), SNESComputeGS()
1240c79ef259SPeter Brune @*/
1241646217ecSPeter Brune PetscErrorCode SNESSetGS(SNES snes, PetscErrorCode (*gsfunc)(SNES,Vec,Vec,void *), void * ctx) {
1242646217ecSPeter Brune   PetscFunctionBegin;
1243646217ecSPeter Brune   if (gsfunc) snes->ops->computegs = gsfunc;
1244646217ecSPeter Brune   if (ctx) snes->gsP = ctx;
1245646217ecSPeter Brune   PetscFunctionReturn(0);
1246646217ecSPeter Brune }
1247646217ecSPeter Brune 
1248d25893d9SBarry Smith #undef __FUNCT__
12498b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction"
12508b0a5094SBarry Smith PetscErrorCode  SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx)
12518b0a5094SBarry Smith {
12528b0a5094SBarry Smith   PetscErrorCode ierr;
12538b0a5094SBarry Smith   PetscFunctionBegin;
12548b0a5094SBarry Smith   /*  A(x)*x - b(x) */
12558b0a5094SBarry Smith   ierr = (*snes->ops->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,snes->jacP);CHKERRQ(ierr);
12568b0a5094SBarry Smith   ierr = (*snes->ops->computepfunction)(snes,x,f,snes->funP);CHKERRQ(ierr);
12578b0a5094SBarry Smith   ierr = VecView(x,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr);
12588b0a5094SBarry Smith   ierr = VecView(f,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr);
12598b0a5094SBarry Smith   ierr = VecScale(f,-1.0);CHKERRQ(ierr);
12608b0a5094SBarry Smith   ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr);
12618b0a5094SBarry Smith   PetscFunctionReturn(0);
12628b0a5094SBarry Smith }
12638b0a5094SBarry Smith 
12648b0a5094SBarry Smith #undef __FUNCT__
12658b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian"
12668b0a5094SBarry Smith PetscErrorCode  SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx)
12678b0a5094SBarry Smith {
12688b0a5094SBarry Smith   PetscFunctionBegin;
12698b0a5094SBarry Smith   *flag = snes->matstruct;
12708b0a5094SBarry Smith   PetscFunctionReturn(0);
12718b0a5094SBarry Smith }
12728b0a5094SBarry Smith 
12738b0a5094SBarry Smith #undef __FUNCT__
12748b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard"
12758b0a5094SBarry Smith /*@C
12768b0a5094SBarry Smith    SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration
12778b0a5094SBarry Smith 
12788b0a5094SBarry Smith    Logically Collective on SNES
12798b0a5094SBarry Smith 
12808b0a5094SBarry Smith    Input Parameters:
12818b0a5094SBarry Smith +  snes - the SNES context
12828b0a5094SBarry Smith .  r - vector to store function value
12838b0a5094SBarry Smith .  func - function evaluation routine
12848b0a5094SBarry 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)
12858b0a5094SBarry Smith .  mat - matrix to store A
12868b0a5094SBarry Smith .  mfunc  - function to compute matrix value
12878b0a5094SBarry Smith -  ctx - [optional] user-defined context for private data for the
12888b0a5094SBarry Smith          function evaluation routine (may be PETSC_NULL)
12898b0a5094SBarry Smith 
12908b0a5094SBarry Smith    Calling sequence of func:
12918b0a5094SBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
12928b0a5094SBarry Smith 
12938b0a5094SBarry Smith +  f - function vector
12948b0a5094SBarry Smith -  ctx - optional user-defined function context
12958b0a5094SBarry Smith 
12968b0a5094SBarry Smith    Calling sequence of mfunc:
12978b0a5094SBarry Smith $     mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx);
12988b0a5094SBarry Smith 
12998b0a5094SBarry Smith +  x - input vector
13008b0a5094SBarry 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(),
13018b0a5094SBarry Smith           normally just pass mat in this location
13028b0a5094SBarry Smith .  mat - form A(x) matrix
13038b0a5094SBarry Smith .  flag - flag indicating information about the preconditioner matrix
13048b0a5094SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
13058b0a5094SBarry Smith -  ctx - [optional] user-defined Jacobian context
13068b0a5094SBarry Smith 
13078b0a5094SBarry Smith    Notes:
13088b0a5094SBarry Smith     One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both
13098b0a5094SBarry Smith 
13108b0a5094SBarry 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}
13118b0a5094SBarry 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.
13128b0a5094SBarry Smith 
13138b0a5094SBarry Smith      Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner.
13148b0a5094SBarry Smith 
13158b0a5094SBarry Smith    We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used.
13168b0a5094SBarry Smith 
13178b0a5094SBarry 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
13188b0a5094SBarry 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
13198b0a5094SBarry Smith    different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-).
13208b0a5094SBarry Smith 
13218b0a5094SBarry Smith    Level: beginner
13228b0a5094SBarry Smith 
13238b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function
13248b0a5094SBarry Smith 
13258b0a5094SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard()
13268b0a5094SBarry Smith @*/
13278b0a5094SBarry 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)
13288b0a5094SBarry Smith {
13298b0a5094SBarry Smith   PetscErrorCode ierr;
13308b0a5094SBarry Smith   PetscFunctionBegin;
13318b0a5094SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
13328b0a5094SBarry Smith   snes->ops->computepfunction = func;
13338b0a5094SBarry Smith   snes->ops->computepjacobian = mfunc;
13348b0a5094SBarry Smith   ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr);
13358b0a5094SBarry Smith   ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr);
13368b0a5094SBarry Smith   PetscFunctionReturn(0);
13378b0a5094SBarry Smith }
13388b0a5094SBarry Smith 
13398b0a5094SBarry Smith #undef __FUNCT__
1340d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess"
1341d25893d9SBarry Smith /*@C
1342d25893d9SBarry Smith    SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem
1343d25893d9SBarry Smith 
1344d25893d9SBarry Smith    Logically Collective on SNES
1345d25893d9SBarry Smith 
1346d25893d9SBarry Smith    Input Parameters:
1347d25893d9SBarry Smith +  snes - the SNES context
1348d25893d9SBarry Smith .  func - function evaluation routine
1349d25893d9SBarry Smith -  ctx - [optional] user-defined context for private data for the
1350d25893d9SBarry Smith          function evaluation routine (may be PETSC_NULL)
1351d25893d9SBarry Smith 
1352d25893d9SBarry Smith    Calling sequence of func:
1353d25893d9SBarry Smith $    func (SNES snes,Vec x,void *ctx);
1354d25893d9SBarry Smith 
1355d25893d9SBarry Smith .  f - function vector
1356d25893d9SBarry Smith -  ctx - optional user-defined function context
1357d25893d9SBarry Smith 
1358d25893d9SBarry Smith    Level: intermediate
1359d25893d9SBarry Smith 
1360d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function
1361d25893d9SBarry Smith 
1362d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
1363d25893d9SBarry Smith @*/
1364d25893d9SBarry Smith PetscErrorCode  SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx)
1365d25893d9SBarry Smith {
1366d25893d9SBarry Smith   PetscFunctionBegin;
1367d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1368d25893d9SBarry Smith   if (func) snes->ops->computeinitialguess = func;
1369d25893d9SBarry Smith   if (ctx)  snes->initialguessP            = ctx;
1370d25893d9SBarry Smith   PetscFunctionReturn(0);
1371d25893d9SBarry Smith }
1372d25893d9SBarry Smith 
13733ab0aad5SBarry Smith /* --------------------------------------------------------------- */
13743ab0aad5SBarry Smith #undef __FUNCT__
13751096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs"
13761096aae1SMatthew Knepley /*@C
13771096aae1SMatthew Knepley    SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
13781096aae1SMatthew Knepley    it assumes a zero right hand side.
13791096aae1SMatthew Knepley 
13803f9fe445SBarry Smith    Logically Collective on SNES
13811096aae1SMatthew Knepley 
13821096aae1SMatthew Knepley    Input Parameter:
13831096aae1SMatthew Knepley .  snes - the SNES context
13841096aae1SMatthew Knepley 
13851096aae1SMatthew Knepley    Output Parameter:
1386bc08b0f1SBarry Smith .  rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null
13871096aae1SMatthew Knepley 
13881096aae1SMatthew Knepley    Level: intermediate
13891096aae1SMatthew Knepley 
13901096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side
13911096aae1SMatthew Knepley 
139285385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
13931096aae1SMatthew Knepley @*/
13947087cfbeSBarry Smith PetscErrorCode  SNESGetRhs(SNES snes,Vec *rhs)
13951096aae1SMatthew Knepley {
13961096aae1SMatthew Knepley   PetscFunctionBegin;
13970700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
13981096aae1SMatthew Knepley   PetscValidPointer(rhs,2);
139985385478SLisandro Dalcin   *rhs = snes->vec_rhs;
14001096aae1SMatthew Knepley   PetscFunctionReturn(0);
14011096aae1SMatthew Knepley }
14021096aae1SMatthew Knepley 
14031096aae1SMatthew Knepley #undef __FUNCT__
14044a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction"
14059b94acceSBarry Smith /*@
140636851e7fSLois Curfman McInnes    SNESComputeFunction - Calls the function that has been set with
14079b94acceSBarry Smith                          SNESSetFunction().
14089b94acceSBarry Smith 
1409c7afd0dbSLois Curfman McInnes    Collective on SNES
1410c7afd0dbSLois Curfman McInnes 
14119b94acceSBarry Smith    Input Parameters:
1412c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1413c7afd0dbSLois Curfman McInnes -  x - input vector
14149b94acceSBarry Smith 
14159b94acceSBarry Smith    Output Parameter:
14163638b69dSLois Curfman McInnes .  y - function vector, as set by SNESSetFunction()
14179b94acceSBarry Smith 
14181bffabb2SLois Curfman McInnes    Notes:
141936851e7fSLois Curfman McInnes    SNESComputeFunction() is typically used within nonlinear solvers
142036851e7fSLois Curfman McInnes    implementations, so most users would not generally call this routine
142136851e7fSLois Curfman McInnes    themselves.
142236851e7fSLois Curfman McInnes 
142336851e7fSLois Curfman McInnes    Level: developer
142436851e7fSLois Curfman McInnes 
14259b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function
14269b94acceSBarry Smith 
1427a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction()
14289b94acceSBarry Smith @*/
14297087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction(SNES snes,Vec x,Vec y)
14309b94acceSBarry Smith {
1431dfbe8321SBarry Smith   PetscErrorCode ierr;
14329b94acceSBarry Smith 
14333a40ed3dSBarry Smith   PetscFunctionBegin;
14340700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
14350700a824SBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
14360700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
1437c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,x,2);
1438c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,3);
1439184914b5SBarry Smith 
1440d5ba7fb7SMatthew Knepley   ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
1441e7788613SBarry Smith   if (snes->ops->computefunction) {
1442d64ed03dSBarry Smith     PetscStackPush("SNES user function");
144339d508bbSBarry Smith     ierr = (*snes->ops->computefunction)(snes,x,y,snes->funP);CHKERRQ(ierr);
1444d64ed03dSBarry Smith     PetscStackPop;
144573250ac0SBarry Smith   } else if (snes->dm) {
1446644e2e5bSBarry Smith     ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr);
1447c90fad12SPeter Brune   } else if (snes->vec_rhs) {
1448c90fad12SPeter Brune     ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr);
1449644e2e5bSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve().");
145085385478SLisandro Dalcin   if (snes->vec_rhs) {
145185385478SLisandro Dalcin     ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr);
14523ab0aad5SBarry Smith   }
1453ae3c334cSLois Curfman McInnes   snes->nfuncs++;
1454d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
14553a40ed3dSBarry Smith   PetscFunctionReturn(0);
14569b94acceSBarry Smith }
14579b94acceSBarry Smith 
14584a2ae208SSatish Balay #undef __FUNCT__
1459646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS"
1460c79ef259SPeter Brune /*@
1461c79ef259SPeter Brune    SNESComputeGS - Calls the Gauss-Seidel function that has been set with
1462c79ef259SPeter Brune                    SNESSetGS().
1463c79ef259SPeter Brune 
1464c79ef259SPeter Brune    Collective on SNES
1465c79ef259SPeter Brune 
1466c79ef259SPeter Brune    Input Parameters:
1467c79ef259SPeter Brune +  snes - the SNES context
1468c79ef259SPeter Brune .  x - input vector
1469c79ef259SPeter Brune -  b - rhs vector
1470c79ef259SPeter Brune 
1471c79ef259SPeter Brune    Output Parameter:
1472c79ef259SPeter Brune .  x - new solution vector
1473c79ef259SPeter Brune 
1474c79ef259SPeter Brune    Notes:
1475c79ef259SPeter Brune    SNESComputeGS() is typically used within composed nonlinear solver
1476c79ef259SPeter Brune    implementations, so most users would not generally call this routine
1477c79ef259SPeter Brune    themselves.
1478c79ef259SPeter Brune 
1479c79ef259SPeter Brune    Level: developer
1480c79ef259SPeter Brune 
1481c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function
1482c79ef259SPeter Brune 
1483c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction()
1484c79ef259SPeter Brune @*/
1485646217ecSPeter Brune PetscErrorCode  SNESComputeGS(SNES snes,Vec b,Vec x)
1486646217ecSPeter Brune {
1487646217ecSPeter Brune   PetscErrorCode ierr;
1488646217ecSPeter Brune 
1489646217ecSPeter Brune   PetscFunctionBegin;
1490646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1491646217ecSPeter Brune   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
1492646217ecSPeter Brune   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3);
1493646217ecSPeter Brune   PetscCheckSameComm(snes,1,x,2);
1494646217ecSPeter Brune   if(b) PetscCheckSameComm(snes,1,b,3);
1495646217ecSPeter Brune   if (snes->ops->computegs) {
1496646217ecSPeter Brune     PetscStackPush("SNES user GS");
1497646217ecSPeter Brune     ierr = (*snes->ops->computegs)(snes,x,b,snes->gsP);CHKERRQ(ierr);
1498646217ecSPeter Brune     PetscStackPop;
1499646217ecSPeter Brune   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve().");
1500646217ecSPeter Brune   PetscFunctionReturn(0);
1501646217ecSPeter Brune }
1502646217ecSPeter Brune 
1503646217ecSPeter Brune 
1504646217ecSPeter Brune #undef __FUNCT__
15054a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian"
150662fef451SLois Curfman McInnes /*@
150762fef451SLois Curfman McInnes    SNESComputeJacobian - Computes the Jacobian matrix that has been
150862fef451SLois Curfman McInnes    set with SNESSetJacobian().
150962fef451SLois Curfman McInnes 
1510c7afd0dbSLois Curfman McInnes    Collective on SNES and Mat
1511c7afd0dbSLois Curfman McInnes 
151262fef451SLois Curfman McInnes    Input Parameters:
1513c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1514c7afd0dbSLois Curfman McInnes -  x - input vector
151562fef451SLois Curfman McInnes 
151662fef451SLois Curfman McInnes    Output Parameters:
1517c7afd0dbSLois Curfman McInnes +  A - Jacobian matrix
151862fef451SLois Curfman McInnes .  B - optional preconditioning matrix
15192b668275SBarry Smith -  flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER)
1520fee21e36SBarry Smith 
1521e35cf81dSBarry Smith   Options Database Keys:
1522e35cf81dSBarry Smith +    -snes_lag_preconditioner <lag>
1523693365a8SJed Brown .    -snes_lag_jacobian <lag>
1524693365a8SJed Brown .    -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences
1525693365a8SJed Brown .    -snes_compare_explicit_draw  - Compare the computed Jacobian to the finite difference Jacobian and draw the result
1526693365a8SJed Brown .    -snes_compare_explicit_contour  - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result
15274c30e9fbSJed Brown .    -snes_compare_operator  - Make the comparison options above use the operator instead of the preconditioning matrix
1528c01495d3SJed Brown .    -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference
1529c01495d3SJed Brown .    -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences
1530c01495d3SJed Brown .    -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold
1531c01495d3SJed Brown .    -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
1532c01495d3SJed Brown .    -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
15334c30e9fbSJed Brown .    -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences
1534c01495d3SJed Brown -    -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences
1535c01495d3SJed Brown 
1536e35cf81dSBarry Smith 
153762fef451SLois Curfman McInnes    Notes:
153862fef451SLois Curfman McInnes    Most users should not need to explicitly call this routine, as it
153962fef451SLois Curfman McInnes    is used internally within the nonlinear solvers.
154062fef451SLois Curfman McInnes 
154194b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the
1542dc5a77f8SLois Curfman McInnes    flag parameter.
154362fef451SLois Curfman McInnes 
154436851e7fSLois Curfman McInnes    Level: developer
154536851e7fSLois Curfman McInnes 
154662fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix
154762fef451SLois Curfman McInnes 
1548e35cf81dSBarry Smith .seealso:  SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian()
154962fef451SLois Curfman McInnes @*/
15507087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg)
15519b94acceSBarry Smith {
1552dfbe8321SBarry Smith   PetscErrorCode ierr;
1553ace3abfcSBarry Smith   PetscBool      flag;
15543a40ed3dSBarry Smith 
15553a40ed3dSBarry Smith   PetscFunctionBegin;
15560700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
15570700a824SBarry Smith   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
15584482741eSBarry Smith   PetscValidPointer(flg,5);
1559c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,X,2);
1560e7788613SBarry Smith   if (!snes->ops->computejacobian) PetscFunctionReturn(0);
1561ebd3b9afSBarry Smith 
1562ebd3b9afSBarry Smith   /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */
1563ebd3b9afSBarry Smith 
1564fe3ffe1eSBarry Smith   if (snes->lagjacobian == -2) {
1565fe3ffe1eSBarry Smith     snes->lagjacobian = -1;
1566fe3ffe1eSBarry Smith     ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr);
1567fe3ffe1eSBarry Smith   } else if (snes->lagjacobian == -1) {
1568e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
1569e35cf81dSBarry Smith     ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr);
1570ebd3b9afSBarry Smith     ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
1571ebd3b9afSBarry Smith     if (flag) {
1572ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1573ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1574ebd3b9afSBarry Smith     }
1575e35cf81dSBarry Smith     PetscFunctionReturn(0);
1576e35cf81dSBarry Smith   } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) {
1577e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
1578e35cf81dSBarry Smith     ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr);
1579ebd3b9afSBarry Smith     ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
1580ebd3b9afSBarry Smith     if (flag) {
1581ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1582ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1583ebd3b9afSBarry Smith     }
1584e35cf81dSBarry Smith     PetscFunctionReturn(0);
1585e35cf81dSBarry Smith   }
1586e35cf81dSBarry Smith 
1587c4fc05e7SBarry Smith   *flg = DIFFERENT_NONZERO_PATTERN;
1588e35cf81dSBarry Smith   ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
1589d64ed03dSBarry Smith   PetscStackPush("SNES user Jacobian function");
1590e7788613SBarry Smith   ierr = (*snes->ops->computejacobian)(snes,X,A,B,flg,snes->jacP);CHKERRQ(ierr);
1591d64ed03dSBarry Smith   PetscStackPop;
1592d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
1593a8054027SBarry Smith 
15943b4f5425SBarry Smith   if (snes->lagpreconditioner == -2) {
15953b4f5425SBarry Smith     ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr);
15963b4f5425SBarry Smith     snes->lagpreconditioner = -1;
15973b4f5425SBarry Smith   } else if (snes->lagpreconditioner == -1) {
1598a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
1599a8054027SBarry Smith     ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr);
1600a8054027SBarry Smith   } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) {
1601a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
1602a8054027SBarry Smith     ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr);
1603a8054027SBarry Smith   }
1604a8054027SBarry Smith 
16056d84be18SBarry Smith   /* make sure user returned a correct Jacobian and preconditioner */
16060700a824SBarry Smith   /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3);
16070700a824SBarry Smith     PetscValidHeaderSpecific(*B,MAT_CLASSID,4);   */
1608693365a8SJed Brown   {
1609693365a8SJed Brown     PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE;
1610693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr);
1611693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr);
1612693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr);
1613693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr);
1614693365a8SJed Brown     if (flag || flag_draw || flag_contour) {
1615693365a8SJed Brown       Mat Bexp_mine = PETSC_NULL,Bexp,FDexp;
1616693365a8SJed Brown       MatStructure mstruct;
1617693365a8SJed Brown       PetscViewer vdraw,vstdout;
16186b3a5b13SJed Brown       PetscBool flg;
1619693365a8SJed Brown       if (flag_operator) {
1620693365a8SJed Brown         ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr);
1621693365a8SJed Brown         Bexp = Bexp_mine;
1622693365a8SJed Brown       } else {
1623693365a8SJed Brown         /* See if the preconditioning matrix can be viewed and added directly */
1624693365a8SJed Brown         ierr = PetscTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr);
1625693365a8SJed Brown         if (flg) Bexp = *B;
1626693365a8SJed Brown         else {
1627693365a8SJed Brown           /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */
1628693365a8SJed Brown           ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr);
1629693365a8SJed Brown           Bexp = Bexp_mine;
1630693365a8SJed Brown         }
1631693365a8SJed Brown       }
1632693365a8SJed Brown       ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr);
1633693365a8SJed Brown       ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr);
1634693365a8SJed Brown       ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr);
1635693365a8SJed Brown       if (flag_draw || flag_contour) {
1636693365a8SJed Brown         ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
1637693365a8SJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
1638693365a8SJed Brown       } else vdraw = PETSC_NULL;
1639693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr);
1640693365a8SJed Brown       if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);}
1641693365a8SJed Brown       if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);}
1642693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr);
1643693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
1644693365a8SJed Brown       if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);}
1645693365a8SJed Brown       ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
1646693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr);
1647693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
1648693365a8SJed Brown       if (vdraw) {              /* Always use contour for the difference */
1649693365a8SJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
1650693365a8SJed Brown         ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);
1651693365a8SJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
1652693365a8SJed Brown       }
1653693365a8SJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
1654693365a8SJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
1655693365a8SJed Brown       ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr);
1656693365a8SJed Brown       ierr = MatDestroy(&FDexp);CHKERRQ(ierr);
1657693365a8SJed Brown     }
1658693365a8SJed Brown   }
16594c30e9fbSJed Brown   {
16606719d8e4SJed Brown     PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE;
16616719d8e4SJed Brown     PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON;
16624c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr);
16636719d8e4SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr);
16644c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr);
16654c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr);
16666719d8e4SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr);
16676719d8e4SJed Brown     ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr);
16686719d8e4SJed Brown     ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr);
16696719d8e4SJed Brown     if (flag || flag_display || flag_draw || flag_contour || flag_threshold) {
16704c30e9fbSJed Brown       Mat Bfd;
16714c30e9fbSJed Brown       MatStructure mstruct;
16724c30e9fbSJed Brown       PetscViewer vdraw,vstdout;
16734c30e9fbSJed Brown       ISColoring iscoloring;
16744c30e9fbSJed Brown       MatFDColoring matfdcoloring;
16754c30e9fbSJed Brown       PetscErrorCode (*func)(SNES,Vec,Vec,void*);
16764c30e9fbSJed Brown       void *funcctx;
16776719d8e4SJed Brown       PetscReal norm1,norm2,normmax;
16784c30e9fbSJed Brown 
16794c30e9fbSJed Brown       ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr);
16804c30e9fbSJed Brown       ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr);
16814c30e9fbSJed Brown       ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr);
16824c30e9fbSJed Brown       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
16834c30e9fbSJed Brown 
16844c30e9fbSJed Brown       /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */
16854c30e9fbSJed Brown       ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr);
16864c30e9fbSJed Brown       ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr);
16874c30e9fbSJed Brown       ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr);
16884c30e9fbSJed Brown       ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr);
16894c30e9fbSJed Brown       ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr);
16904c30e9fbSJed Brown       ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr);
16914c30e9fbSJed Brown       ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr);
16924c30e9fbSJed Brown 
16934c30e9fbSJed Brown       ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr);
16944c30e9fbSJed Brown       if (flag_draw || flag_contour) {
16954c30e9fbSJed Brown         ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
16964c30e9fbSJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
16974c30e9fbSJed Brown       } else vdraw = PETSC_NULL;
16984c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr);
16996719d8e4SJed Brown       if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);}
17004c30e9fbSJed Brown       if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);}
17014c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr);
17026719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
17034c30e9fbSJed Brown       if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);}
17044c30e9fbSJed Brown       ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
17054c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr);
17066719d8e4SJed Brown       ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr);
17074c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr);
17086719d8e4SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr);
17096719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
17104c30e9fbSJed Brown       if (vdraw) {              /* Always use contour for the difference */
17114c30e9fbSJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
17124c30e9fbSJed Brown         ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);
17134c30e9fbSJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
17144c30e9fbSJed Brown       }
17154c30e9fbSJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
17166719d8e4SJed Brown 
17176719d8e4SJed Brown       if (flag_threshold) {
17186719d8e4SJed Brown         PetscInt bs,rstart,rend,i;
17196719d8e4SJed Brown         ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr);
17206719d8e4SJed Brown         ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr);
17216719d8e4SJed Brown         for (i=rstart; i<rend; i++) {
17226719d8e4SJed Brown           const PetscScalar *ba,*ca;
17236719d8e4SJed Brown           const PetscInt *bj,*cj;
17246719d8e4SJed Brown           PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1;
17256719d8e4SJed Brown           PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0;
17266719d8e4SJed Brown           ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr);
17276719d8e4SJed Brown           ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
17286719d8e4SJed Brown           if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold");
17296719d8e4SJed Brown           for (j=0; j<bn; j++) {
17306719d8e4SJed Brown             PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
17316719d8e4SJed Brown             if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) {
17326719d8e4SJed Brown               maxentrycol = bj[j];
17336719d8e4SJed Brown               maxentry = PetscRealPart(ba[j]);
17346719d8e4SJed Brown             }
17356719d8e4SJed Brown             if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) {
17366719d8e4SJed Brown               maxdiffcol = bj[j];
17376719d8e4SJed Brown               maxdiff = PetscRealPart(ca[j]);
17386719d8e4SJed Brown             }
17396719d8e4SJed Brown             if (rdiff > maxrdiff) {
17406719d8e4SJed Brown               maxrdiffcol = bj[j];
17416719d8e4SJed Brown               maxrdiff = rdiff;
17426719d8e4SJed Brown             }
17436719d8e4SJed Brown           }
17446719d8e4SJed Brown           if (maxrdiff > 1) {
17456719d8e4SJed 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);
17466719d8e4SJed Brown             for (j=0; j<bn; j++) {
17476719d8e4SJed Brown               PetscReal rdiff;
17486719d8e4SJed Brown               rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
17496719d8e4SJed Brown               if (rdiff > 1) {
17506719d8e4SJed Brown                 ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr);
17516719d8e4SJed Brown               }
17526719d8e4SJed Brown             }
17536719d8e4SJed Brown             ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr);
17546719d8e4SJed Brown           }
17556719d8e4SJed Brown           ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr);
17566719d8e4SJed Brown           ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
17576719d8e4SJed Brown         }
17586719d8e4SJed Brown       }
17594c30e9fbSJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
17604c30e9fbSJed Brown       ierr = MatDestroy(&Bfd);CHKERRQ(ierr);
17614c30e9fbSJed Brown     }
17624c30e9fbSJed Brown   }
17633a40ed3dSBarry Smith   PetscFunctionReturn(0);
17649b94acceSBarry Smith }
17659b94acceSBarry Smith 
17664a2ae208SSatish Balay #undef __FUNCT__
17674a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian"
17689b94acceSBarry Smith /*@C
17699b94acceSBarry Smith    SNESSetJacobian - Sets the function to compute Jacobian as well as the
1770044dda88SLois Curfman McInnes    location to store the matrix.
17719b94acceSBarry Smith 
17723f9fe445SBarry Smith    Logically Collective on SNES and Mat
1773c7afd0dbSLois Curfman McInnes 
17749b94acceSBarry Smith    Input Parameters:
1775c7afd0dbSLois Curfman McInnes +  snes - the SNES context
17769b94acceSBarry Smith .  A - Jacobian matrix
17779b94acceSBarry Smith .  B - preconditioner matrix (usually same as the Jacobian)
1778efd51863SBarry Smith .  func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value)
1779c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
1780efd51863SBarry Smith          Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value)
17819b94acceSBarry Smith 
17829b94acceSBarry Smith    Calling sequence of func:
17838d76a1e5SLois Curfman McInnes $     func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx);
17849b94acceSBarry Smith 
1785c7afd0dbSLois Curfman McInnes +  x - input vector
17869b94acceSBarry Smith .  A - Jacobian matrix
17879b94acceSBarry Smith .  B - preconditioner matrix, usually the same as A
1788ac21db08SLois Curfman McInnes .  flag - flag indicating information about the preconditioner matrix
17892b668275SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
1790c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined Jacobian context
17919b94acceSBarry Smith 
17929b94acceSBarry Smith    Notes:
179394b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the flag
17942cd2dfdcSLois Curfman McInnes    output parameter in the routine func().  Be sure to read this information!
1795ac21db08SLois Curfman McInnes 
1796ac21db08SLois Curfman McInnes    The routine func() takes Mat * as the matrix arguments rather than Mat.
17979b94acceSBarry Smith    This allows the Jacobian evaluation routine to replace A and/or B with a
17989b94acceSBarry Smith    completely new new matrix structure (not just different matrix elements)
17999b94acceSBarry Smith    when appropriate, for instance, if the nonzero structure is changing
18009b94acceSBarry Smith    throughout the global iterations.
18019b94acceSBarry Smith 
180216913363SBarry Smith    If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on
180316913363SBarry Smith    each matrix.
180416913363SBarry Smith 
1805a8a26c1eSJed Brown    If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument
1806a8a26c1eSJed Brown    must be a MatFDColoring.
1807a8a26c1eSJed Brown 
1808c3cc8fd1SJed Brown    Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian.  One common
1809c3cc8fd1SJed Brown    example is to use the "Picard linearization" which only differentiates through the highest order parts of each term.
1810c3cc8fd1SJed Brown 
181136851e7fSLois Curfman McInnes    Level: beginner
181236851e7fSLois Curfman McInnes 
18139b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix
18149b94acceSBarry Smith 
18153ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure
18169b94acceSBarry Smith @*/
18177087cfbeSBarry Smith PetscErrorCode  SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
18189b94acceSBarry Smith {
1819dfbe8321SBarry Smith   PetscErrorCode ierr;
18203a7fca6bSBarry Smith 
18213a40ed3dSBarry Smith   PetscFunctionBegin;
18220700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
18230700a824SBarry Smith   if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2);
18240700a824SBarry Smith   if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3);
1825c9780b6fSBarry Smith   if (A) PetscCheckSameComm(snes,1,A,2);
182606975374SJed Brown   if (B) PetscCheckSameComm(snes,1,B,3);
1827e7788613SBarry Smith   if (func) snes->ops->computejacobian = func;
18283a7fca6bSBarry Smith   if (ctx)  snes->jacP                 = ctx;
18293a7fca6bSBarry Smith   if (A) {
18307dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
18316bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
18329b94acceSBarry Smith     snes->jacobian = A;
18333a7fca6bSBarry Smith   }
18343a7fca6bSBarry Smith   if (B) {
18357dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr);
18366bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
18379b94acceSBarry Smith     snes->jacobian_pre = B;
18383a7fca6bSBarry Smith   }
18393a40ed3dSBarry Smith   PetscFunctionReturn(0);
18409b94acceSBarry Smith }
184162fef451SLois Curfman McInnes 
18424a2ae208SSatish Balay #undef __FUNCT__
18434a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian"
1844c2aafc4cSSatish Balay /*@C
1845b4fd4287SBarry Smith    SNESGetJacobian - Returns the Jacobian matrix and optionally the user
1846b4fd4287SBarry Smith    provided context for evaluating the Jacobian.
1847b4fd4287SBarry Smith 
1848c7afd0dbSLois Curfman McInnes    Not Collective, but Mat object will be parallel if SNES object is
1849c7afd0dbSLois Curfman McInnes 
1850b4fd4287SBarry Smith    Input Parameter:
1851b4fd4287SBarry Smith .  snes - the nonlinear solver context
1852b4fd4287SBarry Smith 
1853b4fd4287SBarry Smith    Output Parameters:
1854c7afd0dbSLois Curfman McInnes +  A - location to stash Jacobian matrix (or PETSC_NULL)
1855b4fd4287SBarry Smith .  B - location to stash preconditioner matrix (or PETSC_NULL)
185670e92668SMatthew Knepley .  func - location to put Jacobian function (or PETSC_NULL)
185770e92668SMatthew Knepley -  ctx - location to stash Jacobian ctx (or PETSC_NULL)
1858fee21e36SBarry Smith 
185936851e7fSLois Curfman McInnes    Level: advanced
186036851e7fSLois Curfman McInnes 
1861b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian()
1862b4fd4287SBarry Smith @*/
18637087cfbeSBarry Smith PetscErrorCode  SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
1864b4fd4287SBarry Smith {
18653a40ed3dSBarry Smith   PetscFunctionBegin;
18660700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1867b4fd4287SBarry Smith   if (A)    *A    = snes->jacobian;
1868b4fd4287SBarry Smith   if (B)    *B    = snes->jacobian_pre;
1869e7788613SBarry Smith   if (func) *func = snes->ops->computejacobian;
187070e92668SMatthew Knepley   if (ctx)  *ctx  = snes->jacP;
18713a40ed3dSBarry Smith   PetscFunctionReturn(0);
1872b4fd4287SBarry Smith }
1873b4fd4287SBarry Smith 
18749b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */
18759b94acceSBarry Smith 
18764a2ae208SSatish Balay #undef __FUNCT__
18774a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp"
18789b94acceSBarry Smith /*@
18799b94acceSBarry Smith    SNESSetUp - Sets up the internal data structures for the later use
1880272ac6f2SLois Curfman McInnes    of a nonlinear solver.
18819b94acceSBarry Smith 
1882fee21e36SBarry Smith    Collective on SNES
1883fee21e36SBarry Smith 
1884c7afd0dbSLois Curfman McInnes    Input Parameters:
188570e92668SMatthew Knepley .  snes - the SNES context
1886c7afd0dbSLois Curfman McInnes 
1887272ac6f2SLois Curfman McInnes    Notes:
1888272ac6f2SLois Curfman McInnes    For basic use of the SNES solvers the user need not explicitly call
1889272ac6f2SLois Curfman McInnes    SNESSetUp(), since these actions will automatically occur during
1890272ac6f2SLois Curfman McInnes    the call to SNESSolve().  However, if one wishes to control this
1891272ac6f2SLois Curfman McInnes    phase separately, SNESSetUp() should be called after SNESCreate()
1892272ac6f2SLois Curfman McInnes    and optional routines of the form SNESSetXXX(), but before SNESSolve().
1893272ac6f2SLois Curfman McInnes 
189436851e7fSLois Curfman McInnes    Level: advanced
189536851e7fSLois Curfman McInnes 
18969b94acceSBarry Smith .keywords: SNES, nonlinear, setup
18979b94acceSBarry Smith 
18989b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
18999b94acceSBarry Smith @*/
19007087cfbeSBarry Smith PetscErrorCode  SNESSetUp(SNES snes)
19019b94acceSBarry Smith {
1902dfbe8321SBarry Smith   PetscErrorCode ierr;
19033a40ed3dSBarry Smith 
19043a40ed3dSBarry Smith   PetscFunctionBegin;
19050700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
19064dc4c822SBarry Smith   if (snes->setupcalled) PetscFunctionReturn(0);
19079b94acceSBarry Smith 
19087adad957SLisandro Dalcin   if (!((PetscObject)snes)->type_name) {
190985385478SLisandro Dalcin     ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr);
191085385478SLisandro Dalcin   }
191185385478SLisandro Dalcin 
1912c9b9fda1SJed Brown   if (!snes->vec_func) {
1913c9b9fda1SJed Brown     if (snes->vec_rhs) {
1914c9b9fda1SJed Brown       ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr);
1915c9b9fda1SJed Brown     } else if (snes->vec_sol) {
1916c9b9fda1SJed Brown       ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr);
1917c9b9fda1SJed Brown     } else if (snes->dm) {
1918efd51863SBarry Smith       ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr);
1919efd51863SBarry Smith     }
1920c9b9fda1SJed Brown   }
192117186662SBarry Smith   if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
192258c9b817SLisandro Dalcin   if (snes->vec_rhs  == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector");
192358c9b817SLisandro Dalcin 
192458c9b817SLisandro Dalcin   if (!snes->vec_sol_update /* && snes->vec_sol */) {
192558c9b817SLisandro Dalcin     ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr);
192658c9b817SLisandro Dalcin     ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr);
192758c9b817SLisandro Dalcin   }
192858c9b817SLisandro Dalcin 
1929ef8dffc7SBarry Smith   if (!snes->ops->computejacobian && snes->dm) {
1930ef8dffc7SBarry Smith     Mat J;
1931950540a4SJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&J);CHKERRQ(ierr);
1932cab2e9ccSBarry Smith     ierr = SNESSetJacobian(snes,J,J,SNESDMComputeJacobian,PETSC_NULL);CHKERRQ(ierr);
1933cab2e9ccSBarry Smith     ierr = MatDestroy(&J);CHKERRQ(ierr);
19342ef29e96SBarry Smith   } else if (!snes->jacobian && snes->ops->computejacobian == MatMFFDComputeJacobian) {
1935a8248277SBarry Smith     Mat J;
1936a8248277SBarry Smith     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
1937a8248277SBarry Smith     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
1938a8248277SBarry Smith     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
1939a8248277SBarry Smith     ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,snes->funP);CHKERRQ(ierr);
1940a8248277SBarry Smith     ierr = MatDestroy(&J);CHKERRQ(ierr);
1941a8248277SBarry Smith   } else if (snes->dm && snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) {
1942a8248277SBarry Smith     Mat J,B;
1943a8248277SBarry Smith     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
1944a8248277SBarry Smith     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
1945a8248277SBarry Smith     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
1946950540a4SJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
1947a8248277SBarry Smith     ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,snes->funP);CHKERRQ(ierr);
1948a8248277SBarry Smith     ierr = MatDestroy(&J);CHKERRQ(ierr);
1949a8248277SBarry Smith     ierr = MatDestroy(&B);CHKERRQ(ierr);
1950efd51863SBarry Smith   } else if (snes->dm && !snes->jacobian_pre){
1951efd51863SBarry Smith     Mat J;
1952950540a4SJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&J);CHKERRQ(ierr);
19533cbb28f5SBarry Smith     ierr = SNESSetJacobian(snes,J,J,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
1954efd51863SBarry Smith     ierr = MatDestroy(&J);CHKERRQ(ierr);
1955ef8dffc7SBarry Smith   }
1956cfaf3a74SBarry Smith   if (!snes->ops->computefunction && !snes->dm) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction() or call SNESSetDM()");
1957c9b9fda1SJed Brown   if (!snes->vec_func) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a vector when calling SNESSetFunction() or call SNESSetDM()");
1958efd51863SBarry Smith 
1959b710008aSBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);}
1960b710008aSBarry Smith 
1961d25893d9SBarry Smith   if (snes->ops->usercompute && !snes->user) {
1962d25893d9SBarry Smith     ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr);
1963d25893d9SBarry Smith   }
1964d25893d9SBarry Smith 
1965410397dcSLisandro Dalcin   if (snes->ops->setup) {
1966410397dcSLisandro Dalcin     ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr);
1967410397dcSLisandro Dalcin   }
196858c9b817SLisandro Dalcin 
19697aaed0d8SBarry Smith   snes->setupcalled = PETSC_TRUE;
19703a40ed3dSBarry Smith   PetscFunctionReturn(0);
19719b94acceSBarry Smith }
19729b94acceSBarry Smith 
19734a2ae208SSatish Balay #undef __FUNCT__
197437596af1SLisandro Dalcin #define __FUNCT__ "SNESReset"
197537596af1SLisandro Dalcin /*@
197637596af1SLisandro Dalcin    SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats
197737596af1SLisandro Dalcin 
197837596af1SLisandro Dalcin    Collective on SNES
197937596af1SLisandro Dalcin 
198037596af1SLisandro Dalcin    Input Parameter:
198137596af1SLisandro Dalcin .  snes - iterative context obtained from SNESCreate()
198237596af1SLisandro Dalcin 
1983d25893d9SBarry Smith    Level: intermediate
1984d25893d9SBarry Smith 
1985d25893d9SBarry Smith    Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext()
198637596af1SLisandro Dalcin 
198737596af1SLisandro Dalcin .keywords: SNES, destroy
198837596af1SLisandro Dalcin 
198937596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve()
199037596af1SLisandro Dalcin @*/
199137596af1SLisandro Dalcin PetscErrorCode  SNESReset(SNES snes)
199237596af1SLisandro Dalcin {
199337596af1SLisandro Dalcin   PetscErrorCode ierr;
199437596af1SLisandro Dalcin 
199537596af1SLisandro Dalcin   PetscFunctionBegin;
199637596af1SLisandro Dalcin   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1997d25893d9SBarry Smith   if (snes->ops->userdestroy && snes->user) {
1998d25893d9SBarry Smith     ierr       = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr);
1999d25893d9SBarry Smith     snes->user = PETSC_NULL;
2000d25893d9SBarry Smith   }
20018a23116dSBarry Smith   if (snes->pc) {
20028a23116dSBarry Smith     ierr = SNESReset(snes->pc);CHKERRQ(ierr);
20038a23116dSBarry Smith   }
20048a23116dSBarry Smith 
200537596af1SLisandro Dalcin   if (snes->ops->reset) {
200637596af1SLisandro Dalcin     ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr);
200737596af1SLisandro Dalcin   }
200837596af1SLisandro Dalcin   if (snes->ksp) {ierr = KSPReset(snes->ksp);CHKERRQ(ierr);}
20096bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
20106bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
20116bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr);
20126bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
20136bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
20146bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
201537596af1SLisandro Dalcin   if (snes->work) {ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);}
201637596af1SLisandro Dalcin   if (snes->vwork) {ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);}
201737596af1SLisandro Dalcin   snes->nwork = snes->nvwork = 0;
201837596af1SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
201937596af1SLisandro Dalcin   PetscFunctionReturn(0);
202037596af1SLisandro Dalcin }
202137596af1SLisandro Dalcin 
202237596af1SLisandro Dalcin #undef __FUNCT__
20234a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy"
202452baeb72SSatish Balay /*@
20259b94acceSBarry Smith    SNESDestroy - Destroys the nonlinear solver context that was created
20269b94acceSBarry Smith    with SNESCreate().
20279b94acceSBarry Smith 
2028c7afd0dbSLois Curfman McInnes    Collective on SNES
2029c7afd0dbSLois Curfman McInnes 
20309b94acceSBarry Smith    Input Parameter:
20319b94acceSBarry Smith .  snes - the SNES context
20329b94acceSBarry Smith 
203336851e7fSLois Curfman McInnes    Level: beginner
203436851e7fSLois Curfman McInnes 
20359b94acceSBarry Smith .keywords: SNES, nonlinear, destroy
20369b94acceSBarry Smith 
203763a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve()
20389b94acceSBarry Smith @*/
20396bf464f9SBarry Smith PetscErrorCode  SNESDestroy(SNES *snes)
20409b94acceSBarry Smith {
20416849ba73SBarry Smith   PetscErrorCode ierr;
20423a40ed3dSBarry Smith 
20433a40ed3dSBarry Smith   PetscFunctionBegin;
20446bf464f9SBarry Smith   if (!*snes) PetscFunctionReturn(0);
20456bf464f9SBarry Smith   PetscValidHeaderSpecific((*snes),SNES_CLASSID,1);
20466bf464f9SBarry Smith   if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);}
2047d4bb536fSBarry Smith 
20486bf464f9SBarry Smith   ierr = SNESReset((*snes));CHKERRQ(ierr);
20498a23116dSBarry Smith   ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr);
20506b8b9a38SLisandro Dalcin 
2051be0abb6dSBarry Smith   /* if memory was published with AMS then destroy it */
20526bf464f9SBarry Smith   ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr);
20536bf464f9SBarry Smith   if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);}
20546d4c513bSLisandro Dalcin 
20556bf464f9SBarry Smith   ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr);
20566bf464f9SBarry Smith   ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr);
20576b8b9a38SLisandro Dalcin 
20586bf464f9SBarry Smith   ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr);
20596bf464f9SBarry Smith   if ((*snes)->ops->convergeddestroy) {
20606bf464f9SBarry Smith     ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr);
20616b8b9a38SLisandro Dalcin   }
20626bf464f9SBarry Smith   if ((*snes)->conv_malloc) {
20636bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr);
20646bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr);
206558c9b817SLisandro Dalcin   }
2066ea630c6eSPeter Brune   ierr = PetscViewerDestroy(&(*snes)->ls_monitor);CHKERRQ(ierr);
20676bf464f9SBarry Smith   ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr);
2068a79aaaedSSatish Balay   ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr);
20693a40ed3dSBarry Smith  PetscFunctionReturn(0);
20709b94acceSBarry Smith }
20719b94acceSBarry Smith 
20729b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */
20739b94acceSBarry Smith 
20744a2ae208SSatish Balay #undef __FUNCT__
2075a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner"
2076a8054027SBarry Smith /*@
2077a8054027SBarry Smith    SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.
2078a8054027SBarry Smith 
20793f9fe445SBarry Smith    Logically Collective on SNES
2080a8054027SBarry Smith 
2081a8054027SBarry Smith    Input Parameters:
2082a8054027SBarry Smith +  snes - the SNES context
2083a8054027SBarry 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
20843b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2085a8054027SBarry Smith 
2086a8054027SBarry Smith    Options Database Keys:
2087a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2088a8054027SBarry Smith 
2089a8054027SBarry Smith    Notes:
2090a8054027SBarry Smith    The default is 1
2091a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2092a8054027SBarry Smith    If  -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use
2093a8054027SBarry Smith 
2094a8054027SBarry Smith    Level: intermediate
2095a8054027SBarry Smith 
2096a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2097a8054027SBarry Smith 
2098e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2099a8054027SBarry Smith 
2100a8054027SBarry Smith @*/
21017087cfbeSBarry Smith PetscErrorCode  SNESSetLagPreconditioner(SNES snes,PetscInt lag)
2102a8054027SBarry Smith {
2103a8054027SBarry Smith   PetscFunctionBegin;
21040700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2105e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2106e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2107c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2108a8054027SBarry Smith   snes->lagpreconditioner = lag;
2109a8054027SBarry Smith   PetscFunctionReturn(0);
2110a8054027SBarry Smith }
2111a8054027SBarry Smith 
2112a8054027SBarry Smith #undef __FUNCT__
2113efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence"
2114efd51863SBarry Smith /*@
2115efd51863SBarry Smith    SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does
2116efd51863SBarry Smith 
2117efd51863SBarry Smith    Logically Collective on SNES
2118efd51863SBarry Smith 
2119efd51863SBarry Smith    Input Parameters:
2120efd51863SBarry Smith +  snes - the SNES context
2121efd51863SBarry Smith -  steps - the number of refinements to do, defaults to 0
2122efd51863SBarry Smith 
2123efd51863SBarry Smith    Options Database Keys:
2124efd51863SBarry Smith .    -snes_grid_sequence <steps>
2125efd51863SBarry Smith 
2126efd51863SBarry Smith    Level: intermediate
2127efd51863SBarry Smith 
2128c0df2a02SJed Brown    Notes:
2129c0df2a02SJed Brown    Use SNESGetSolution() to extract the fine grid solution after grid sequencing.
2130c0df2a02SJed Brown 
2131efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2132efd51863SBarry Smith 
2133efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2134efd51863SBarry Smith 
2135efd51863SBarry Smith @*/
2136efd51863SBarry Smith PetscErrorCode  SNESSetGridSequence(SNES snes,PetscInt steps)
2137efd51863SBarry Smith {
2138efd51863SBarry Smith   PetscFunctionBegin;
2139efd51863SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2140efd51863SBarry Smith   PetscValidLogicalCollectiveInt(snes,steps,2);
2141efd51863SBarry Smith   snes->gridsequence = steps;
2142efd51863SBarry Smith   PetscFunctionReturn(0);
2143efd51863SBarry Smith }
2144efd51863SBarry Smith 
2145efd51863SBarry Smith #undef __FUNCT__
2146a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner"
2147a8054027SBarry Smith /*@
2148a8054027SBarry Smith    SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt
2149a8054027SBarry Smith 
21503f9fe445SBarry Smith    Not Collective
2151a8054027SBarry Smith 
2152a8054027SBarry Smith    Input Parameter:
2153a8054027SBarry Smith .  snes - the SNES context
2154a8054027SBarry Smith 
2155a8054027SBarry Smith    Output Parameter:
2156a8054027SBarry 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
21573b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2158a8054027SBarry Smith 
2159a8054027SBarry Smith    Options Database Keys:
2160a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2161a8054027SBarry Smith 
2162a8054027SBarry Smith    Notes:
2163a8054027SBarry Smith    The default is 1
2164a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2165a8054027SBarry Smith 
2166a8054027SBarry Smith    Level: intermediate
2167a8054027SBarry Smith 
2168a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2169a8054027SBarry Smith 
2170a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner()
2171a8054027SBarry Smith 
2172a8054027SBarry Smith @*/
21737087cfbeSBarry Smith PetscErrorCode  SNESGetLagPreconditioner(SNES snes,PetscInt *lag)
2174a8054027SBarry Smith {
2175a8054027SBarry Smith   PetscFunctionBegin;
21760700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2177a8054027SBarry Smith   *lag = snes->lagpreconditioner;
2178a8054027SBarry Smith   PetscFunctionReturn(0);
2179a8054027SBarry Smith }
2180a8054027SBarry Smith 
2181a8054027SBarry Smith #undef __FUNCT__
2182e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian"
2183e35cf81dSBarry Smith /*@
2184e35cf81dSBarry Smith    SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how
2185e35cf81dSBarry Smith      often the preconditioner is rebuilt.
2186e35cf81dSBarry Smith 
21873f9fe445SBarry Smith    Logically Collective on SNES
2188e35cf81dSBarry Smith 
2189e35cf81dSBarry Smith    Input Parameters:
2190e35cf81dSBarry Smith +  snes - the SNES context
2191e35cf81dSBarry 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
2192fe3ffe1eSBarry Smith          the Jacobian is built etc. -2 means rebuild at next chance but then never again
2193e35cf81dSBarry Smith 
2194e35cf81dSBarry Smith    Options Database Keys:
2195e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2196e35cf81dSBarry Smith 
2197e35cf81dSBarry Smith    Notes:
2198e35cf81dSBarry Smith    The default is 1
2199e35cf81dSBarry Smith    The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2200fe3ffe1eSBarry 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
2201fe3ffe1eSBarry Smith    at the next Newton step but never again (unless it is reset to another value)
2202e35cf81dSBarry Smith 
2203e35cf81dSBarry Smith    Level: intermediate
2204e35cf81dSBarry Smith 
2205e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2206e35cf81dSBarry Smith 
2207e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian()
2208e35cf81dSBarry Smith 
2209e35cf81dSBarry Smith @*/
22107087cfbeSBarry Smith PetscErrorCode  SNESSetLagJacobian(SNES snes,PetscInt lag)
2211e35cf81dSBarry Smith {
2212e35cf81dSBarry Smith   PetscFunctionBegin;
22130700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2214e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2215e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2216c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2217e35cf81dSBarry Smith   snes->lagjacobian = lag;
2218e35cf81dSBarry Smith   PetscFunctionReturn(0);
2219e35cf81dSBarry Smith }
2220e35cf81dSBarry Smith 
2221e35cf81dSBarry Smith #undef __FUNCT__
2222e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian"
2223e35cf81dSBarry Smith /*@
2224e35cf81dSBarry Smith    SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt
2225e35cf81dSBarry Smith 
22263f9fe445SBarry Smith    Not Collective
2227e35cf81dSBarry Smith 
2228e35cf81dSBarry Smith    Input Parameter:
2229e35cf81dSBarry Smith .  snes - the SNES context
2230e35cf81dSBarry Smith 
2231e35cf81dSBarry Smith    Output Parameter:
2232e35cf81dSBarry 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
2233e35cf81dSBarry Smith          the Jacobian is built etc.
2234e35cf81dSBarry Smith 
2235e35cf81dSBarry Smith    Options Database Keys:
2236e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2237e35cf81dSBarry Smith 
2238e35cf81dSBarry Smith    Notes:
2239e35cf81dSBarry Smith    The default is 1
2240e35cf81dSBarry Smith    The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2241e35cf81dSBarry Smith 
2242e35cf81dSBarry Smith    Level: intermediate
2243e35cf81dSBarry Smith 
2244e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2245e35cf81dSBarry Smith 
2246e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner()
2247e35cf81dSBarry Smith 
2248e35cf81dSBarry Smith @*/
22497087cfbeSBarry Smith PetscErrorCode  SNESGetLagJacobian(SNES snes,PetscInt *lag)
2250e35cf81dSBarry Smith {
2251e35cf81dSBarry Smith   PetscFunctionBegin;
22520700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2253e35cf81dSBarry Smith   *lag = snes->lagjacobian;
2254e35cf81dSBarry Smith   PetscFunctionReturn(0);
2255e35cf81dSBarry Smith }
2256e35cf81dSBarry Smith 
2257e35cf81dSBarry Smith #undef __FUNCT__
22584a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances"
22599b94acceSBarry Smith /*@
2260d7a720efSLois Curfman McInnes    SNESSetTolerances - Sets various parameters used in convergence tests.
22619b94acceSBarry Smith 
22623f9fe445SBarry Smith    Logically Collective on SNES
2263c7afd0dbSLois Curfman McInnes 
22649b94acceSBarry Smith    Input Parameters:
2265c7afd0dbSLois Curfman McInnes +  snes - the SNES context
226670441072SBarry Smith .  abstol - absolute convergence tolerance
226733174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
226833174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
226933174efeSLois Curfman McInnes            of the change in the solution between steps
227033174efeSLois Curfman McInnes .  maxit - maximum number of iterations
2271c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
2272fee21e36SBarry Smith 
227333174efeSLois Curfman McInnes    Options Database Keys:
227470441072SBarry Smith +    -snes_atol <abstol> - Sets abstol
2275c7afd0dbSLois Curfman McInnes .    -snes_rtol <rtol> - Sets rtol
2276c7afd0dbSLois Curfman McInnes .    -snes_stol <stol> - Sets stol
2277c7afd0dbSLois Curfman McInnes .    -snes_max_it <maxit> - Sets maxit
2278c7afd0dbSLois Curfman McInnes -    -snes_max_funcs <maxf> - Sets maxf
22799b94acceSBarry Smith 
2280d7a720efSLois Curfman McInnes    Notes:
22819b94acceSBarry Smith    The default maximum number of iterations is 50.
22829b94acceSBarry Smith    The default maximum number of function evaluations is 1000.
22839b94acceSBarry Smith 
228436851e7fSLois Curfman McInnes    Level: intermediate
228536851e7fSLois Curfman McInnes 
228633174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances
22879b94acceSBarry Smith 
22882492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance()
22899b94acceSBarry Smith @*/
22907087cfbeSBarry Smith PetscErrorCode  SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
22919b94acceSBarry Smith {
22923a40ed3dSBarry Smith   PetscFunctionBegin;
22930700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2294c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,abstol,2);
2295c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol,3);
2296c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,stol,4);
2297c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxit,5);
2298c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxf,6);
2299c5eb9154SBarry Smith 
2300ab54825eSJed Brown   if (abstol != PETSC_DEFAULT) {
2301ab54825eSJed Brown     if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol);
2302ab54825eSJed Brown     snes->abstol = abstol;
2303ab54825eSJed Brown   }
2304ab54825eSJed Brown   if (rtol != PETSC_DEFAULT) {
2305ab54825eSJed 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);
2306ab54825eSJed Brown     snes->rtol = rtol;
2307ab54825eSJed Brown   }
2308ab54825eSJed Brown   if (stol != PETSC_DEFAULT) {
2309ab54825eSJed Brown     if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol);
2310ab54825eSJed Brown     snes->xtol = stol;
2311ab54825eSJed Brown   }
2312ab54825eSJed Brown   if (maxit != PETSC_DEFAULT) {
2313ab54825eSJed Brown     if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit);
2314ab54825eSJed Brown     snes->max_its = maxit;
2315ab54825eSJed Brown   }
2316ab54825eSJed Brown   if (maxf != PETSC_DEFAULT) {
2317ab54825eSJed Brown     if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf);
2318ab54825eSJed Brown     snes->max_funcs = maxf;
2319ab54825eSJed Brown   }
23203a40ed3dSBarry Smith   PetscFunctionReturn(0);
23219b94acceSBarry Smith }
23229b94acceSBarry Smith 
23234a2ae208SSatish Balay #undef __FUNCT__
23244a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances"
23259b94acceSBarry Smith /*@
232633174efeSLois Curfman McInnes    SNESGetTolerances - Gets various parameters used in convergence tests.
232733174efeSLois Curfman McInnes 
2328c7afd0dbSLois Curfman McInnes    Not Collective
2329c7afd0dbSLois Curfman McInnes 
233033174efeSLois Curfman McInnes    Input Parameters:
2331c7afd0dbSLois Curfman McInnes +  snes - the SNES context
233285385478SLisandro Dalcin .  atol - absolute convergence tolerance
233333174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
233433174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
233533174efeSLois Curfman McInnes            of the change in the solution between steps
233633174efeSLois Curfman McInnes .  maxit - maximum number of iterations
2337c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
2338fee21e36SBarry Smith 
233933174efeSLois Curfman McInnes    Notes:
234033174efeSLois Curfman McInnes    The user can specify PETSC_NULL for any parameter that is not needed.
234133174efeSLois Curfman McInnes 
234236851e7fSLois Curfman McInnes    Level: intermediate
234336851e7fSLois Curfman McInnes 
234433174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances
234533174efeSLois Curfman McInnes 
234633174efeSLois Curfman McInnes .seealso: SNESSetTolerances()
234733174efeSLois Curfman McInnes @*/
23487087cfbeSBarry Smith PetscErrorCode  SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
234933174efeSLois Curfman McInnes {
23503a40ed3dSBarry Smith   PetscFunctionBegin;
23510700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
235285385478SLisandro Dalcin   if (atol)  *atol  = snes->abstol;
235333174efeSLois Curfman McInnes   if (rtol)  *rtol  = snes->rtol;
235433174efeSLois Curfman McInnes   if (stol)  *stol  = snes->xtol;
235533174efeSLois Curfman McInnes   if (maxit) *maxit = snes->max_its;
235633174efeSLois Curfman McInnes   if (maxf)  *maxf  = snes->max_funcs;
23573a40ed3dSBarry Smith   PetscFunctionReturn(0);
235833174efeSLois Curfman McInnes }
235933174efeSLois Curfman McInnes 
23604a2ae208SSatish Balay #undef __FUNCT__
23614a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance"
236233174efeSLois Curfman McInnes /*@
23639b94acceSBarry Smith    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
23649b94acceSBarry Smith 
23653f9fe445SBarry Smith    Logically Collective on SNES
2366fee21e36SBarry Smith 
2367c7afd0dbSLois Curfman McInnes    Input Parameters:
2368c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2369c7afd0dbSLois Curfman McInnes -  tol - tolerance
2370c7afd0dbSLois Curfman McInnes 
23719b94acceSBarry Smith    Options Database Key:
2372c7afd0dbSLois Curfman McInnes .  -snes_trtol <tol> - Sets tol
23739b94acceSBarry Smith 
237436851e7fSLois Curfman McInnes    Level: intermediate
237536851e7fSLois Curfman McInnes 
23769b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance
23779b94acceSBarry Smith 
23782492ecdbSBarry Smith .seealso: SNESSetTolerances()
23799b94acceSBarry Smith @*/
23807087cfbeSBarry Smith PetscErrorCode  SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
23819b94acceSBarry Smith {
23823a40ed3dSBarry Smith   PetscFunctionBegin;
23830700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2384c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,tol,2);
23859b94acceSBarry Smith   snes->deltatol = tol;
23863a40ed3dSBarry Smith   PetscFunctionReturn(0);
23879b94acceSBarry Smith }
23889b94acceSBarry Smith 
2389df9fa365SBarry Smith /*
2390df9fa365SBarry Smith    Duplicate the lg monitors for SNES from KSP; for some reason with
2391df9fa365SBarry Smith    dynamic libraries things don't work under Sun4 if we just use
2392df9fa365SBarry Smith    macros instead of functions
2393df9fa365SBarry Smith */
23944a2ae208SSatish Balay #undef __FUNCT__
2395a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG"
23967087cfbeSBarry Smith PetscErrorCode  SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx)
2397ce1608b8SBarry Smith {
2398dfbe8321SBarry Smith   PetscErrorCode ierr;
2399ce1608b8SBarry Smith 
2400ce1608b8SBarry Smith   PetscFunctionBegin;
24010700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2402a6570f20SBarry Smith   ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr);
2403ce1608b8SBarry Smith   PetscFunctionReturn(0);
2404ce1608b8SBarry Smith }
2405ce1608b8SBarry Smith 
24064a2ae208SSatish Balay #undef __FUNCT__
2407a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate"
24087087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2409df9fa365SBarry Smith {
2410dfbe8321SBarry Smith   PetscErrorCode ierr;
2411df9fa365SBarry Smith 
2412df9fa365SBarry Smith   PetscFunctionBegin;
2413a6570f20SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2414df9fa365SBarry Smith   PetscFunctionReturn(0);
2415df9fa365SBarry Smith }
2416df9fa365SBarry Smith 
24174a2ae208SSatish Balay #undef __FUNCT__
2418a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy"
24196bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGDestroy(PetscDrawLG *draw)
2420df9fa365SBarry Smith {
2421dfbe8321SBarry Smith   PetscErrorCode ierr;
2422df9fa365SBarry Smith 
2423df9fa365SBarry Smith   PetscFunctionBegin;
2424a6570f20SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2425df9fa365SBarry Smith   PetscFunctionReturn(0);
2426df9fa365SBarry Smith }
2427df9fa365SBarry Smith 
24287087cfbeSBarry Smith extern PetscErrorCode  SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
2429b271bb04SBarry Smith #undef __FUNCT__
2430b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange"
24317087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx)
2432b271bb04SBarry Smith {
2433b271bb04SBarry Smith   PetscDrawLG      lg;
2434b271bb04SBarry Smith   PetscErrorCode   ierr;
2435b271bb04SBarry Smith   PetscReal        x,y,per;
2436b271bb04SBarry Smith   PetscViewer      v = (PetscViewer)monctx;
2437b271bb04SBarry Smith   static PetscReal prev; /* should be in the context */
2438b271bb04SBarry Smith   PetscDraw        draw;
2439b271bb04SBarry Smith   PetscFunctionBegin;
2440b271bb04SBarry Smith   if (!monctx) {
2441b271bb04SBarry Smith     MPI_Comm    comm;
2442b271bb04SBarry Smith 
2443b271bb04SBarry Smith     ierr   = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
2444b271bb04SBarry Smith     v      = PETSC_VIEWER_DRAW_(comm);
2445b271bb04SBarry Smith   }
2446b271bb04SBarry Smith   ierr   = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr);
2447b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2448b271bb04SBarry Smith   ierr   = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2449b271bb04SBarry Smith   ierr   = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr);
2450b271bb04SBarry Smith   x = (PetscReal) n;
2451b271bb04SBarry Smith   if (rnorm > 0.0) y = log10(rnorm); else y = -15.0;
2452b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2453b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2454b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2455b271bb04SBarry Smith   }
2456b271bb04SBarry Smith 
2457b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr);
2458b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2459b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2460b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr);
2461b271bb04SBarry Smith   ierr =  SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr);
2462b271bb04SBarry Smith   x = (PetscReal) n;
2463b271bb04SBarry Smith   y = 100.0*per;
2464b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2465b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2466b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2467b271bb04SBarry Smith   }
2468b271bb04SBarry Smith 
2469b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr);
2470b271bb04SBarry Smith   if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2471b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2472b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr);
2473b271bb04SBarry Smith   x = (PetscReal) n;
2474b271bb04SBarry Smith   y = (prev - rnorm)/prev;
2475b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2476b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2477b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2478b271bb04SBarry Smith   }
2479b271bb04SBarry Smith 
2480b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr);
2481b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2482b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2483b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr);
2484b271bb04SBarry Smith   x = (PetscReal) n;
2485b271bb04SBarry Smith   y = (prev - rnorm)/(prev*per);
2486b271bb04SBarry Smith   if (n > 2) { /*skip initial crazy value */
2487b271bb04SBarry Smith     ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2488b271bb04SBarry Smith   }
2489b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2490b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2491b271bb04SBarry Smith   }
2492b271bb04SBarry Smith   prev = rnorm;
2493b271bb04SBarry Smith   PetscFunctionReturn(0);
2494b271bb04SBarry Smith }
2495b271bb04SBarry Smith 
2496b271bb04SBarry Smith #undef __FUNCT__
2497b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate"
24987087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2499b271bb04SBarry Smith {
2500b271bb04SBarry Smith   PetscErrorCode ierr;
2501b271bb04SBarry Smith 
2502b271bb04SBarry Smith   PetscFunctionBegin;
2503b271bb04SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2504b271bb04SBarry Smith   PetscFunctionReturn(0);
2505b271bb04SBarry Smith }
2506b271bb04SBarry Smith 
2507b271bb04SBarry Smith #undef __FUNCT__
2508b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy"
25096bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGRangeDestroy(PetscDrawLG *draw)
2510b271bb04SBarry Smith {
2511b271bb04SBarry Smith   PetscErrorCode ierr;
2512b271bb04SBarry Smith 
2513b271bb04SBarry Smith   PetscFunctionBegin;
2514b271bb04SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2515b271bb04SBarry Smith   PetscFunctionReturn(0);
2516b271bb04SBarry Smith }
2517b271bb04SBarry Smith 
25187a03ce2fSLisandro Dalcin #undef __FUNCT__
25197a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor"
2520228d79bcSJed Brown /*@
2521228d79bcSJed Brown    SNESMonitor - runs the user provided monitor routines, if they exist
2522228d79bcSJed Brown 
2523228d79bcSJed Brown    Collective on SNES
2524228d79bcSJed Brown 
2525228d79bcSJed Brown    Input Parameters:
2526228d79bcSJed Brown +  snes - nonlinear solver context obtained from SNESCreate()
2527228d79bcSJed Brown .  iter - iteration number
2528228d79bcSJed Brown -  rnorm - relative norm of the residual
2529228d79bcSJed Brown 
2530228d79bcSJed Brown    Notes:
2531228d79bcSJed Brown    This routine is called by the SNES implementations.
2532228d79bcSJed Brown    It does not typically need to be called by the user.
2533228d79bcSJed Brown 
2534228d79bcSJed Brown    Level: developer
2535228d79bcSJed Brown 
2536228d79bcSJed Brown .seealso: SNESMonitorSet()
2537228d79bcSJed Brown @*/
25387a03ce2fSLisandro Dalcin PetscErrorCode  SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm)
25397a03ce2fSLisandro Dalcin {
25407a03ce2fSLisandro Dalcin   PetscErrorCode ierr;
25417a03ce2fSLisandro Dalcin   PetscInt       i,n = snes->numbermonitors;
25427a03ce2fSLisandro Dalcin 
25437a03ce2fSLisandro Dalcin   PetscFunctionBegin;
25447a03ce2fSLisandro Dalcin   for (i=0; i<n; i++) {
25457a03ce2fSLisandro Dalcin     ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr);
25467a03ce2fSLisandro Dalcin   }
25477a03ce2fSLisandro Dalcin   PetscFunctionReturn(0);
25487a03ce2fSLisandro Dalcin }
25497a03ce2fSLisandro Dalcin 
25509b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */
25519b94acceSBarry Smith 
25524a2ae208SSatish Balay #undef __FUNCT__
2553a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet"
25549b94acceSBarry Smith /*@C
2555a6570f20SBarry Smith    SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
25569b94acceSBarry Smith    iteration of the nonlinear solver to display the iteration's
25579b94acceSBarry Smith    progress.
25589b94acceSBarry Smith 
25593f9fe445SBarry Smith    Logically Collective on SNES
2560fee21e36SBarry Smith 
2561c7afd0dbSLois Curfman McInnes    Input Parameters:
2562c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2563c7afd0dbSLois Curfman McInnes .  func - monitoring routine
2564b8a78c4aSBarry Smith .  mctx - [optional] user-defined context for private data for the
2565e8105e01SRichard Katz           monitor routine (use PETSC_NULL if no context is desired)
2566b3006f0bSLois Curfman McInnes -  monitordestroy - [optional] routine that frees monitor context
2567b3006f0bSLois Curfman McInnes           (may be PETSC_NULL)
25689b94acceSBarry Smith 
2569c7afd0dbSLois Curfman McInnes    Calling sequence of func:
2570a7cc72afSBarry Smith $     int func(SNES snes,PetscInt its, PetscReal norm,void *mctx)
2571c7afd0dbSLois Curfman McInnes 
2572c7afd0dbSLois Curfman McInnes +    snes - the SNES context
2573c7afd0dbSLois Curfman McInnes .    its - iteration number
2574c7afd0dbSLois Curfman McInnes .    norm - 2-norm function value (may be estimated)
257540a0c1c6SLois Curfman McInnes -    mctx - [optional] monitoring context
25769b94acceSBarry Smith 
25779665c990SLois Curfman McInnes    Options Database Keys:
2578a6570f20SBarry Smith +    -snes_monitor        - sets SNESMonitorDefault()
2579a6570f20SBarry Smith .    -snes_monitor_draw    - sets line graph monitor,
2580a6570f20SBarry Smith                             uses SNESMonitorLGCreate()
2581cca6129bSJed Brown -    -snes_monitor_cancel - cancels all monitors that have
2582c7afd0dbSLois Curfman McInnes                             been hardwired into a code by
2583a6570f20SBarry Smith                             calls to SNESMonitorSet(), but
2584c7afd0dbSLois Curfman McInnes                             does not cancel those set via
2585c7afd0dbSLois Curfman McInnes                             the options database.
25869665c990SLois Curfman McInnes 
2587639f9d9dSBarry Smith    Notes:
25886bc08f3fSLois Curfman McInnes    Several different monitoring routines may be set by calling
2589a6570f20SBarry Smith    SNESMonitorSet() multiple times; all will be called in the
25906bc08f3fSLois Curfman McInnes    order in which they were set.
2591639f9d9dSBarry Smith 
2592025f1a04SBarry Smith    Fortran notes: Only a single monitor function can be set for each SNES object
2593025f1a04SBarry Smith 
259436851e7fSLois Curfman McInnes    Level: intermediate
259536851e7fSLois Curfman McInnes 
25969b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor
25979b94acceSBarry Smith 
2598a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel()
25999b94acceSBarry Smith @*/
2600c2efdce3SBarry Smith PetscErrorCode  SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
26019b94acceSBarry Smith {
2602b90d0a6eSBarry Smith   PetscInt       i;
2603649052a6SBarry Smith   PetscErrorCode ierr;
2604b90d0a6eSBarry Smith 
26053a40ed3dSBarry Smith   PetscFunctionBegin;
26060700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
260717186662SBarry Smith   if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
2608b90d0a6eSBarry Smith   for (i=0; i<snes->numbermonitors;i++) {
2609649052a6SBarry Smith     if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) {
2610649052a6SBarry Smith       if (monitordestroy) {
2611c2efdce3SBarry Smith         ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr);
2612649052a6SBarry Smith       }
2613b90d0a6eSBarry Smith       PetscFunctionReturn(0);
2614b90d0a6eSBarry Smith     }
2615b90d0a6eSBarry Smith   }
2616b90d0a6eSBarry Smith   snes->monitor[snes->numbermonitors]           = monitor;
2617b8a78c4aSBarry Smith   snes->monitordestroy[snes->numbermonitors]    = monitordestroy;
2618639f9d9dSBarry Smith   snes->monitorcontext[snes->numbermonitors++]  = (void*)mctx;
26193a40ed3dSBarry Smith   PetscFunctionReturn(0);
26209b94acceSBarry Smith }
26219b94acceSBarry Smith 
26224a2ae208SSatish Balay #undef __FUNCT__
2623a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel"
26245cd90555SBarry Smith /*@C
2625a6570f20SBarry Smith    SNESMonitorCancel - Clears all the monitor functions for a SNES object.
26265cd90555SBarry Smith 
26273f9fe445SBarry Smith    Logically Collective on SNES
2628c7afd0dbSLois Curfman McInnes 
26295cd90555SBarry Smith    Input Parameters:
26305cd90555SBarry Smith .  snes - the SNES context
26315cd90555SBarry Smith 
26321a480d89SAdministrator    Options Database Key:
2633a6570f20SBarry Smith .  -snes_monitor_cancel - cancels all monitors that have been hardwired
2634a6570f20SBarry Smith     into a code by calls to SNESMonitorSet(), but does not cancel those
2635c7afd0dbSLois Curfman McInnes     set via the options database
26365cd90555SBarry Smith 
26375cd90555SBarry Smith    Notes:
26385cd90555SBarry Smith    There is no way to clear one specific monitor from a SNES object.
26395cd90555SBarry Smith 
264036851e7fSLois Curfman McInnes    Level: intermediate
264136851e7fSLois Curfman McInnes 
26425cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor
26435cd90555SBarry Smith 
2644a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet()
26455cd90555SBarry Smith @*/
26467087cfbeSBarry Smith PetscErrorCode  SNESMonitorCancel(SNES snes)
26475cd90555SBarry Smith {
2648d952e501SBarry Smith   PetscErrorCode ierr;
2649d952e501SBarry Smith   PetscInt       i;
2650d952e501SBarry Smith 
26515cd90555SBarry Smith   PetscFunctionBegin;
26520700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2653d952e501SBarry Smith   for (i=0; i<snes->numbermonitors; i++) {
2654d952e501SBarry Smith     if (snes->monitordestroy[i]) {
26553c4aec1bSBarry Smith       ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr);
2656d952e501SBarry Smith     }
2657d952e501SBarry Smith   }
26585cd90555SBarry Smith   snes->numbermonitors = 0;
26595cd90555SBarry Smith   PetscFunctionReturn(0);
26605cd90555SBarry Smith }
26615cd90555SBarry Smith 
26624a2ae208SSatish Balay #undef __FUNCT__
26634a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest"
26649b94acceSBarry Smith /*@C
26659b94acceSBarry Smith    SNESSetConvergenceTest - Sets the function that is to be used
26669b94acceSBarry Smith    to test for convergence of the nonlinear iterative solution.
26679b94acceSBarry Smith 
26683f9fe445SBarry Smith    Logically Collective on SNES
2669fee21e36SBarry Smith 
2670c7afd0dbSLois Curfman McInnes    Input Parameters:
2671c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2672c7afd0dbSLois Curfman McInnes .  func - routine to test for convergence
26737f7931b9SBarry Smith .  cctx - [optional] context for private data for the convergence routine  (may be PETSC_NULL)
26747f7931b9SBarry Smith -  destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran)
26759b94acceSBarry Smith 
2676c7afd0dbSLois Curfman McInnes    Calling sequence of func:
267706ee9f85SBarry Smith $     PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
2678c7afd0dbSLois Curfman McInnes 
2679c7afd0dbSLois Curfman McInnes +    snes - the SNES context
268006ee9f85SBarry Smith .    it - current iteration (0 is the first and is before any Newton step)
2681c7afd0dbSLois Curfman McInnes .    cctx - [optional] convergence context
2682184914b5SBarry Smith .    reason - reason for convergence/divergence
2683c7afd0dbSLois Curfman McInnes .    xnorm - 2-norm of current iterate
26844b27c08aSLois Curfman McInnes .    gnorm - 2-norm of current step
26854b27c08aSLois Curfman McInnes -    f - 2-norm of function
26869b94acceSBarry Smith 
268736851e7fSLois Curfman McInnes    Level: advanced
268836851e7fSLois Curfman McInnes 
26899b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test
26909b94acceSBarry Smith 
269185385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged()
26929b94acceSBarry Smith @*/
26937087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
26949b94acceSBarry Smith {
26957f7931b9SBarry Smith   PetscErrorCode ierr;
26967f7931b9SBarry Smith 
26973a40ed3dSBarry Smith   PetscFunctionBegin;
26980700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
269985385478SLisandro Dalcin   if (!func) func = SNESSkipConverged;
27007f7931b9SBarry Smith   if (snes->ops->convergeddestroy) {
27017f7931b9SBarry Smith     ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr);
27027f7931b9SBarry Smith   }
270385385478SLisandro Dalcin   snes->ops->converged        = func;
27047f7931b9SBarry Smith   snes->ops->convergeddestroy = destroy;
270585385478SLisandro Dalcin   snes->cnvP                  = cctx;
27063a40ed3dSBarry Smith   PetscFunctionReturn(0);
27079b94acceSBarry Smith }
27089b94acceSBarry Smith 
27094a2ae208SSatish Balay #undef __FUNCT__
27104a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason"
271152baeb72SSatish Balay /*@
2712184914b5SBarry Smith    SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
2713184914b5SBarry Smith 
2714184914b5SBarry Smith    Not Collective
2715184914b5SBarry Smith 
2716184914b5SBarry Smith    Input Parameter:
2717184914b5SBarry Smith .  snes - the SNES context
2718184914b5SBarry Smith 
2719184914b5SBarry Smith    Output Parameter:
27204d0a8057SBarry Smith .  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
2721184914b5SBarry Smith             manual pages for the individual convergence tests for complete lists
2722184914b5SBarry Smith 
2723184914b5SBarry Smith    Level: intermediate
2724184914b5SBarry Smith 
2725184914b5SBarry Smith    Notes: Can only be called after the call the SNESSolve() is complete.
2726184914b5SBarry Smith 
2727184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test
2728184914b5SBarry Smith 
272985385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason
2730184914b5SBarry Smith @*/
27317087cfbeSBarry Smith PetscErrorCode  SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
2732184914b5SBarry Smith {
2733184914b5SBarry Smith   PetscFunctionBegin;
27340700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
27354482741eSBarry Smith   PetscValidPointer(reason,2);
2736184914b5SBarry Smith   *reason = snes->reason;
2737184914b5SBarry Smith   PetscFunctionReturn(0);
2738184914b5SBarry Smith }
2739184914b5SBarry Smith 
27404a2ae208SSatish Balay #undef __FUNCT__
27414a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory"
2742c9005455SLois Curfman McInnes /*@
2743c9005455SLois Curfman McInnes    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
2744c9005455SLois Curfman McInnes 
27453f9fe445SBarry Smith    Logically Collective on SNES
2746fee21e36SBarry Smith 
2747c7afd0dbSLois Curfman McInnes    Input Parameters:
2748c7afd0dbSLois Curfman McInnes +  snes - iterative context obtained from SNESCreate()
27498c7482ecSBarry Smith .  a   - array to hold history, this array will contain the function norms computed at each step
2750cd5578b5SBarry Smith .  its - integer array holds the number of linear iterations for each solve.
2751758f92a0SBarry Smith .  na  - size of a and its
275264731454SLois Curfman McInnes -  reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
2753758f92a0SBarry Smith            else it continues storing new values for new nonlinear solves after the old ones
2754c7afd0dbSLois Curfman McInnes 
2755308dcc3eSBarry Smith    Notes:
2756308dcc3eSBarry Smith    If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a
2757308dcc3eSBarry Smith    default array of length 10000 is allocated.
2758308dcc3eSBarry Smith 
2759c9005455SLois Curfman McInnes    This routine is useful, e.g., when running a code for purposes
2760c9005455SLois Curfman McInnes    of accurate performance monitoring, when no I/O should be done
2761c9005455SLois Curfman McInnes    during the section of code that is being timed.
2762c9005455SLois Curfman McInnes 
276336851e7fSLois Curfman McInnes    Level: intermediate
276436851e7fSLois Curfman McInnes 
2765c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history
2766758f92a0SBarry Smith 
276708405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory()
2768758f92a0SBarry Smith 
2769c9005455SLois Curfman McInnes @*/
27707087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool  reset)
2771c9005455SLois Curfman McInnes {
2772308dcc3eSBarry Smith   PetscErrorCode ierr;
2773308dcc3eSBarry Smith 
27743a40ed3dSBarry Smith   PetscFunctionBegin;
27750700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
27764482741eSBarry Smith   if (na)  PetscValidScalarPointer(a,2);
2777a562a398SLisandro Dalcin   if (its) PetscValidIntPointer(its,3);
2778308dcc3eSBarry Smith   if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) {
2779308dcc3eSBarry Smith     if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
2780308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr);
2781308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr);
2782308dcc3eSBarry Smith     snes->conv_malloc   = PETSC_TRUE;
2783308dcc3eSBarry Smith   }
2784c9005455SLois Curfman McInnes   snes->conv_hist       = a;
2785758f92a0SBarry Smith   snes->conv_hist_its   = its;
2786758f92a0SBarry Smith   snes->conv_hist_max   = na;
2787a12bc48fSLisandro Dalcin   snes->conv_hist_len   = 0;
2788758f92a0SBarry Smith   snes->conv_hist_reset = reset;
2789758f92a0SBarry Smith   PetscFunctionReturn(0);
2790758f92a0SBarry Smith }
2791758f92a0SBarry Smith 
2792308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
2793c6db04a5SJed Brown #include <engine.h>   /* MATLAB include file */
2794c6db04a5SJed Brown #include <mex.h>      /* MATLAB include file */
2795308dcc3eSBarry Smith EXTERN_C_BEGIN
2796308dcc3eSBarry Smith #undef __FUNCT__
2797308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab"
2798308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes)
2799308dcc3eSBarry Smith {
2800308dcc3eSBarry Smith   mxArray        *mat;
2801308dcc3eSBarry Smith   PetscInt       i;
2802308dcc3eSBarry Smith   PetscReal      *ar;
2803308dcc3eSBarry Smith 
2804308dcc3eSBarry Smith   PetscFunctionBegin;
2805308dcc3eSBarry Smith   mat  = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL);
2806308dcc3eSBarry Smith   ar   = (PetscReal*) mxGetData(mat);
2807308dcc3eSBarry Smith   for (i=0; i<snes->conv_hist_len; i++) {
2808308dcc3eSBarry Smith     ar[i] = snes->conv_hist[i];
2809308dcc3eSBarry Smith   }
2810308dcc3eSBarry Smith   PetscFunctionReturn(mat);
2811308dcc3eSBarry Smith }
2812308dcc3eSBarry Smith EXTERN_C_END
2813308dcc3eSBarry Smith #endif
2814308dcc3eSBarry Smith 
2815308dcc3eSBarry Smith 
28164a2ae208SSatish Balay #undef __FUNCT__
28174a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory"
28180c4c9dddSBarry Smith /*@C
2819758f92a0SBarry Smith    SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
2820758f92a0SBarry Smith 
28213f9fe445SBarry Smith    Not Collective
2822758f92a0SBarry Smith 
2823758f92a0SBarry Smith    Input Parameter:
2824758f92a0SBarry Smith .  snes - iterative context obtained from SNESCreate()
2825758f92a0SBarry Smith 
2826758f92a0SBarry Smith    Output Parameters:
2827758f92a0SBarry Smith .  a   - array to hold history
2828758f92a0SBarry Smith .  its - integer array holds the number of linear iterations (or
2829758f92a0SBarry Smith          negative if not converged) for each solve.
2830758f92a0SBarry Smith -  na  - size of a and its
2831758f92a0SBarry Smith 
2832758f92a0SBarry Smith    Notes:
2833758f92a0SBarry Smith     The calling sequence for this routine in Fortran is
2834758f92a0SBarry Smith $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
2835758f92a0SBarry Smith 
2836758f92a0SBarry Smith    This routine is useful, e.g., when running a code for purposes
2837758f92a0SBarry Smith    of accurate performance monitoring, when no I/O should be done
2838758f92a0SBarry Smith    during the section of code that is being timed.
2839758f92a0SBarry Smith 
2840758f92a0SBarry Smith    Level: intermediate
2841758f92a0SBarry Smith 
2842758f92a0SBarry Smith .keywords: SNES, get, convergence, history
2843758f92a0SBarry Smith 
2844758f92a0SBarry Smith .seealso: SNESSetConvergencHistory()
2845758f92a0SBarry Smith 
2846758f92a0SBarry Smith @*/
28477087cfbeSBarry Smith PetscErrorCode  SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
2848758f92a0SBarry Smith {
2849758f92a0SBarry Smith   PetscFunctionBegin;
28500700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2851758f92a0SBarry Smith   if (a)   *a   = snes->conv_hist;
2852758f92a0SBarry Smith   if (its) *its = snes->conv_hist_its;
2853758f92a0SBarry Smith   if (na)  *na  = snes->conv_hist_len;
28543a40ed3dSBarry Smith   PetscFunctionReturn(0);
2855c9005455SLois Curfman McInnes }
2856c9005455SLois Curfman McInnes 
2857e74ef692SMatthew Knepley #undef __FUNCT__
2858e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate"
2859ac226902SBarry Smith /*@C
286076b2cf59SMatthew Knepley   SNESSetUpdate - Sets the general-purpose update function called
2861eec8f646SJed Brown   at the beginning of every iteration of the nonlinear solve. Specifically
28627e4bb74cSBarry Smith   it is called just before the Jacobian is "evaluated".
286376b2cf59SMatthew Knepley 
28643f9fe445SBarry Smith   Logically Collective on SNES
286576b2cf59SMatthew Knepley 
286676b2cf59SMatthew Knepley   Input Parameters:
286776b2cf59SMatthew Knepley . snes - The nonlinear solver context
286876b2cf59SMatthew Knepley . func - The function
286976b2cf59SMatthew Knepley 
287076b2cf59SMatthew Knepley   Calling sequence of func:
2871b5d30489SBarry Smith . func (SNES snes, PetscInt step);
287276b2cf59SMatthew Knepley 
287376b2cf59SMatthew Knepley . step - The current step of the iteration
287476b2cf59SMatthew Knepley 
2875fe97e370SBarry Smith   Level: advanced
2876fe97e370SBarry Smith 
2877fe97e370SBarry 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()
2878fe97e370SBarry Smith         This is not used by most users.
287976b2cf59SMatthew Knepley 
288076b2cf59SMatthew Knepley .keywords: SNES, update
2881b5d30489SBarry Smith 
288285385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve()
288376b2cf59SMatthew Knepley @*/
28847087cfbeSBarry Smith PetscErrorCode  SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
288576b2cf59SMatthew Knepley {
288676b2cf59SMatthew Knepley   PetscFunctionBegin;
28870700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID,1);
2888e7788613SBarry Smith   snes->ops->update = func;
288976b2cf59SMatthew Knepley   PetscFunctionReturn(0);
289076b2cf59SMatthew Knepley }
289176b2cf59SMatthew Knepley 
2892e74ef692SMatthew Knepley #undef __FUNCT__
2893e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate"
289476b2cf59SMatthew Knepley /*@
289576b2cf59SMatthew Knepley   SNESDefaultUpdate - The default update function which does nothing.
289676b2cf59SMatthew Knepley 
289776b2cf59SMatthew Knepley   Not collective
289876b2cf59SMatthew Knepley 
289976b2cf59SMatthew Knepley   Input Parameters:
290076b2cf59SMatthew Knepley . snes - The nonlinear solver context
290176b2cf59SMatthew Knepley . step - The current step of the iteration
290276b2cf59SMatthew Knepley 
2903205452f4SMatthew Knepley   Level: intermediate
2904205452f4SMatthew Knepley 
290576b2cf59SMatthew Knepley .keywords: SNES, update
2906a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC()
290776b2cf59SMatthew Knepley @*/
29087087cfbeSBarry Smith PetscErrorCode  SNESDefaultUpdate(SNES snes, PetscInt step)
290976b2cf59SMatthew Knepley {
291076b2cf59SMatthew Knepley   PetscFunctionBegin;
291176b2cf59SMatthew Knepley   PetscFunctionReturn(0);
291276b2cf59SMatthew Knepley }
291376b2cf59SMatthew Knepley 
29144a2ae208SSatish Balay #undef __FUNCT__
29154a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private"
29169b94acceSBarry Smith /*
29179b94acceSBarry Smith    SNESScaleStep_Private - Scales a step so that its length is less than the
29189b94acceSBarry Smith    positive parameter delta.
29199b94acceSBarry Smith 
29209b94acceSBarry Smith     Input Parameters:
2921c7afd0dbSLois Curfman McInnes +   snes - the SNES context
29229b94acceSBarry Smith .   y - approximate solution of linear system
29239b94acceSBarry Smith .   fnorm - 2-norm of current function
2924c7afd0dbSLois Curfman McInnes -   delta - trust region size
29259b94acceSBarry Smith 
29269b94acceSBarry Smith     Output Parameters:
2927c7afd0dbSLois Curfman McInnes +   gpnorm - predicted function norm at the new point, assuming local
29289b94acceSBarry Smith     linearization.  The value is zero if the step lies within the trust
29299b94acceSBarry Smith     region, and exceeds zero otherwise.
2930c7afd0dbSLois Curfman McInnes -   ynorm - 2-norm of the step
29319b94acceSBarry Smith 
29329b94acceSBarry Smith     Note:
29334b27c08aSLois Curfman McInnes     For non-trust region methods such as SNESLS, the parameter delta
29349b94acceSBarry Smith     is set to be the maximum allowable step size.
29359b94acceSBarry Smith 
29369b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step
29379b94acceSBarry Smith */
2938dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
29399b94acceSBarry Smith {
2940064f8208SBarry Smith   PetscReal      nrm;
2941ea709b57SSatish Balay   PetscScalar    cnorm;
2942dfbe8321SBarry Smith   PetscErrorCode ierr;
29433a40ed3dSBarry Smith 
29443a40ed3dSBarry Smith   PetscFunctionBegin;
29450700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
29460700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
2947c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,2);
2948184914b5SBarry Smith 
2949064f8208SBarry Smith   ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr);
2950064f8208SBarry Smith   if (nrm > *delta) {
2951064f8208SBarry Smith      nrm = *delta/nrm;
2952064f8208SBarry Smith      *gpnorm = (1.0 - nrm)*(*fnorm);
2953064f8208SBarry Smith      cnorm = nrm;
29542dcb1b2aSMatthew Knepley      ierr = VecScale(y,cnorm);CHKERRQ(ierr);
29559b94acceSBarry Smith      *ynorm = *delta;
29569b94acceSBarry Smith   } else {
29579b94acceSBarry Smith      *gpnorm = 0.0;
2958064f8208SBarry Smith      *ynorm = nrm;
29599b94acceSBarry Smith   }
29603a40ed3dSBarry Smith   PetscFunctionReturn(0);
29619b94acceSBarry Smith }
29629b94acceSBarry Smith 
29634a2ae208SSatish Balay #undef __FUNCT__
29644a2ae208SSatish Balay #define __FUNCT__ "SNESSolve"
29656ce558aeSBarry Smith /*@C
2966f69a0ea3SMatthew Knepley    SNESSolve - Solves a nonlinear system F(x) = b.
2967f69a0ea3SMatthew Knepley    Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
29689b94acceSBarry Smith 
2969c7afd0dbSLois Curfman McInnes    Collective on SNES
2970c7afd0dbSLois Curfman McInnes 
2971b2002411SLois Curfman McInnes    Input Parameters:
2972c7afd0dbSLois Curfman McInnes +  snes - the SNES context
29733cebf274SJed Brown .  b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero.
297485385478SLisandro Dalcin -  x - the solution vector.
29759b94acceSBarry Smith 
2976b2002411SLois Curfman McInnes    Notes:
29778ddd3da0SLois Curfman McInnes    The user should initialize the vector,x, with the initial guess
29788ddd3da0SLois Curfman McInnes    for the nonlinear solve prior to calling SNESSolve.  In particular,
29798ddd3da0SLois Curfman McInnes    to employ an initial guess of zero, the user should explicitly set
29808ddd3da0SLois Curfman McInnes    this vector to zero by calling VecSet().
29818ddd3da0SLois Curfman McInnes 
298236851e7fSLois Curfman McInnes    Level: beginner
298336851e7fSLois Curfman McInnes 
29849b94acceSBarry Smith .keywords: SNES, nonlinear, solve
29859b94acceSBarry Smith 
2986c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution()
29879b94acceSBarry Smith @*/
29887087cfbeSBarry Smith PetscErrorCode  SNESSolve(SNES snes,Vec b,Vec x)
29899b94acceSBarry Smith {
2990dfbe8321SBarry Smith   PetscErrorCode ierr;
2991ace3abfcSBarry Smith   PetscBool      flg;
2992eabae89aSBarry Smith   char           filename[PETSC_MAX_PATH_LEN];
2993eabae89aSBarry Smith   PetscViewer    viewer;
2994efd51863SBarry Smith   PetscInt       grid;
2995052efed2SBarry Smith 
29963a40ed3dSBarry Smith   PetscFunctionBegin;
29970700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
29980700a824SBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
2999f69a0ea3SMatthew Knepley   PetscCheckSameComm(snes,1,x,3);
30000700a824SBarry Smith   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2);
300185385478SLisandro Dalcin   if (b) PetscCheckSameComm(snes,1,b,2);
300285385478SLisandro Dalcin 
3003a8248277SBarry Smith   for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);}
3004efd51863SBarry Smith   for (grid=0; grid<snes->gridsequence+1; grid++) {
3005efd51863SBarry Smith 
300685385478SLisandro Dalcin     /* set solution vector */
3007efd51863SBarry Smith     if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);}
30086bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
300985385478SLisandro Dalcin     snes->vec_sol = x;
301085385478SLisandro Dalcin     /* set afine vector if provided */
301185385478SLisandro Dalcin     if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); }
30126bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
301385385478SLisandro Dalcin     snes->vec_rhs = b;
301485385478SLisandro Dalcin 
301570e92668SMatthew Knepley     ierr = SNESSetUp(snes);CHKERRQ(ierr);
30163f149594SLisandro Dalcin 
3017d25893d9SBarry Smith     if (!grid && snes->ops->computeinitialguess) {
3018d25893d9SBarry Smith       ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr);
3019d25893d9SBarry Smith     }
3020d25893d9SBarry Smith 
3021abc0a331SBarry Smith     if (snes->conv_hist_reset) snes->conv_hist_len = 0;
302250ffb88aSMatthew Knepley     snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;
3023d5e45103SBarry Smith 
30243f149594SLisandro Dalcin     ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
30254936397dSBarry Smith     ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr);
302685385478SLisandro Dalcin     ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
30274936397dSBarry Smith     if (snes->domainerror){
30284936397dSBarry Smith       snes->reason      = SNES_DIVERGED_FUNCTION_DOMAIN;
30294936397dSBarry Smith       snes->domainerror = PETSC_FALSE;
30304936397dSBarry Smith     }
303117186662SBarry Smith     if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
30323f149594SLisandro Dalcin 
30337adad957SLisandro Dalcin     ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
3034eabae89aSBarry Smith     if (flg && !PetscPreLoadingOn) {
30357adad957SLisandro Dalcin       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr);
3036eabae89aSBarry Smith       ierr = SNESView(snes,viewer);CHKERRQ(ierr);
30376bf464f9SBarry Smith       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
3038eabae89aSBarry Smith     }
3039eabae89aSBarry Smith 
304090d69ab7SBarry Smith     flg  = PETSC_FALSE;
3041acfcf0e5SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr);
3042da9b6338SBarry Smith     if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); }
30435968eb51SBarry Smith     if (snes->printreason) {
3044a8248277SBarry Smith       ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
30455968eb51SBarry Smith       if (snes->reason > 0) {
3046a8248277SBarry Smith         ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),"Nonlinear solve converged due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr);
30475968eb51SBarry Smith       } else {
3048a8248277SBarry Smith         ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),"Nonlinear solve did not converge due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr);
30495968eb51SBarry Smith       }
3050a8248277SBarry Smith       ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
30515968eb51SBarry Smith     }
30525968eb51SBarry Smith 
30538501fc72SJed Brown     flg = PETSC_FALSE;
30548501fc72SJed Brown     ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
30558501fc72SJed Brown     if (flg) {
30568501fc72SJed Brown       PetscViewer viewer;
30578501fc72SJed Brown       ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr);
30588501fc72SJed Brown       ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr);
30598501fc72SJed Brown       ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr);
30608501fc72SJed Brown       ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr);
30618501fc72SJed Brown       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
30628501fc72SJed Brown     }
30638501fc72SJed Brown 
3064e113a28aSBarry Smith     if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged");
3065efd51863SBarry Smith     if (grid <  snes->gridsequence) {
3066efd51863SBarry Smith       DM  fine;
3067efd51863SBarry Smith       Vec xnew;
3068efd51863SBarry Smith       Mat interp;
3069efd51863SBarry Smith 
3070efd51863SBarry Smith       ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr);
3071e727c939SJed Brown       ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr);
3072efd51863SBarry Smith       ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr);
3073efd51863SBarry Smith       ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr);
3074efd51863SBarry Smith       ierr = MatDestroy(&interp);CHKERRQ(ierr);
3075efd51863SBarry Smith       x    = xnew;
3076efd51863SBarry Smith 
3077efd51863SBarry Smith       ierr = SNESReset(snes);CHKERRQ(ierr);
3078efd51863SBarry Smith       ierr = SNESSetDM(snes,fine);CHKERRQ(ierr);
3079efd51863SBarry Smith       ierr = DMDestroy(&fine);CHKERRQ(ierr);
3080a8248277SBarry Smith       ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);
3081efd51863SBarry Smith     }
3082efd51863SBarry Smith   }
30833a40ed3dSBarry Smith   PetscFunctionReturn(0);
30849b94acceSBarry Smith }
30859b94acceSBarry Smith 
30869b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */
30879b94acceSBarry Smith 
30884a2ae208SSatish Balay #undef __FUNCT__
30894a2ae208SSatish Balay #define __FUNCT__ "SNESSetType"
309082bf6240SBarry Smith /*@C
30914b0e389bSBarry Smith    SNESSetType - Sets the method for the nonlinear solver.
30929b94acceSBarry Smith 
3093fee21e36SBarry Smith    Collective on SNES
3094fee21e36SBarry Smith 
3095c7afd0dbSLois Curfman McInnes    Input Parameters:
3096c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3097454a90a3SBarry Smith -  type - a known method
3098c7afd0dbSLois Curfman McInnes 
3099c7afd0dbSLois Curfman McInnes    Options Database Key:
3100454a90a3SBarry Smith .  -snes_type <type> - Sets the method; use -help for a list
3101c7afd0dbSLois Curfman McInnes    of available methods (for instance, ls or tr)
3102ae12b187SLois Curfman McInnes 
31039b94acceSBarry Smith    Notes:
3104e090d566SSatish Balay    See "petsc/include/petscsnes.h" for available methods (for instance)
31054b27c08aSLois Curfman McInnes +    SNESLS - Newton's method with line search
3106c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
31074b27c08aSLois Curfman McInnes .    SNESTR - Newton's method with trust region
3108c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
31099b94acceSBarry Smith 
3110ae12b187SLois Curfman McInnes   Normally, it is best to use the SNESSetFromOptions() command and then
3111ae12b187SLois Curfman McInnes   set the SNES solver type from the options database rather than by using
3112ae12b187SLois Curfman McInnes   this routine.  Using the options database provides the user with
3113ae12b187SLois Curfman McInnes   maximum flexibility in evaluating the many nonlinear solvers.
3114ae12b187SLois Curfman McInnes   The SNESSetType() routine is provided for those situations where it
3115ae12b187SLois Curfman McInnes   is necessary to set the nonlinear solver independently of the command
3116ae12b187SLois Curfman McInnes   line or options database.  This might be the case, for example, when
3117ae12b187SLois Curfman McInnes   the choice of solver changes during the execution of the program,
3118ae12b187SLois Curfman McInnes   and the user's application is taking responsibility for choosing the
3119b0a32e0cSBarry Smith   appropriate method.
312036851e7fSLois Curfman McInnes 
312136851e7fSLois Curfman McInnes   Level: intermediate
3122a703fe33SLois Curfman McInnes 
3123454a90a3SBarry Smith .keywords: SNES, set, type
3124435da068SBarry Smith 
3125435da068SBarry Smith .seealso: SNESType, SNESCreate()
3126435da068SBarry Smith 
31279b94acceSBarry Smith @*/
31287087cfbeSBarry Smith PetscErrorCode  SNESSetType(SNES snes,const SNESType type)
31299b94acceSBarry Smith {
3130dfbe8321SBarry Smith   PetscErrorCode ierr,(*r)(SNES);
3131ace3abfcSBarry Smith   PetscBool      match;
31323a40ed3dSBarry Smith 
31333a40ed3dSBarry Smith   PetscFunctionBegin;
31340700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
31354482741eSBarry Smith   PetscValidCharPointer(type,2);
313682bf6240SBarry Smith 
31376831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr);
31380f5bd95cSBarry Smith   if (match) PetscFunctionReturn(0);
313992ff6ae8SBarry Smith 
31404b91b6eaSBarry Smith   ierr =  PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr);
3141e32f2f54SBarry Smith   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
314275396ef9SLisandro Dalcin   /* Destroy the previous private SNES context */
314375396ef9SLisandro Dalcin   if (snes->ops->destroy) { ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); }
314475396ef9SLisandro Dalcin   /* Reinitialize function pointers in SNESOps structure */
314575396ef9SLisandro Dalcin   snes->ops->setup          = 0;
314675396ef9SLisandro Dalcin   snes->ops->solve          = 0;
314775396ef9SLisandro Dalcin   snes->ops->view           = 0;
314875396ef9SLisandro Dalcin   snes->ops->setfromoptions = 0;
314975396ef9SLisandro Dalcin   snes->ops->destroy        = 0;
315075396ef9SLisandro Dalcin   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
315175396ef9SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
3152454a90a3SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr);
315303bfa161SLisandro Dalcin   ierr = (*r)(snes);CHKERRQ(ierr);
31549fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS)
31559fb22e1aSBarry Smith   if (PetscAMSPublishAll) {
31569fb22e1aSBarry Smith     ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr);
31579fb22e1aSBarry Smith   }
31589fb22e1aSBarry Smith #endif
31593a40ed3dSBarry Smith   PetscFunctionReturn(0);
31609b94acceSBarry Smith }
31619b94acceSBarry Smith 
3162a847f771SSatish Balay 
31639b94acceSBarry Smith /* --------------------------------------------------------------------- */
31644a2ae208SSatish Balay #undef __FUNCT__
31654a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy"
316652baeb72SSatish Balay /*@
31679b94acceSBarry Smith    SNESRegisterDestroy - Frees the list of nonlinear solvers that were
3168f1af5d2fSBarry Smith    registered by SNESRegisterDynamic().
31699b94acceSBarry Smith 
3170fee21e36SBarry Smith    Not Collective
3171fee21e36SBarry Smith 
317236851e7fSLois Curfman McInnes    Level: advanced
317336851e7fSLois Curfman McInnes 
31749b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy
31759b94acceSBarry Smith 
31769b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll()
31779b94acceSBarry Smith @*/
31787087cfbeSBarry Smith PetscErrorCode  SNESRegisterDestroy(void)
31799b94acceSBarry Smith {
3180dfbe8321SBarry Smith   PetscErrorCode ierr;
318182bf6240SBarry Smith 
31823a40ed3dSBarry Smith   PetscFunctionBegin;
31831441b1d3SBarry Smith   ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr);
31844c49b128SBarry Smith   SNESRegisterAllCalled = PETSC_FALSE;
31853a40ed3dSBarry Smith   PetscFunctionReturn(0);
31869b94acceSBarry Smith }
31879b94acceSBarry Smith 
31884a2ae208SSatish Balay #undef __FUNCT__
31894a2ae208SSatish Balay #define __FUNCT__ "SNESGetType"
31909b94acceSBarry Smith /*@C
31919a28b0a6SLois Curfman McInnes    SNESGetType - Gets the SNES method type and name (as a string).
31929b94acceSBarry Smith 
3193c7afd0dbSLois Curfman McInnes    Not Collective
3194c7afd0dbSLois Curfman McInnes 
31959b94acceSBarry Smith    Input Parameter:
31964b0e389bSBarry Smith .  snes - nonlinear solver context
31979b94acceSBarry Smith 
31989b94acceSBarry Smith    Output Parameter:
31993a7fca6bSBarry Smith .  type - SNES method (a character string)
32009b94acceSBarry Smith 
320136851e7fSLois Curfman McInnes    Level: intermediate
320236851e7fSLois Curfman McInnes 
3203454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name
32049b94acceSBarry Smith @*/
32057087cfbeSBarry Smith PetscErrorCode  SNESGetType(SNES snes,const SNESType *type)
32069b94acceSBarry Smith {
32073a40ed3dSBarry Smith   PetscFunctionBegin;
32080700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
32094482741eSBarry Smith   PetscValidPointer(type,2);
32107adad957SLisandro Dalcin   *type = ((PetscObject)snes)->type_name;
32113a40ed3dSBarry Smith   PetscFunctionReturn(0);
32129b94acceSBarry Smith }
32139b94acceSBarry Smith 
32144a2ae208SSatish Balay #undef __FUNCT__
32154a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution"
321652baeb72SSatish Balay /*@
32179b94acceSBarry Smith    SNESGetSolution - Returns the vector where the approximate solution is
3218c0df2a02SJed Brown    stored. This is the fine grid solution when using SNESSetGridSequence().
32199b94acceSBarry Smith 
3220c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3221c7afd0dbSLois Curfman McInnes 
32229b94acceSBarry Smith    Input Parameter:
32239b94acceSBarry Smith .  snes - the SNES context
32249b94acceSBarry Smith 
32259b94acceSBarry Smith    Output Parameter:
32269b94acceSBarry Smith .  x - the solution
32279b94acceSBarry Smith 
322870e92668SMatthew Knepley    Level: intermediate
322936851e7fSLois Curfman McInnes 
32309b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution
32319b94acceSBarry Smith 
323285385478SLisandro Dalcin .seealso:  SNESGetSolutionUpdate(), SNESGetFunction()
32339b94acceSBarry Smith @*/
32347087cfbeSBarry Smith PetscErrorCode  SNESGetSolution(SNES snes,Vec *x)
32359b94acceSBarry Smith {
32363a40ed3dSBarry Smith   PetscFunctionBegin;
32370700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
32384482741eSBarry Smith   PetscValidPointer(x,2);
323985385478SLisandro Dalcin   *x = snes->vec_sol;
324070e92668SMatthew Knepley   PetscFunctionReturn(0);
324170e92668SMatthew Knepley }
324270e92668SMatthew Knepley 
324370e92668SMatthew Knepley #undef __FUNCT__
32444a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate"
324552baeb72SSatish Balay /*@
32469b94acceSBarry Smith    SNESGetSolutionUpdate - Returns the vector where the solution update is
32479b94acceSBarry Smith    stored.
32489b94acceSBarry Smith 
3249c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3250c7afd0dbSLois Curfman McInnes 
32519b94acceSBarry Smith    Input Parameter:
32529b94acceSBarry Smith .  snes - the SNES context
32539b94acceSBarry Smith 
32549b94acceSBarry Smith    Output Parameter:
32559b94acceSBarry Smith .  x - the solution update
32569b94acceSBarry Smith 
325736851e7fSLois Curfman McInnes    Level: advanced
325836851e7fSLois Curfman McInnes 
32599b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update
32609b94acceSBarry Smith 
326185385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction()
32629b94acceSBarry Smith @*/
32637087cfbeSBarry Smith PetscErrorCode  SNESGetSolutionUpdate(SNES snes,Vec *x)
32649b94acceSBarry Smith {
32653a40ed3dSBarry Smith   PetscFunctionBegin;
32660700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
32674482741eSBarry Smith   PetscValidPointer(x,2);
326885385478SLisandro Dalcin   *x = snes->vec_sol_update;
32693a40ed3dSBarry Smith   PetscFunctionReturn(0);
32709b94acceSBarry Smith }
32719b94acceSBarry Smith 
32724a2ae208SSatish Balay #undef __FUNCT__
32734a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction"
32749b94acceSBarry Smith /*@C
32753638b69dSLois Curfman McInnes    SNESGetFunction - Returns the vector where the function is stored.
32769b94acceSBarry Smith 
3277c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3278c7afd0dbSLois Curfman McInnes 
32799b94acceSBarry Smith    Input Parameter:
32809b94acceSBarry Smith .  snes - the SNES context
32819b94acceSBarry Smith 
32829b94acceSBarry Smith    Output Parameter:
32837bf4e008SBarry Smith +  r - the function (or PETSC_NULL)
328470e92668SMatthew Knepley .  func - the function (or PETSC_NULL)
328570e92668SMatthew Knepley -  ctx - the function context (or PETSC_NULL)
32869b94acceSBarry Smith 
328736851e7fSLois Curfman McInnes    Level: advanced
328836851e7fSLois Curfman McInnes 
3289a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function
32909b94acceSBarry Smith 
32914b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution()
32929b94acceSBarry Smith @*/
32937087cfbeSBarry Smith PetscErrorCode  SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
32949b94acceSBarry Smith {
32953a40ed3dSBarry Smith   PetscFunctionBegin;
32960700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
329785385478SLisandro Dalcin   if (r)    *r    = snes->vec_func;
3298e7788613SBarry Smith   if (func) *func = snes->ops->computefunction;
329970e92668SMatthew Knepley   if (ctx)  *ctx  = snes->funP;
33003a40ed3dSBarry Smith   PetscFunctionReturn(0);
33019b94acceSBarry Smith }
33029b94acceSBarry Smith 
3303c79ef259SPeter Brune /*@C
3304c79ef259SPeter Brune    SNESGetGS - Returns the GS function and context.
3305c79ef259SPeter Brune 
3306c79ef259SPeter Brune    Input Parameter:
3307c79ef259SPeter Brune .  snes - the SNES context
3308c79ef259SPeter Brune 
3309c79ef259SPeter Brune    Output Parameter:
3310c79ef259SPeter Brune +  gsfunc - the function (or PETSC_NULL)
3311c79ef259SPeter Brune -  ctx    - the function context (or PETSC_NULL)
3312c79ef259SPeter Brune 
3313c79ef259SPeter Brune    Level: advanced
3314c79ef259SPeter Brune 
3315c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function
3316c79ef259SPeter Brune 
3317c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction()
3318c79ef259SPeter Brune @*/
3319c79ef259SPeter Brune 
33204a2ae208SSatish Balay #undef __FUNCT__
3321646217ecSPeter Brune #define __FUNCT__ "SNESGetGS"
3322646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx)
3323646217ecSPeter Brune {
3324646217ecSPeter Brune   PetscFunctionBegin;
3325646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3326646217ecSPeter Brune   if (func) *func = snes->ops->computegs;
3327646217ecSPeter Brune   if (ctx)  *ctx  = snes->funP;
3328646217ecSPeter Brune   PetscFunctionReturn(0);
3329646217ecSPeter Brune }
3330646217ecSPeter Brune 
33314a2ae208SSatish Balay #undef __FUNCT__
33324a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix"
33333c7409f5SSatish Balay /*@C
33343c7409f5SSatish Balay    SNESSetOptionsPrefix - Sets the prefix used for searching for all
3335d850072dSLois Curfman McInnes    SNES options in the database.
33363c7409f5SSatish Balay 
33373f9fe445SBarry Smith    Logically Collective on SNES
3338fee21e36SBarry Smith 
3339c7afd0dbSLois Curfman McInnes    Input Parameter:
3340c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3341c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3342c7afd0dbSLois Curfman McInnes 
3343d850072dSLois Curfman McInnes    Notes:
3344a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
3345c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
3346d850072dSLois Curfman McInnes 
334736851e7fSLois Curfman McInnes    Level: advanced
334836851e7fSLois Curfman McInnes 
33493c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database
3350a86d99e1SLois Curfman McInnes 
3351a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions()
33523c7409f5SSatish Balay @*/
33537087cfbeSBarry Smith PetscErrorCode  SNESSetOptionsPrefix(SNES snes,const char prefix[])
33543c7409f5SSatish Balay {
3355dfbe8321SBarry Smith   PetscErrorCode ierr;
33563c7409f5SSatish Balay 
33573a40ed3dSBarry Smith   PetscFunctionBegin;
33580700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3359639f9d9dSBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
33601cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
336194b7f48cSBarry Smith   ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
33623a40ed3dSBarry Smith   PetscFunctionReturn(0);
33633c7409f5SSatish Balay }
33643c7409f5SSatish Balay 
33654a2ae208SSatish Balay #undef __FUNCT__
33664a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix"
33673c7409f5SSatish Balay /*@C
3368f525115eSLois Curfman McInnes    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
3369d850072dSLois Curfman McInnes    SNES options in the database.
33703c7409f5SSatish Balay 
33713f9fe445SBarry Smith    Logically Collective on SNES
3372fee21e36SBarry Smith 
3373c7afd0dbSLois Curfman McInnes    Input Parameters:
3374c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3375c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3376c7afd0dbSLois Curfman McInnes 
3377d850072dSLois Curfman McInnes    Notes:
3378a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
3379c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
3380d850072dSLois Curfman McInnes 
338136851e7fSLois Curfman McInnes    Level: advanced
338236851e7fSLois Curfman McInnes 
33833c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database
3384a86d99e1SLois Curfman McInnes 
3385a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix()
33863c7409f5SSatish Balay @*/
33877087cfbeSBarry Smith PetscErrorCode  SNESAppendOptionsPrefix(SNES snes,const char prefix[])
33883c7409f5SSatish Balay {
3389dfbe8321SBarry Smith   PetscErrorCode ierr;
33903c7409f5SSatish Balay 
33913a40ed3dSBarry Smith   PetscFunctionBegin;
33920700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3393639f9d9dSBarry Smith   ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
33941cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
339594b7f48cSBarry Smith   ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
33963a40ed3dSBarry Smith   PetscFunctionReturn(0);
33973c7409f5SSatish Balay }
33983c7409f5SSatish Balay 
33994a2ae208SSatish Balay #undef __FUNCT__
34004a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix"
34019ab63eb5SSatish Balay /*@C
34023c7409f5SSatish Balay    SNESGetOptionsPrefix - Sets the prefix used for searching for all
34033c7409f5SSatish Balay    SNES options in the database.
34043c7409f5SSatish Balay 
3405c7afd0dbSLois Curfman McInnes    Not Collective
3406c7afd0dbSLois Curfman McInnes 
34073c7409f5SSatish Balay    Input Parameter:
34083c7409f5SSatish Balay .  snes - the SNES context
34093c7409f5SSatish Balay 
34103c7409f5SSatish Balay    Output Parameter:
34113c7409f5SSatish Balay .  prefix - pointer to the prefix string used
34123c7409f5SSatish Balay 
34134ef407dbSRichard Tran Mills    Notes: On the fortran side, the user should pass in a string 'prefix' of
34149ab63eb5SSatish Balay    sufficient length to hold the prefix.
34159ab63eb5SSatish Balay 
341636851e7fSLois Curfman McInnes    Level: advanced
341736851e7fSLois Curfman McInnes 
34183c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database
3419a86d99e1SLois Curfman McInnes 
3420a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix()
34213c7409f5SSatish Balay @*/
34227087cfbeSBarry Smith PetscErrorCode  SNESGetOptionsPrefix(SNES snes,const char *prefix[])
34233c7409f5SSatish Balay {
3424dfbe8321SBarry Smith   PetscErrorCode ierr;
34253c7409f5SSatish Balay 
34263a40ed3dSBarry Smith   PetscFunctionBegin;
34270700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3428639f9d9dSBarry Smith   ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
34293a40ed3dSBarry Smith   PetscFunctionReturn(0);
34303c7409f5SSatish Balay }
34313c7409f5SSatish Balay 
3432b2002411SLois Curfman McInnes 
34334a2ae208SSatish Balay #undef __FUNCT__
34344a2ae208SSatish Balay #define __FUNCT__ "SNESRegister"
34353cea93caSBarry Smith /*@C
34363cea93caSBarry Smith   SNESRegister - See SNESRegisterDynamic()
34373cea93caSBarry Smith 
34387f6c08e0SMatthew Knepley   Level: advanced
34393cea93caSBarry Smith @*/
34407087cfbeSBarry Smith PetscErrorCode  SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES))
3441b2002411SLois Curfman McInnes {
3442e2d1d2b7SBarry Smith   char           fullname[PETSC_MAX_PATH_LEN];
3443dfbe8321SBarry Smith   PetscErrorCode ierr;
3444b2002411SLois Curfman McInnes 
3445b2002411SLois Curfman McInnes   PetscFunctionBegin;
3446b0a32e0cSBarry Smith   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
3447c134de8dSSatish Balay   ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
3448b2002411SLois Curfman McInnes   PetscFunctionReturn(0);
3449b2002411SLois Curfman McInnes }
3450da9b6338SBarry Smith 
3451da9b6338SBarry Smith #undef __FUNCT__
3452da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin"
34537087cfbeSBarry Smith PetscErrorCode  SNESTestLocalMin(SNES snes)
3454da9b6338SBarry Smith {
3455dfbe8321SBarry Smith   PetscErrorCode ierr;
345677431f27SBarry Smith   PetscInt       N,i,j;
3457da9b6338SBarry Smith   Vec            u,uh,fh;
3458da9b6338SBarry Smith   PetscScalar    value;
3459da9b6338SBarry Smith   PetscReal      norm;
3460da9b6338SBarry Smith 
3461da9b6338SBarry Smith   PetscFunctionBegin;
3462da9b6338SBarry Smith   ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr);
3463da9b6338SBarry Smith   ierr = VecDuplicate(u,&uh);CHKERRQ(ierr);
3464da9b6338SBarry Smith   ierr = VecDuplicate(u,&fh);CHKERRQ(ierr);
3465da9b6338SBarry Smith 
3466da9b6338SBarry Smith   /* currently only works for sequential */
3467da9b6338SBarry Smith   ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");
3468da9b6338SBarry Smith   ierr = VecGetSize(u,&N);CHKERRQ(ierr);
3469da9b6338SBarry Smith   for (i=0; i<N; i++) {
3470da9b6338SBarry Smith     ierr = VecCopy(u,uh);CHKERRQ(ierr);
347177431f27SBarry Smith     ierr  = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr);
3472da9b6338SBarry Smith     for (j=-10; j<11; j++) {
3473ccae9161SBarry Smith       value = PetscSign(j)*exp(PetscAbs(j)-10.0);
3474da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
34753ab0aad5SBarry Smith       ierr  = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr);
3476da9b6338SBarry Smith       ierr  = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr);
347777431f27SBarry Smith       ierr  = PetscPrintf(PETSC_COMM_WORLD,"       j norm %D %18.16e\n",j,norm);CHKERRQ(ierr);
3478da9b6338SBarry Smith       value = -value;
3479da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
3480da9b6338SBarry Smith     }
3481da9b6338SBarry Smith   }
34826bf464f9SBarry Smith   ierr = VecDestroy(&uh);CHKERRQ(ierr);
34836bf464f9SBarry Smith   ierr = VecDestroy(&fh);CHKERRQ(ierr);
3484da9b6338SBarry Smith   PetscFunctionReturn(0);
3485da9b6338SBarry Smith }
348671f87433Sdalcinl 
348771f87433Sdalcinl #undef __FUNCT__
3488fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW"
348971f87433Sdalcinl /*@
3490fa9f3622SBarry Smith    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
349171f87433Sdalcinl    computing relative tolerance for linear solvers within an inexact
349271f87433Sdalcinl    Newton method.
349371f87433Sdalcinl 
34943f9fe445SBarry Smith    Logically Collective on SNES
349571f87433Sdalcinl 
349671f87433Sdalcinl    Input Parameters:
349771f87433Sdalcinl +  snes - SNES context
349871f87433Sdalcinl -  flag - PETSC_TRUE or PETSC_FALSE
349971f87433Sdalcinl 
350064ba62caSBarry Smith     Options Database:
350164ba62caSBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
350264ba62caSBarry Smith .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
350364ba62caSBarry Smith .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
350464ba62caSBarry Smith .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
350564ba62caSBarry Smith .  -snes_ksp_ew_gamma <gamma> - Sets gamma
350664ba62caSBarry Smith .  -snes_ksp_ew_alpha <alpha> - Sets alpha
350764ba62caSBarry Smith .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
350864ba62caSBarry Smith -  -snes_ksp_ew_threshold <threshold> - Sets threshold
350964ba62caSBarry Smith 
351071f87433Sdalcinl    Notes:
351171f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
351271f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
351371f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
351471f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
351571f87433Sdalcinl    solver.
351671f87433Sdalcinl 
351771f87433Sdalcinl    Level: advanced
351871f87433Sdalcinl 
351971f87433Sdalcinl    Reference:
352071f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
352171f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
352271f87433Sdalcinl 
352371f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
352471f87433Sdalcinl 
3525fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
352671f87433Sdalcinl @*/
35277087cfbeSBarry Smith PetscErrorCode  SNESKSPSetUseEW(SNES snes,PetscBool  flag)
352871f87433Sdalcinl {
352971f87433Sdalcinl   PetscFunctionBegin;
35300700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3531acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flag,2);
353271f87433Sdalcinl   snes->ksp_ewconv = flag;
353371f87433Sdalcinl   PetscFunctionReturn(0);
353471f87433Sdalcinl }
353571f87433Sdalcinl 
353671f87433Sdalcinl #undef __FUNCT__
3537fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW"
353871f87433Sdalcinl /*@
3539fa9f3622SBarry Smith    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
354071f87433Sdalcinl    for computing relative tolerance for linear solvers within an
354171f87433Sdalcinl    inexact Newton method.
354271f87433Sdalcinl 
354371f87433Sdalcinl    Not Collective
354471f87433Sdalcinl 
354571f87433Sdalcinl    Input Parameter:
354671f87433Sdalcinl .  snes - SNES context
354771f87433Sdalcinl 
354871f87433Sdalcinl    Output Parameter:
354971f87433Sdalcinl .  flag - PETSC_TRUE or PETSC_FALSE
355071f87433Sdalcinl 
355171f87433Sdalcinl    Notes:
355271f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
355371f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
355471f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
355571f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
355671f87433Sdalcinl    solver.
355771f87433Sdalcinl 
355871f87433Sdalcinl    Level: advanced
355971f87433Sdalcinl 
356071f87433Sdalcinl    Reference:
356171f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
356271f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
356371f87433Sdalcinl 
356471f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
356571f87433Sdalcinl 
3566fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
356771f87433Sdalcinl @*/
35687087cfbeSBarry Smith PetscErrorCode  SNESKSPGetUseEW(SNES snes, PetscBool  *flag)
356971f87433Sdalcinl {
357071f87433Sdalcinl   PetscFunctionBegin;
35710700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
357271f87433Sdalcinl   PetscValidPointer(flag,2);
357371f87433Sdalcinl   *flag = snes->ksp_ewconv;
357471f87433Sdalcinl   PetscFunctionReturn(0);
357571f87433Sdalcinl }
357671f87433Sdalcinl 
357771f87433Sdalcinl #undef __FUNCT__
3578fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW"
357971f87433Sdalcinl /*@
3580fa9f3622SBarry Smith    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
358171f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
358271f87433Sdalcinl    Newton method.
358371f87433Sdalcinl 
35843f9fe445SBarry Smith    Logically Collective on SNES
358571f87433Sdalcinl 
358671f87433Sdalcinl    Input Parameters:
358771f87433Sdalcinl +    snes - SNES context
358871f87433Sdalcinl .    version - version 1, 2 (default is 2) or 3
358971f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
359071f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
359171f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
359271f87433Sdalcinl              (0 <= gamma2 <= 1)
359371f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
359471f87433Sdalcinl .    alpha2 - power for safeguard
359571f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
359671f87433Sdalcinl 
359771f87433Sdalcinl    Note:
359871f87433Sdalcinl    Version 3 was contributed by Luis Chacon, June 2006.
359971f87433Sdalcinl 
360071f87433Sdalcinl    Use PETSC_DEFAULT to retain the default for any of the parameters.
360171f87433Sdalcinl 
360271f87433Sdalcinl    Level: advanced
360371f87433Sdalcinl 
360471f87433Sdalcinl    Reference:
360571f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
360671f87433Sdalcinl    inexact Newton method", Utah State University Math. Stat. Dept. Res.
360771f87433Sdalcinl    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
360871f87433Sdalcinl 
360971f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
361071f87433Sdalcinl 
3611fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
361271f87433Sdalcinl @*/
36137087cfbeSBarry Smith PetscErrorCode  SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,
361471f87433Sdalcinl 							    PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
361571f87433Sdalcinl {
3616fa9f3622SBarry Smith   SNESKSPEW *kctx;
361771f87433Sdalcinl   PetscFunctionBegin;
36180700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3619fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
3620e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
3621c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,version,2);
3622c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_0,3);
3623c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_max,4);
3624c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,gamma,5);
3625c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha,6);
3626c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha2,7);
3627c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,threshold,8);
362871f87433Sdalcinl 
362971f87433Sdalcinl   if (version != PETSC_DEFAULT)   kctx->version   = version;
363071f87433Sdalcinl   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
363171f87433Sdalcinl   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
363271f87433Sdalcinl   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
363371f87433Sdalcinl   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
363471f87433Sdalcinl   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
363571f87433Sdalcinl   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
363671f87433Sdalcinl 
363771f87433Sdalcinl   if (kctx->version < 1 || kctx->version > 3) {
3638e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version);
363971f87433Sdalcinl   }
364071f87433Sdalcinl   if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
3641e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0);
364271f87433Sdalcinl   }
364371f87433Sdalcinl   if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
3644e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max);
364571f87433Sdalcinl   }
364671f87433Sdalcinl   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
3647e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma);
364871f87433Sdalcinl   }
364971f87433Sdalcinl   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
3650e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha);
365171f87433Sdalcinl   }
365271f87433Sdalcinl   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
3653e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold);
365471f87433Sdalcinl   }
365571f87433Sdalcinl   PetscFunctionReturn(0);
365671f87433Sdalcinl }
365771f87433Sdalcinl 
365871f87433Sdalcinl #undef __FUNCT__
3659fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW"
366071f87433Sdalcinl /*@
3661fa9f3622SBarry Smith    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
366271f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
366371f87433Sdalcinl    Newton method.
366471f87433Sdalcinl 
366571f87433Sdalcinl    Not Collective
366671f87433Sdalcinl 
366771f87433Sdalcinl    Input Parameters:
366871f87433Sdalcinl      snes - SNES context
366971f87433Sdalcinl 
367071f87433Sdalcinl    Output Parameters:
367171f87433Sdalcinl +    version - version 1, 2 (default is 2) or 3
367271f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
367371f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
367471f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
367571f87433Sdalcinl              (0 <= gamma2 <= 1)
367671f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
367771f87433Sdalcinl .    alpha2 - power for safeguard
367871f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
367971f87433Sdalcinl 
368071f87433Sdalcinl    Level: advanced
368171f87433Sdalcinl 
368271f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters
368371f87433Sdalcinl 
3684fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
368571f87433Sdalcinl @*/
36867087cfbeSBarry Smith PetscErrorCode  SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,
368771f87433Sdalcinl 							    PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
368871f87433Sdalcinl {
3689fa9f3622SBarry Smith   SNESKSPEW *kctx;
369071f87433Sdalcinl   PetscFunctionBegin;
36910700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3692fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
3693e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
369471f87433Sdalcinl   if(version)   *version   = kctx->version;
369571f87433Sdalcinl   if(rtol_0)    *rtol_0    = kctx->rtol_0;
369671f87433Sdalcinl   if(rtol_max)  *rtol_max  = kctx->rtol_max;
369771f87433Sdalcinl   if(gamma)     *gamma     = kctx->gamma;
369871f87433Sdalcinl   if(alpha)     *alpha     = kctx->alpha;
369971f87433Sdalcinl   if(alpha2)    *alpha2    = kctx->alpha2;
370071f87433Sdalcinl   if(threshold) *threshold = kctx->threshold;
370171f87433Sdalcinl   PetscFunctionReturn(0);
370271f87433Sdalcinl }
370371f87433Sdalcinl 
370471f87433Sdalcinl #undef __FUNCT__
3705fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve"
3706fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x)
370771f87433Sdalcinl {
370871f87433Sdalcinl   PetscErrorCode ierr;
3709fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
371071f87433Sdalcinl   PetscReal      rtol=PETSC_DEFAULT,stol;
371171f87433Sdalcinl 
371271f87433Sdalcinl   PetscFunctionBegin;
3713e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
371471f87433Sdalcinl   if (!snes->iter) { /* first time in, so use the original user rtol */
371571f87433Sdalcinl     rtol = kctx->rtol_0;
371671f87433Sdalcinl   } else {
371771f87433Sdalcinl     if (kctx->version == 1) {
371871f87433Sdalcinl       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
371971f87433Sdalcinl       if (rtol < 0.0) rtol = -rtol;
372071f87433Sdalcinl       stol = pow(kctx->rtol_last,kctx->alpha2);
372171f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
372271f87433Sdalcinl     } else if (kctx->version == 2) {
372371f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
372471f87433Sdalcinl       stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
372571f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
372671f87433Sdalcinl     } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */
372771f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
372871f87433Sdalcinl       /* safeguard: avoid sharp decrease of rtol */
372971f87433Sdalcinl       stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha);
373071f87433Sdalcinl       stol = PetscMax(rtol,stol);
373171f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
373271f87433Sdalcinl       /* safeguard: avoid oversolving */
373371f87433Sdalcinl       stol = kctx->gamma*(snes->ttol)/snes->norm;
373471f87433Sdalcinl       stol = PetscMax(rtol,stol);
373571f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
3736e32f2f54SBarry Smith     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
373771f87433Sdalcinl   }
373871f87433Sdalcinl   /* safeguard: avoid rtol greater than one */
373971f87433Sdalcinl   rtol = PetscMin(rtol,kctx->rtol_max);
374071f87433Sdalcinl   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
374171f87433Sdalcinl   ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr);
374271f87433Sdalcinl   PetscFunctionReturn(0);
374371f87433Sdalcinl }
374471f87433Sdalcinl 
374571f87433Sdalcinl #undef __FUNCT__
3746fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve"
3747fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x)
374871f87433Sdalcinl {
374971f87433Sdalcinl   PetscErrorCode ierr;
3750fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
375171f87433Sdalcinl   PCSide         pcside;
375271f87433Sdalcinl   Vec            lres;
375371f87433Sdalcinl 
375471f87433Sdalcinl   PetscFunctionBegin;
3755e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
375671f87433Sdalcinl   ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr);
375771f87433Sdalcinl   ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr);
375871f87433Sdalcinl   if (kctx->version == 1) {
3759b037da10SBarry Smith     ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr);
376071f87433Sdalcinl     if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
376171f87433Sdalcinl       /* KSP residual is true linear residual */
376271f87433Sdalcinl       ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr);
376371f87433Sdalcinl     } else {
376471f87433Sdalcinl       /* KSP residual is preconditioned residual */
376571f87433Sdalcinl       /* compute true linear residual norm */
376671f87433Sdalcinl       ierr = VecDuplicate(b,&lres);CHKERRQ(ierr);
376771f87433Sdalcinl       ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr);
376871f87433Sdalcinl       ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr);
376971f87433Sdalcinl       ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr);
37706bf464f9SBarry Smith       ierr = VecDestroy(&lres);CHKERRQ(ierr);
377171f87433Sdalcinl     }
377271f87433Sdalcinl   }
377371f87433Sdalcinl   PetscFunctionReturn(0);
377471f87433Sdalcinl }
377571f87433Sdalcinl 
377671f87433Sdalcinl #undef __FUNCT__
377771f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve"
377871f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x)
377971f87433Sdalcinl {
378071f87433Sdalcinl   PetscErrorCode ierr;
378171f87433Sdalcinl 
378271f87433Sdalcinl   PetscFunctionBegin;
3783fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr);  }
378471f87433Sdalcinl   ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr);
3785fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); }
378671f87433Sdalcinl   PetscFunctionReturn(0);
378771f87433Sdalcinl }
37886c699258SBarry Smith 
37896c699258SBarry Smith #undef __FUNCT__
37906c699258SBarry Smith #define __FUNCT__ "SNESSetDM"
37916c699258SBarry Smith /*@
37926c699258SBarry Smith    SNESSetDM - Sets the DM that may be used by some preconditioners
37936c699258SBarry Smith 
37943f9fe445SBarry Smith    Logically Collective on SNES
37956c699258SBarry Smith 
37966c699258SBarry Smith    Input Parameters:
37976c699258SBarry Smith +  snes - the preconditioner context
37986c699258SBarry Smith -  dm - the dm
37996c699258SBarry Smith 
38006c699258SBarry Smith    Level: intermediate
38016c699258SBarry Smith 
38026c699258SBarry Smith 
38036c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM()
38046c699258SBarry Smith @*/
38057087cfbeSBarry Smith PetscErrorCode  SNESSetDM(SNES snes,DM dm)
38066c699258SBarry Smith {
38076c699258SBarry Smith   PetscErrorCode ierr;
3808345fed2cSBarry Smith   KSP            ksp;
38096c699258SBarry Smith 
38106c699258SBarry Smith   PetscFunctionBegin;
38110700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3812d0660788SBarry Smith   if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);}
38136bf464f9SBarry Smith   ierr = DMDestroy(&snes->dm);CHKERRQ(ierr);
38146c699258SBarry Smith   snes->dm = dm;
3815345fed2cSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
3816345fed2cSBarry Smith   ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr);
3817f22f69f0SBarry Smith   ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr);
38182c155ee1SBarry Smith   if (snes->pc) {
38192c155ee1SBarry Smith     ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr);
38202c155ee1SBarry Smith   }
38216c699258SBarry Smith   PetscFunctionReturn(0);
38226c699258SBarry Smith }
38236c699258SBarry Smith 
38246c699258SBarry Smith #undef __FUNCT__
38256c699258SBarry Smith #define __FUNCT__ "SNESGetDM"
38266c699258SBarry Smith /*@
38276c699258SBarry Smith    SNESGetDM - Gets the DM that may be used by some preconditioners
38286c699258SBarry Smith 
38293f9fe445SBarry Smith    Not Collective but DM obtained is parallel on SNES
38306c699258SBarry Smith 
38316c699258SBarry Smith    Input Parameter:
38326c699258SBarry Smith . snes - the preconditioner context
38336c699258SBarry Smith 
38346c699258SBarry Smith    Output Parameter:
38356c699258SBarry Smith .  dm - the dm
38366c699258SBarry Smith 
38376c699258SBarry Smith    Level: intermediate
38386c699258SBarry Smith 
38396c699258SBarry Smith 
38406c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM()
38416c699258SBarry Smith @*/
38427087cfbeSBarry Smith PetscErrorCode  SNESGetDM(SNES snes,DM *dm)
38436c699258SBarry Smith {
38446c699258SBarry Smith   PetscFunctionBegin;
38450700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
38466c699258SBarry Smith   *dm = snes->dm;
38476c699258SBarry Smith   PetscFunctionReturn(0);
38486c699258SBarry Smith }
38490807856dSBarry Smith 
385031823bd8SMatthew G Knepley #undef __FUNCT__
385131823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC"
385231823bd8SMatthew G Knepley /*@
3853fd4b34e9SJed Brown   SNESSetPC - Sets the nonlinear preconditioner to be used.
385431823bd8SMatthew G Knepley 
385531823bd8SMatthew G Knepley   Collective on SNES
385631823bd8SMatthew G Knepley 
385731823bd8SMatthew G Knepley   Input Parameters:
385831823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate()
385931823bd8SMatthew G Knepley - pc   - the preconditioner object
386031823bd8SMatthew G Knepley 
386131823bd8SMatthew G Knepley   Notes:
386231823bd8SMatthew G Knepley   Use SNESGetPC() to retrieve the preconditioner context (for example,
386331823bd8SMatthew G Knepley   to configure it using the API).
386431823bd8SMatthew G Knepley 
386531823bd8SMatthew G Knepley   Level: developer
386631823bd8SMatthew G Knepley 
386731823bd8SMatthew G Knepley .keywords: SNES, set, precondition
386831823bd8SMatthew G Knepley .seealso: SNESGetPC()
386931823bd8SMatthew G Knepley @*/
387031823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc)
387131823bd8SMatthew G Knepley {
387231823bd8SMatthew G Knepley   PetscErrorCode ierr;
387331823bd8SMatthew G Knepley 
387431823bd8SMatthew G Knepley   PetscFunctionBegin;
387531823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
387631823bd8SMatthew G Knepley   PetscValidHeaderSpecific(pc, SNES_CLASSID, 2);
387731823bd8SMatthew G Knepley   PetscCheckSameComm(snes, 1, pc, 2);
387831823bd8SMatthew G Knepley   ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr);
3879bf11d3b6SBarry Smith   ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr);
388031823bd8SMatthew G Knepley   snes->pc = pc;
388131823bd8SMatthew G Knepley   ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr);
388231823bd8SMatthew G Knepley   PetscFunctionReturn(0);
388331823bd8SMatthew G Knepley }
388431823bd8SMatthew G Knepley 
388531823bd8SMatthew G Knepley #undef __FUNCT__
388631823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC"
388731823bd8SMatthew G Knepley /*@
3888fd4b34e9SJed Brown   SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC().
388931823bd8SMatthew G Knepley 
389031823bd8SMatthew G Knepley   Not Collective
389131823bd8SMatthew G Knepley 
389231823bd8SMatthew G Knepley   Input Parameter:
389331823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate()
389431823bd8SMatthew G Knepley 
389531823bd8SMatthew G Knepley   Output Parameter:
389631823bd8SMatthew G Knepley . pc - preconditioner context
389731823bd8SMatthew G Knepley 
389831823bd8SMatthew G Knepley   Level: developer
389931823bd8SMatthew G Knepley 
390031823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner
390131823bd8SMatthew G Knepley .seealso: SNESSetPC()
390231823bd8SMatthew G Knepley @*/
390331823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc)
390431823bd8SMatthew G Knepley {
390531823bd8SMatthew G Knepley   PetscErrorCode ierr;
390631823bd8SMatthew G Knepley 
390731823bd8SMatthew G Knepley   PetscFunctionBegin;
390831823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
390931823bd8SMatthew G Knepley   PetscValidPointer(pc, 2);
391031823bd8SMatthew G Knepley   if (!snes->pc) {
391131823bd8SMatthew G Knepley     ierr = SNESCreate(((PetscObject) snes)->comm, &snes->pc);CHKERRQ(ierr);
39124a0c5b0cSMatthew G Knepley     ierr = PetscObjectIncrementTabLevel((PetscObject) snes->pc, (PetscObject) snes, 1);CHKERRQ(ierr);
391331823bd8SMatthew G Knepley     ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr);
391431823bd8SMatthew G Knepley   }
391531823bd8SMatthew G Knepley   *pc = snes->pc;
391631823bd8SMatthew G Knepley   PetscFunctionReturn(0);
391731823bd8SMatthew G Knepley }
391831823bd8SMatthew G Knepley 
391969b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3920c6db04a5SJed Brown #include <mex.h>
392169b4f73cSBarry Smith 
39228f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext;
39238f6e6473SBarry Smith 
39240807856dSBarry Smith #undef __FUNCT__
39250807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab"
39260807856dSBarry Smith /*
39270807856dSBarry Smith    SNESComputeFunction_Matlab - Calls the function that has been set with
39280807856dSBarry Smith                          SNESSetFunctionMatlab().
39290807856dSBarry Smith 
39300807856dSBarry Smith    Collective on SNES
39310807856dSBarry Smith 
39320807856dSBarry Smith    Input Parameters:
39330807856dSBarry Smith +  snes - the SNES context
39340807856dSBarry Smith -  x - input vector
39350807856dSBarry Smith 
39360807856dSBarry Smith    Output Parameter:
39370807856dSBarry Smith .  y - function vector, as set by SNESSetFunction()
39380807856dSBarry Smith 
39390807856dSBarry Smith    Notes:
39400807856dSBarry Smith    SNESComputeFunction() is typically used within nonlinear solvers
39410807856dSBarry Smith    implementations, so most users would not generally call this routine
39420807856dSBarry Smith    themselves.
39430807856dSBarry Smith 
39440807856dSBarry Smith    Level: developer
39450807856dSBarry Smith 
39460807856dSBarry Smith .keywords: SNES, nonlinear, compute, function
39470807856dSBarry Smith 
39480807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
394961b2408cSBarry Smith */
39507087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx)
39510807856dSBarry Smith {
3952e650e774SBarry Smith   PetscErrorCode    ierr;
39538f6e6473SBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
39548f6e6473SBarry Smith   int               nlhs = 1,nrhs = 5;
39558f6e6473SBarry Smith   mxArray	    *plhs[1],*prhs[5];
395691621f2eSBarry Smith   long long int     lx = 0,ly = 0,ls = 0;
3957e650e774SBarry Smith 
39580807856dSBarry Smith   PetscFunctionBegin;
39590807856dSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
39600807856dSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
39610807856dSBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
39620807856dSBarry Smith   PetscCheckSameComm(snes,1,x,2);
39630807856dSBarry Smith   PetscCheckSameComm(snes,1,y,3);
39640807856dSBarry Smith 
39650807856dSBarry Smith   /* call Matlab function in ctx with arguments x and y */
3966e650e774SBarry Smith 
396791621f2eSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
3968e650e774SBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
3969e650e774SBarry Smith   ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr);
397091621f2eSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
397191621f2eSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
397291621f2eSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)ly);
39738f6e6473SBarry Smith   prhs[3] =  mxCreateString(sctx->funcname);
39748f6e6473SBarry Smith   prhs[4] =  sctx->ctx;
3975b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr);
3976e650e774SBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
3977e650e774SBarry Smith   mxDestroyArray(prhs[0]);
3978e650e774SBarry Smith   mxDestroyArray(prhs[1]);
3979e650e774SBarry Smith   mxDestroyArray(prhs[2]);
39808f6e6473SBarry Smith   mxDestroyArray(prhs[3]);
3981e650e774SBarry Smith   mxDestroyArray(plhs[0]);
39820807856dSBarry Smith   PetscFunctionReturn(0);
39830807856dSBarry Smith }
39840807856dSBarry Smith 
39850807856dSBarry Smith 
39860807856dSBarry Smith #undef __FUNCT__
39870807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab"
398861b2408cSBarry Smith /*
39890807856dSBarry Smith    SNESSetFunctionMatlab - Sets the function evaluation routine and function
39900807856dSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
3991e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
39920807856dSBarry Smith 
39930807856dSBarry Smith    Logically Collective on SNES
39940807856dSBarry Smith 
39950807856dSBarry Smith    Input Parameters:
39960807856dSBarry Smith +  snes - the SNES context
39970807856dSBarry Smith .  r - vector to store function value
39980807856dSBarry Smith -  func - function evaluation routine
39990807856dSBarry Smith 
40000807856dSBarry Smith    Calling sequence of func:
400161b2408cSBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
40020807856dSBarry Smith 
40030807856dSBarry Smith 
40040807856dSBarry Smith    Notes:
40050807856dSBarry Smith    The Newton-like methods typically solve linear systems of the form
40060807856dSBarry Smith $      f'(x) x = -f(x),
40070807856dSBarry Smith    where f'(x) denotes the Jacobian matrix and f(x) is the function.
40080807856dSBarry Smith 
40090807856dSBarry Smith    Level: beginner
40100807856dSBarry Smith 
40110807856dSBarry Smith .keywords: SNES, nonlinear, set, function
40120807856dSBarry Smith 
40130807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
401461b2408cSBarry Smith */
40157087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx)
40160807856dSBarry Smith {
40170807856dSBarry Smith   PetscErrorCode    ierr;
40188f6e6473SBarry Smith   SNESMatlabContext *sctx;
40190807856dSBarry Smith 
40200807856dSBarry Smith   PetscFunctionBegin;
40218f6e6473SBarry Smith   /* currently sctx is memory bleed */
40228f6e6473SBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
40238f6e6473SBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
40248f6e6473SBarry Smith   /*
40258f6e6473SBarry Smith      This should work, but it doesn't
40268f6e6473SBarry Smith   sctx->ctx = ctx;
40278f6e6473SBarry Smith   mexMakeArrayPersistent(sctx->ctx);
40288f6e6473SBarry Smith   */
40298f6e6473SBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
40308f6e6473SBarry Smith   ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr);
40310807856dSBarry Smith   PetscFunctionReturn(0);
40320807856dSBarry Smith }
403369b4f73cSBarry Smith 
403461b2408cSBarry Smith #undef __FUNCT__
403561b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab"
403661b2408cSBarry Smith /*
403761b2408cSBarry Smith    SNESComputeJacobian_Matlab - Calls the function that has been set with
403861b2408cSBarry Smith                          SNESSetJacobianMatlab().
403961b2408cSBarry Smith 
404061b2408cSBarry Smith    Collective on SNES
404161b2408cSBarry Smith 
404261b2408cSBarry Smith    Input Parameters:
404361b2408cSBarry Smith +  snes - the SNES context
404461b2408cSBarry Smith .  x - input vector
404561b2408cSBarry Smith .  A, B - the matrices
404661b2408cSBarry Smith -  ctx - user context
404761b2408cSBarry Smith 
404861b2408cSBarry Smith    Output Parameter:
404961b2408cSBarry Smith .  flag - structure of the matrix
405061b2408cSBarry Smith 
405161b2408cSBarry Smith    Level: developer
405261b2408cSBarry Smith 
405361b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function
405461b2408cSBarry Smith 
405561b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
405661b2408cSBarry Smith @*/
40577087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx)
405861b2408cSBarry Smith {
405961b2408cSBarry Smith   PetscErrorCode    ierr;
406061b2408cSBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
406161b2408cSBarry Smith   int               nlhs = 2,nrhs = 6;
406261b2408cSBarry Smith   mxArray	    *plhs[2],*prhs[6];
406361b2408cSBarry Smith   long long int     lx = 0,lA = 0,ls = 0, lB = 0;
406461b2408cSBarry Smith 
406561b2408cSBarry Smith   PetscFunctionBegin;
406661b2408cSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
406761b2408cSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
406861b2408cSBarry Smith 
406961b2408cSBarry Smith   /* call Matlab function in ctx with arguments x and y */
407061b2408cSBarry Smith 
407161b2408cSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
407261b2408cSBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
407361b2408cSBarry Smith   ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr);
407461b2408cSBarry Smith   ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr);
407561b2408cSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
407661b2408cSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
407761b2408cSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)lA);
407861b2408cSBarry Smith   prhs[3] =  mxCreateDoubleScalar((double)lB);
407961b2408cSBarry Smith   prhs[4] =  mxCreateString(sctx->funcname);
408061b2408cSBarry Smith   prhs[5] =  sctx->ctx;
4081b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr);
408261b2408cSBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
408361b2408cSBarry Smith   *flag   =  (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr);
408461b2408cSBarry Smith   mxDestroyArray(prhs[0]);
408561b2408cSBarry Smith   mxDestroyArray(prhs[1]);
408661b2408cSBarry Smith   mxDestroyArray(prhs[2]);
408761b2408cSBarry Smith   mxDestroyArray(prhs[3]);
408861b2408cSBarry Smith   mxDestroyArray(prhs[4]);
408961b2408cSBarry Smith   mxDestroyArray(plhs[0]);
409061b2408cSBarry Smith   mxDestroyArray(plhs[1]);
409161b2408cSBarry Smith   PetscFunctionReturn(0);
409261b2408cSBarry Smith }
409361b2408cSBarry Smith 
409461b2408cSBarry Smith 
409561b2408cSBarry Smith #undef __FUNCT__
409661b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab"
409761b2408cSBarry Smith /*
409861b2408cSBarry Smith    SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
409961b2408cSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4100e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
410161b2408cSBarry Smith 
410261b2408cSBarry Smith    Logically Collective on SNES
410361b2408cSBarry Smith 
410461b2408cSBarry Smith    Input Parameters:
410561b2408cSBarry Smith +  snes - the SNES context
410661b2408cSBarry Smith .  A,B - Jacobian matrices
410761b2408cSBarry Smith .  func - function evaluation routine
410861b2408cSBarry Smith -  ctx - user context
410961b2408cSBarry Smith 
411061b2408cSBarry Smith    Calling sequence of func:
411161b2408cSBarry Smith $    flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx);
411261b2408cSBarry Smith 
411361b2408cSBarry Smith 
411461b2408cSBarry Smith    Level: developer
411561b2408cSBarry Smith 
411661b2408cSBarry Smith .keywords: SNES, nonlinear, set, function
411761b2408cSBarry Smith 
411861b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
411961b2408cSBarry Smith */
41207087cfbeSBarry Smith PetscErrorCode  SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx)
412161b2408cSBarry Smith {
412261b2408cSBarry Smith   PetscErrorCode    ierr;
412361b2408cSBarry Smith   SNESMatlabContext *sctx;
412461b2408cSBarry Smith 
412561b2408cSBarry Smith   PetscFunctionBegin;
412661b2408cSBarry Smith   /* currently sctx is memory bleed */
412761b2408cSBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
412861b2408cSBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
412961b2408cSBarry Smith   /*
413061b2408cSBarry Smith      This should work, but it doesn't
413161b2408cSBarry Smith   sctx->ctx = ctx;
413261b2408cSBarry Smith   mexMakeArrayPersistent(sctx->ctx);
413361b2408cSBarry Smith   */
413461b2408cSBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
413561b2408cSBarry Smith   ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
413661b2408cSBarry Smith   PetscFunctionReturn(0);
413761b2408cSBarry Smith }
413869b4f73cSBarry Smith 
4139f9eb7ae2SShri Abhyankar #undef __FUNCT__
4140f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab"
4141f9eb7ae2SShri Abhyankar /*
4142f9eb7ae2SShri Abhyankar    SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab().
4143f9eb7ae2SShri Abhyankar 
4144f9eb7ae2SShri Abhyankar    Collective on SNES
4145f9eb7ae2SShri Abhyankar 
4146f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction()
4147f9eb7ae2SShri Abhyankar @*/
41487087cfbeSBarry Smith PetscErrorCode  SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx)
4149f9eb7ae2SShri Abhyankar {
4150f9eb7ae2SShri Abhyankar   PetscErrorCode  ierr;
415148f37e70SShri Abhyankar   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
4152f9eb7ae2SShri Abhyankar   int             nlhs = 1,nrhs = 6;
4153f9eb7ae2SShri Abhyankar   mxArray	  *plhs[1],*prhs[6];
4154f9eb7ae2SShri Abhyankar   long long int   lx = 0,ls = 0;
4155f9eb7ae2SShri Abhyankar   Vec             x=snes->vec_sol;
4156f9eb7ae2SShri Abhyankar 
4157f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4158f9eb7ae2SShri Abhyankar   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4159f9eb7ae2SShri Abhyankar 
4160f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4161f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4162f9eb7ae2SShri Abhyankar   prhs[0] =  mxCreateDoubleScalar((double)ls);
4163f9eb7ae2SShri Abhyankar   prhs[1] =  mxCreateDoubleScalar((double)it);
4164f9eb7ae2SShri Abhyankar   prhs[2] =  mxCreateDoubleScalar((double)fnorm);
4165f9eb7ae2SShri Abhyankar   prhs[3] =  mxCreateDoubleScalar((double)lx);
4166f9eb7ae2SShri Abhyankar   prhs[4] =  mxCreateString(sctx->funcname);
4167f9eb7ae2SShri Abhyankar   prhs[5] =  sctx->ctx;
4168f9eb7ae2SShri Abhyankar   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr);
4169f9eb7ae2SShri Abhyankar   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4170f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[0]);
4171f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[1]);
4172f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[2]);
4173f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[3]);
4174f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[4]);
4175f9eb7ae2SShri Abhyankar   mxDestroyArray(plhs[0]);
4176f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
4177f9eb7ae2SShri Abhyankar }
4178f9eb7ae2SShri Abhyankar 
4179f9eb7ae2SShri Abhyankar 
4180f9eb7ae2SShri Abhyankar #undef __FUNCT__
4181f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab"
4182f9eb7ae2SShri Abhyankar /*
4183e3c5b3baSBarry Smith    SNESMonitorSetMatlab - Sets the monitor function from MATLAB
4184f9eb7ae2SShri Abhyankar 
4185f9eb7ae2SShri Abhyankar    Level: developer
4186f9eb7ae2SShri Abhyankar 
4187f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function
4188f9eb7ae2SShri Abhyankar 
4189f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
4190f9eb7ae2SShri Abhyankar */
41917087cfbeSBarry Smith PetscErrorCode  SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx)
4192f9eb7ae2SShri Abhyankar {
4193f9eb7ae2SShri Abhyankar   PetscErrorCode    ierr;
4194f9eb7ae2SShri Abhyankar   SNESMatlabContext *sctx;
4195f9eb7ae2SShri Abhyankar 
4196f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4197f9eb7ae2SShri Abhyankar   /* currently sctx is memory bleed */
4198f9eb7ae2SShri Abhyankar   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
4199f9eb7ae2SShri Abhyankar   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
4200f9eb7ae2SShri Abhyankar   /*
4201f9eb7ae2SShri Abhyankar      This should work, but it doesn't
4202f9eb7ae2SShri Abhyankar   sctx->ctx = ctx;
4203f9eb7ae2SShri Abhyankar   mexMakeArrayPersistent(sctx->ctx);
4204f9eb7ae2SShri Abhyankar   */
4205f9eb7ae2SShri Abhyankar   sctx->ctx = mxDuplicateArray(ctx);
4206f9eb7ae2SShri Abhyankar   ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr);
4207f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
4208f9eb7ae2SShri Abhyankar }
4209f9eb7ae2SShri Abhyankar 
421069b4f73cSBarry Smith #endif
4211