xref: /petsc/src/snes/interface/snes.c (revision 4a0c5b0c254533510f18d4cc0ff9d9f9e759c2a4)
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) {
189eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is rebuilt every %D Newton 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   }
19694b7f48cSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
197*4a0c5b0cSMatthew G Knepley   if (snes->pc) {
198*4a0c5b0cSMatthew G Knepley     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
199*4a0c5b0cSMatthew G Knepley     ierr = SNESView(snes->pc, viewer);CHKERRQ(ierr);
200*4a0c5b0cSMatthew G Knepley     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
201*4a0c5b0cSMatthew G Knepley   }
202b0a32e0cSBarry Smith   ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
20394b7f48cSBarry Smith   ierr = KSPView(ksp,viewer);CHKERRQ(ierr);
204b0a32e0cSBarry Smith   ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2053a40ed3dSBarry Smith   PetscFunctionReturn(0);
2069b94acceSBarry Smith }
2079b94acceSBarry Smith 
20876b2cf59SMatthew Knepley /*
20976b2cf59SMatthew Knepley   We retain a list of functions that also take SNES command
21076b2cf59SMatthew Knepley   line options. These are called at the end SNESSetFromOptions()
21176b2cf59SMatthew Knepley */
21276b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5
213a7cc72afSBarry Smith static PetscInt numberofsetfromoptions;
2146849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES);
21576b2cf59SMatthew Knepley 
216e74ef692SMatthew Knepley #undef __FUNCT__
217e74ef692SMatthew Knepley #define __FUNCT__ "SNESAddOptionsChecker"
218ac226902SBarry Smith /*@C
21976b2cf59SMatthew Knepley   SNESAddOptionsChecker - Adds an additional function to check for SNES options.
22076b2cf59SMatthew Knepley 
22176b2cf59SMatthew Knepley   Not Collective
22276b2cf59SMatthew Knepley 
22376b2cf59SMatthew Knepley   Input Parameter:
22476b2cf59SMatthew Knepley . snescheck - function that checks for options
22576b2cf59SMatthew Knepley 
22676b2cf59SMatthew Knepley   Level: developer
22776b2cf59SMatthew Knepley 
22876b2cf59SMatthew Knepley .seealso: SNESSetFromOptions()
22976b2cf59SMatthew Knepley @*/
2307087cfbeSBarry Smith PetscErrorCode  SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES))
23176b2cf59SMatthew Knepley {
23276b2cf59SMatthew Knepley   PetscFunctionBegin;
23376b2cf59SMatthew Knepley   if (numberofsetfromoptions >= MAXSETFROMOPTIONS) {
234e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS);
23576b2cf59SMatthew Knepley   }
23676b2cf59SMatthew Knepley   othersetfromoptions[numberofsetfromoptions++] = snescheck;
23776b2cf59SMatthew Knepley   PetscFunctionReturn(0);
23876b2cf59SMatthew Knepley }
23976b2cf59SMatthew Knepley 
2407087cfbeSBarry Smith extern PetscErrorCode  SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*);
241aa3661deSLisandro Dalcin 
242aa3661deSLisandro Dalcin #undef __FUNCT__
243aa3661deSLisandro Dalcin #define __FUNCT__ "SNESSetUpMatrixFree_Private"
244ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool  hasOperator, PetscInt version)
245aa3661deSLisandro Dalcin {
246aa3661deSLisandro Dalcin   Mat            J;
247aa3661deSLisandro Dalcin   KSP            ksp;
248aa3661deSLisandro Dalcin   PC             pc;
249ace3abfcSBarry Smith   PetscBool      match;
250aa3661deSLisandro Dalcin   PetscErrorCode ierr;
251aa3661deSLisandro Dalcin 
252aa3661deSLisandro Dalcin   PetscFunctionBegin;
2530700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
254aa3661deSLisandro Dalcin 
25598613b67SLisandro Dalcin   if(!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) {
25698613b67SLisandro Dalcin     Mat A = snes->jacobian, B = snes->jacobian_pre;
25798613b67SLisandro Dalcin     ierr = MatGetVecs(A ? A : B, PETSC_NULL,&snes->vec_func);CHKERRQ(ierr);
25898613b67SLisandro Dalcin   }
25998613b67SLisandro Dalcin 
260aa3661deSLisandro Dalcin   if (version == 1) {
261aa3661deSLisandro Dalcin     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
26298613b67SLisandro Dalcin     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
2639c6ac3b3SBarry Smith     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
264aa3661deSLisandro Dalcin   } else if (version == 2) {
265e32f2f54SBarry Smith     if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first");
266ce63c4c1SBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) && !defined(PETSC_USE_REAL_LONG_DOUBLE)
267aa3661deSLisandro Dalcin     ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr);
268aa3661deSLisandro Dalcin #else
269e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)");
270aa3661deSLisandro Dalcin #endif
271aa3661deSLisandro Dalcin   } else {
272e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2");
273aa3661deSLisandro Dalcin   }
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 
295aa3661deSLisandro Dalcin   PetscFunctionReturn(0);
296aa3661deSLisandro Dalcin }
297aa3661deSLisandro Dalcin 
2984a2ae208SSatish Balay #undef __FUNCT__
2994a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions"
3009b94acceSBarry Smith /*@
30194b7f48cSBarry Smith    SNESSetFromOptions - Sets various SNES and KSP parameters from user options.
3029b94acceSBarry Smith 
303c7afd0dbSLois Curfman McInnes    Collective on SNES
304c7afd0dbSLois Curfman McInnes 
3059b94acceSBarry Smith    Input Parameter:
3069b94acceSBarry Smith .  snes - the SNES context
3079b94acceSBarry Smith 
30836851e7fSLois Curfman McInnes    Options Database Keys:
3096831982aSBarry Smith +  -snes_type <type> - ls, tr, umls, umtr, test
31082738288SBarry Smith .  -snes_stol - convergence tolerance in terms of the norm
31182738288SBarry Smith                 of the change in the solution between steps
31270441072SBarry Smith .  -snes_atol <abstol> - absolute tolerance of residual norm
313b39c3a46SLois Curfman McInnes .  -snes_rtol <rtol> - relative decrease in tolerance norm from initial
314b39c3a46SLois Curfman McInnes .  -snes_max_it <max_it> - maximum number of iterations
315b39c3a46SLois Curfman McInnes .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
31650ffb88aSMatthew Knepley .  -snes_max_fail <max_fail> - maximum number of failures
317ddf469c8SBarry Smith .  -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops
318a8054027SBarry Smith .  -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild)
319e35cf81dSBarry Smith .  -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild)
320b39c3a46SLois Curfman McInnes .  -snes_trtol <trtol> - trust region tolerance
3212492ecdbSBarry Smith .  -snes_no_convergence_test - skip convergence test in nonlinear
32282738288SBarry Smith                                solver; hence iterations will continue until max_it
3231fbbfb26SLois Curfman McInnes                                or some other criterion is reached. Saves expense
32482738288SBarry Smith                                of convergence test
325e8105e01SRichard Katz .  -snes_monitor <optional filename> - prints residual norm at each iteration. if no
326e8105e01SRichard Katz                                        filename given prints to stdout
327a6570f20SBarry Smith .  -snes_monitor_solution - plots solution at each iteration
328a6570f20SBarry Smith .  -snes_monitor_residual - plots residual (not its norm) at each iteration
329a6570f20SBarry Smith .  -snes_monitor_solution_update - plots update to solution at each iteration
330a6570f20SBarry Smith .  -snes_monitor_draw - plots residual norm at each iteration
331e24b481bSBarry Smith .  -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
3325968eb51SBarry Smith .  -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
333fee2055bSBarry Smith -  -snes_converged_reason - print the reason for convergence/divergence after each solve
33482738288SBarry Smith 
33582738288SBarry Smith     Options Database for Eisenstat-Walker method:
336fa9f3622SBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
3374b27c08aSLois Curfman McInnes .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
33836851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
33936851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
34036851e7fSLois Curfman McInnes .  -snes_ksp_ew_gamma <gamma> - Sets gamma
34136851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha <alpha> - Sets alpha
34236851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
34336851e7fSLois Curfman McInnes -  -snes_ksp_ew_threshold <threshold> - Sets threshold
34482738288SBarry Smith 
34511ca99fdSLois Curfman McInnes    Notes:
34611ca99fdSLois Curfman McInnes    To see all options, run your program with the -help option or consult
3470598bfebSBarry Smith    the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>.
34883e2fdc7SBarry Smith 
34936851e7fSLois Curfman McInnes    Level: beginner
35036851e7fSLois Curfman McInnes 
3519b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database
3529b94acceSBarry Smith 
35369ed319cSSatish Balay .seealso: SNESSetOptionsPrefix()
3549b94acceSBarry Smith @*/
3557087cfbeSBarry Smith PetscErrorCode  SNESSetFromOptions(SNES snes)
3569b94acceSBarry Smith {
357ace3abfcSBarry Smith   PetscBool               flg,mf,mf_operator;
358efd51863SBarry Smith   PetscInt                i,indx,lag,mf_version,grids;
359aa3661deSLisandro Dalcin   MatStructure            matflag;
36085385478SLisandro Dalcin   const char              *deft = SNESLS;
36185385478SLisandro Dalcin   const char              *convtests[] = {"default","skip"};
36285385478SLisandro Dalcin   SNESKSPEW               *kctx = NULL;
363e8105e01SRichard Katz   char                    type[256], monfilename[PETSC_MAX_PATH_LEN];
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);}
371cce0b1b2SLisandro Dalcin   ierr = PetscOptionsBegin(((PetscObject)snes)->comm,((PetscObject)snes)->prefix,"Nonlinear solver (SNES) options","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 
45490d69ab7SBarry Smith     flg  = PETSC_FALSE;
455acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
456a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);}
45790d69ab7SBarry Smith     flg  = PETSC_FALSE;
458acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
459a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);}
46090d69ab7SBarry Smith     flg  = PETSC_FALSE;
461acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
462a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);}
46390d69ab7SBarry Smith     flg  = PETSC_FALSE;
464acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
465a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
46690d69ab7SBarry Smith     flg  = PETSC_FALSE;
467acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
468b271bb04SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
469e24b481bSBarry Smith 
47090d69ab7SBarry Smith     flg  = PETSC_FALSE;
471acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
4724b27c08aSLois Curfman McInnes     if (flg) {
473186905e3SBarry Smith       ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,snes->funP);CHKERRQ(ierr);
474ae15b995SBarry Smith       ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr);
4759b94acceSBarry Smith     }
476639f9d9dSBarry Smith 
477aa3661deSLisandro Dalcin     mf = mf_operator = PETSC_FALSE;
478aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
479acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr);
480aa3661deSLisandro Dalcin     if (flg && mf_operator) mf = PETSC_TRUE;
481aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
482acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);CHKERRQ(ierr);
483aa3661deSLisandro Dalcin     if (!flg && mf_operator) mf = PETSC_TRUE;
484aa3661deSLisandro Dalcin     mf_version = 1;
485aa3661deSLisandro Dalcin     ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);CHKERRQ(ierr);
486aa3661deSLisandro Dalcin 
48776b2cf59SMatthew Knepley     for(i = 0; i < numberofsetfromoptions; i++) {
48876b2cf59SMatthew Knepley       ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr);
48976b2cf59SMatthew Knepley     }
49076b2cf59SMatthew Knepley 
491e7788613SBarry Smith     if (snes->ops->setfromoptions) {
492e7788613SBarry Smith       ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr);
493639f9d9dSBarry Smith     }
4945d973c19SBarry Smith 
4955d973c19SBarry Smith     /* process any options handlers added with PetscObjectAddOptionsHandler() */
4965d973c19SBarry Smith     ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr);
497b0a32e0cSBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
4984bbc92c1SBarry Smith 
499aa3661deSLisandro Dalcin   if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); }
5001cee3971SBarry Smith 
5011cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
502aa3661deSLisandro Dalcin   ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag);
503aa3661deSLisandro Dalcin   ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr);
50485385478SLisandro Dalcin   ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr);
50593993e2dSLois Curfman McInnes 
506*4a0c5b0cSMatthew G Knepley   if (snes->pc) {
507*4a0c5b0cSMatthew G Knepley     ierr = SNESSetOptionsPrefix(snes->pc, "npc_");CHKERRQ(ierr);
508*4a0c5b0cSMatthew G Knepley     ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr);
509*4a0c5b0cSMatthew G Knepley     /* Should we make a duplicate vector and matrix? Leave the DM to make it? */
510*4a0c5b0cSMatthew G Knepley     ierr = SNESSetFunction(snes->pc, snes->vec_func, snes->ops->computefunction, snes->funP);CHKERRQ(ierr);
511*4a0c5b0cSMatthew G Knepley     ierr = SNESSetJacobian(snes->pc, snes->jacobian, snes->jacobian_pre, snes->ops->computejacobian, snes->jacP);CHKERRQ(ierr);
512*4a0c5b0cSMatthew G Knepley     ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr);
513*4a0c5b0cSMatthew G Knepley   }
5143a40ed3dSBarry Smith   PetscFunctionReturn(0);
5159b94acceSBarry Smith }
5169b94acceSBarry Smith 
517d25893d9SBarry Smith #undef __FUNCT__
518d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext"
519d25893d9SBarry Smith /*@
520d25893d9SBarry Smith    SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for
521d25893d9SBarry Smith    the nonlinear solvers.
522d25893d9SBarry Smith 
523d25893d9SBarry Smith    Logically Collective on SNES
524d25893d9SBarry Smith 
525d25893d9SBarry Smith    Input Parameters:
526d25893d9SBarry Smith +  snes - the SNES context
527d25893d9SBarry Smith .  compute - function to compute the context
528d25893d9SBarry Smith -  destroy - function to destroy the context
529d25893d9SBarry Smith 
530d25893d9SBarry Smith    Level: intermediate
531d25893d9SBarry Smith 
532d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context
533d25893d9SBarry Smith 
534d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext()
535d25893d9SBarry Smith @*/
536d25893d9SBarry Smith PetscErrorCode  SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**))
537d25893d9SBarry Smith {
538d25893d9SBarry Smith   PetscFunctionBegin;
539d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
540d25893d9SBarry Smith   snes->ops->usercompute = compute;
541d25893d9SBarry Smith   snes->ops->userdestroy = destroy;
542d25893d9SBarry Smith   PetscFunctionReturn(0);
543d25893d9SBarry Smith }
544a847f771SSatish Balay 
5454a2ae208SSatish Balay #undef __FUNCT__
5464a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext"
547b07ff414SBarry Smith /*@
5489b94acceSBarry Smith    SNESSetApplicationContext - Sets the optional user-defined context for
5499b94acceSBarry Smith    the nonlinear solvers.
5509b94acceSBarry Smith 
5513f9fe445SBarry Smith    Logically Collective on SNES
552fee21e36SBarry Smith 
553c7afd0dbSLois Curfman McInnes    Input Parameters:
554c7afd0dbSLois Curfman McInnes +  snes - the SNES context
555c7afd0dbSLois Curfman McInnes -  usrP - optional user context
556c7afd0dbSLois Curfman McInnes 
55736851e7fSLois Curfman McInnes    Level: intermediate
55836851e7fSLois Curfman McInnes 
5599b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context
5609b94acceSBarry Smith 
561d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetApplicationContext()
5629b94acceSBarry Smith @*/
5637087cfbeSBarry Smith PetscErrorCode  SNESSetApplicationContext(SNES snes,void *usrP)
5649b94acceSBarry Smith {
5651b2093e4SBarry Smith   PetscErrorCode ierr;
566b07ff414SBarry Smith   KSP            ksp;
5671b2093e4SBarry Smith 
5683a40ed3dSBarry Smith   PetscFunctionBegin;
5690700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
570b07ff414SBarry Smith   ierr       = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
571b07ff414SBarry Smith   ierr       = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr);
5729b94acceSBarry Smith   snes->user = usrP;
5733a40ed3dSBarry Smith   PetscFunctionReturn(0);
5749b94acceSBarry Smith }
57574679c65SBarry Smith 
5764a2ae208SSatish Balay #undef __FUNCT__
5774a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext"
578b07ff414SBarry Smith /*@
5799b94acceSBarry Smith    SNESGetApplicationContext - Gets the user-defined context for the
5809b94acceSBarry Smith    nonlinear solvers.
5819b94acceSBarry Smith 
582c7afd0dbSLois Curfman McInnes    Not Collective
583c7afd0dbSLois Curfman McInnes 
5849b94acceSBarry Smith    Input Parameter:
5859b94acceSBarry Smith .  snes - SNES context
5869b94acceSBarry Smith 
5879b94acceSBarry Smith    Output Parameter:
5889b94acceSBarry Smith .  usrP - user context
5899b94acceSBarry Smith 
59036851e7fSLois Curfman McInnes    Level: intermediate
59136851e7fSLois Curfman McInnes 
5929b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context
5939b94acceSBarry Smith 
5949b94acceSBarry Smith .seealso: SNESSetApplicationContext()
5959b94acceSBarry Smith @*/
5967087cfbeSBarry Smith PetscErrorCode  SNESGetApplicationContext(SNES snes,void **usrP)
5979b94acceSBarry Smith {
5983a40ed3dSBarry Smith   PetscFunctionBegin;
5990700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
6009b94acceSBarry Smith   *usrP = snes->user;
6013a40ed3dSBarry Smith   PetscFunctionReturn(0);
6029b94acceSBarry Smith }
60374679c65SBarry Smith 
6044a2ae208SSatish Balay #undef __FUNCT__
6054a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber"
6069b94acceSBarry Smith /*@
607c8228a4eSBarry Smith    SNESGetIterationNumber - Gets the number of nonlinear iterations completed
608c8228a4eSBarry Smith    at this time.
6099b94acceSBarry Smith 
610c7afd0dbSLois Curfman McInnes    Not Collective
611c7afd0dbSLois Curfman McInnes 
6129b94acceSBarry Smith    Input Parameter:
6139b94acceSBarry Smith .  snes - SNES context
6149b94acceSBarry Smith 
6159b94acceSBarry Smith    Output Parameter:
6169b94acceSBarry Smith .  iter - iteration number
6179b94acceSBarry Smith 
618c8228a4eSBarry Smith    Notes:
619c8228a4eSBarry Smith    For example, during the computation of iteration 2 this would return 1.
620c8228a4eSBarry Smith 
621c8228a4eSBarry Smith    This is useful for using lagged Jacobians (where one does not recompute the
62208405cd6SLois Curfman McInnes    Jacobian at each SNES iteration). For example, the code
62308405cd6SLois Curfman McInnes .vb
62408405cd6SLois Curfman McInnes       ierr = SNESGetIterationNumber(snes,&it);
62508405cd6SLois Curfman McInnes       if (!(it % 2)) {
62608405cd6SLois Curfman McInnes         [compute Jacobian here]
62708405cd6SLois Curfman McInnes       }
62808405cd6SLois Curfman McInnes .ve
629c8228a4eSBarry Smith    can be used in your ComputeJacobian() function to cause the Jacobian to be
63008405cd6SLois Curfman McInnes    recomputed every second SNES iteration.
631c8228a4eSBarry Smith 
63236851e7fSLois Curfman McInnes    Level: intermediate
63336851e7fSLois Curfman McInnes 
6342b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number,
6352b668275SBarry Smith 
636b850b91aSLisandro Dalcin .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
6379b94acceSBarry Smith @*/
6387087cfbeSBarry Smith PetscErrorCode  SNESGetIterationNumber(SNES snes,PetscInt* iter)
6399b94acceSBarry Smith {
6403a40ed3dSBarry Smith   PetscFunctionBegin;
6410700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
6424482741eSBarry Smith   PetscValidIntPointer(iter,2);
6439b94acceSBarry Smith   *iter = snes->iter;
6443a40ed3dSBarry Smith   PetscFunctionReturn(0);
6459b94acceSBarry Smith }
64674679c65SBarry Smith 
6474a2ae208SSatish Balay #undef __FUNCT__
6484a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm"
6499b94acceSBarry Smith /*@
6509b94acceSBarry Smith    SNESGetFunctionNorm - Gets the norm of the current function that was set
6519b94acceSBarry Smith    with SNESSSetFunction().
6529b94acceSBarry Smith 
653c7afd0dbSLois Curfman McInnes    Collective on SNES
654c7afd0dbSLois Curfman McInnes 
6559b94acceSBarry Smith    Input Parameter:
6569b94acceSBarry Smith .  snes - SNES context
6579b94acceSBarry Smith 
6589b94acceSBarry Smith    Output Parameter:
6599b94acceSBarry Smith .  fnorm - 2-norm of function
6609b94acceSBarry Smith 
66136851e7fSLois Curfman McInnes    Level: intermediate
66236851e7fSLois Curfman McInnes 
6639b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm
664a86d99e1SLois Curfman McInnes 
665b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations()
6669b94acceSBarry Smith @*/
6677087cfbeSBarry Smith PetscErrorCode  SNESGetFunctionNorm(SNES snes,PetscReal *fnorm)
6689b94acceSBarry Smith {
6693a40ed3dSBarry Smith   PetscFunctionBegin;
6700700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
6714482741eSBarry Smith   PetscValidScalarPointer(fnorm,2);
6729b94acceSBarry Smith   *fnorm = snes->norm;
6733a40ed3dSBarry Smith   PetscFunctionReturn(0);
6749b94acceSBarry Smith }
67574679c65SBarry Smith 
6764a2ae208SSatish Balay #undef __FUNCT__
677b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures"
6789b94acceSBarry Smith /*@
679b850b91aSLisandro Dalcin    SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
6809b94acceSBarry Smith    attempted by the nonlinear solver.
6819b94acceSBarry Smith 
682c7afd0dbSLois Curfman McInnes    Not Collective
683c7afd0dbSLois Curfman McInnes 
6849b94acceSBarry Smith    Input Parameter:
6859b94acceSBarry Smith .  snes - SNES context
6869b94acceSBarry Smith 
6879b94acceSBarry Smith    Output Parameter:
6889b94acceSBarry Smith .  nfails - number of unsuccessful steps attempted
6899b94acceSBarry Smith 
690c96a6f78SLois Curfman McInnes    Notes:
691c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
692c96a6f78SLois Curfman McInnes 
69336851e7fSLois Curfman McInnes    Level: intermediate
69436851e7fSLois Curfman McInnes 
6959b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
69658ebbce7SBarry Smith 
697e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
69858ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures()
6999b94acceSBarry Smith @*/
7007087cfbeSBarry Smith PetscErrorCode  SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails)
7019b94acceSBarry Smith {
7023a40ed3dSBarry Smith   PetscFunctionBegin;
7030700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
7044482741eSBarry Smith   PetscValidIntPointer(nfails,2);
70550ffb88aSMatthew Knepley   *nfails = snes->numFailures;
70650ffb88aSMatthew Knepley   PetscFunctionReturn(0);
70750ffb88aSMatthew Knepley }
70850ffb88aSMatthew Knepley 
70950ffb88aSMatthew Knepley #undef __FUNCT__
710b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures"
71150ffb88aSMatthew Knepley /*@
712b850b91aSLisandro Dalcin    SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
71350ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
71450ffb88aSMatthew Knepley 
71550ffb88aSMatthew Knepley    Not Collective
71650ffb88aSMatthew Knepley 
71750ffb88aSMatthew Knepley    Input Parameters:
71850ffb88aSMatthew Knepley +  snes     - SNES context
71950ffb88aSMatthew Knepley -  maxFails - maximum of unsuccessful steps
72050ffb88aSMatthew Knepley 
72150ffb88aSMatthew Knepley    Level: intermediate
72250ffb88aSMatthew Knepley 
72350ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
72458ebbce7SBarry Smith 
725e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
72658ebbce7SBarry Smith           SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
72750ffb88aSMatthew Knepley @*/
7287087cfbeSBarry Smith PetscErrorCode  SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
72950ffb88aSMatthew Knepley {
73050ffb88aSMatthew Knepley   PetscFunctionBegin;
7310700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
73250ffb88aSMatthew Knepley   snes->maxFailures = maxFails;
73350ffb88aSMatthew Knepley   PetscFunctionReturn(0);
73450ffb88aSMatthew Knepley }
73550ffb88aSMatthew Knepley 
73650ffb88aSMatthew Knepley #undef __FUNCT__
737b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures"
73850ffb88aSMatthew Knepley /*@
739b850b91aSLisandro Dalcin    SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
74050ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
74150ffb88aSMatthew Knepley 
74250ffb88aSMatthew Knepley    Not Collective
74350ffb88aSMatthew Knepley 
74450ffb88aSMatthew Knepley    Input Parameter:
74550ffb88aSMatthew Knepley .  snes     - SNES context
74650ffb88aSMatthew Knepley 
74750ffb88aSMatthew Knepley    Output Parameter:
74850ffb88aSMatthew Knepley .  maxFails - maximum of unsuccessful steps
74950ffb88aSMatthew Knepley 
75050ffb88aSMatthew Knepley    Level: intermediate
75150ffb88aSMatthew Knepley 
75250ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
75358ebbce7SBarry Smith 
754e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
75558ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
75658ebbce7SBarry Smith 
75750ffb88aSMatthew Knepley @*/
7587087cfbeSBarry Smith PetscErrorCode  SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
75950ffb88aSMatthew Knepley {
76050ffb88aSMatthew Knepley   PetscFunctionBegin;
7610700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
7624482741eSBarry Smith   PetscValidIntPointer(maxFails,2);
76350ffb88aSMatthew Knepley   *maxFails = snes->maxFailures;
7643a40ed3dSBarry Smith   PetscFunctionReturn(0);
7659b94acceSBarry Smith }
766a847f771SSatish Balay 
7674a2ae208SSatish Balay #undef __FUNCT__
7682541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals"
7692541af92SBarry Smith /*@
7702541af92SBarry Smith    SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations
7712541af92SBarry Smith      done by SNES.
7722541af92SBarry Smith 
7732541af92SBarry Smith    Not Collective
7742541af92SBarry Smith 
7752541af92SBarry Smith    Input Parameter:
7762541af92SBarry Smith .  snes     - SNES context
7772541af92SBarry Smith 
7782541af92SBarry Smith    Output Parameter:
7792541af92SBarry Smith .  nfuncs - number of evaluations
7802541af92SBarry Smith 
7812541af92SBarry Smith    Level: intermediate
7822541af92SBarry Smith 
7832541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
78458ebbce7SBarry Smith 
785e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures()
7862541af92SBarry Smith @*/
7877087cfbeSBarry Smith PetscErrorCode  SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs)
7882541af92SBarry Smith {
7892541af92SBarry Smith   PetscFunctionBegin;
7900700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
7912541af92SBarry Smith   PetscValidIntPointer(nfuncs,2);
7922541af92SBarry Smith   *nfuncs = snes->nfuncs;
7932541af92SBarry Smith   PetscFunctionReturn(0);
7942541af92SBarry Smith }
7952541af92SBarry Smith 
7962541af92SBarry Smith #undef __FUNCT__
7973d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures"
7983d4c4710SBarry Smith /*@
7993d4c4710SBarry Smith    SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
8003d4c4710SBarry Smith    linear solvers.
8013d4c4710SBarry Smith 
8023d4c4710SBarry Smith    Not Collective
8033d4c4710SBarry Smith 
8043d4c4710SBarry Smith    Input Parameter:
8053d4c4710SBarry Smith .  snes - SNES context
8063d4c4710SBarry Smith 
8073d4c4710SBarry Smith    Output Parameter:
8083d4c4710SBarry Smith .  nfails - number of failed solves
8093d4c4710SBarry Smith 
8103d4c4710SBarry Smith    Notes:
8113d4c4710SBarry Smith    This counter is reset to zero for each successive call to SNESSolve().
8123d4c4710SBarry Smith 
8133d4c4710SBarry Smith    Level: intermediate
8143d4c4710SBarry Smith 
8153d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
81658ebbce7SBarry Smith 
817e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures()
8183d4c4710SBarry Smith @*/
8197087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails)
8203d4c4710SBarry Smith {
8213d4c4710SBarry Smith   PetscFunctionBegin;
8220700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
8233d4c4710SBarry Smith   PetscValidIntPointer(nfails,2);
8243d4c4710SBarry Smith   *nfails = snes->numLinearSolveFailures;
8253d4c4710SBarry Smith   PetscFunctionReturn(0);
8263d4c4710SBarry Smith }
8273d4c4710SBarry Smith 
8283d4c4710SBarry Smith #undef __FUNCT__
8293d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures"
8303d4c4710SBarry Smith /*@
8313d4c4710SBarry Smith    SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
8323d4c4710SBarry Smith    allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE
8333d4c4710SBarry Smith 
8343f9fe445SBarry Smith    Logically Collective on SNES
8353d4c4710SBarry Smith 
8363d4c4710SBarry Smith    Input Parameters:
8373d4c4710SBarry Smith +  snes     - SNES context
8383d4c4710SBarry Smith -  maxFails - maximum allowed linear solve failures
8393d4c4710SBarry Smith 
8403d4c4710SBarry Smith    Level: intermediate
8413d4c4710SBarry Smith 
842a6796414SBarry Smith    Notes: By default this is 0; that is SNES returns on the first failed linear solve
8433d4c4710SBarry Smith 
8443d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
8453d4c4710SBarry Smith 
84658ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations()
8473d4c4710SBarry Smith @*/
8487087cfbeSBarry Smith PetscErrorCode  SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
8493d4c4710SBarry Smith {
8503d4c4710SBarry Smith   PetscFunctionBegin;
8510700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
852c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxFails,2);
8533d4c4710SBarry Smith   snes->maxLinearSolveFailures = maxFails;
8543d4c4710SBarry Smith   PetscFunctionReturn(0);
8553d4c4710SBarry Smith }
8563d4c4710SBarry Smith 
8573d4c4710SBarry Smith #undef __FUNCT__
8583d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures"
8593d4c4710SBarry Smith /*@
8603d4c4710SBarry Smith    SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
8613d4c4710SBarry Smith      are allowed before SNES terminates
8623d4c4710SBarry Smith 
8633d4c4710SBarry Smith    Not Collective
8643d4c4710SBarry Smith 
8653d4c4710SBarry Smith    Input Parameter:
8663d4c4710SBarry Smith .  snes     - SNES context
8673d4c4710SBarry Smith 
8683d4c4710SBarry Smith    Output Parameter:
8693d4c4710SBarry Smith .  maxFails - maximum of unsuccessful solves allowed
8703d4c4710SBarry Smith 
8713d4c4710SBarry Smith    Level: intermediate
8723d4c4710SBarry Smith 
8733d4c4710SBarry Smith    Notes: By default this is 1; that is SNES returns on the first failed linear solve
8743d4c4710SBarry Smith 
8753d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
8763d4c4710SBarry Smith 
877e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(),
8783d4c4710SBarry Smith @*/
8797087cfbeSBarry Smith PetscErrorCode  SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
8803d4c4710SBarry Smith {
8813d4c4710SBarry Smith   PetscFunctionBegin;
8820700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
8833d4c4710SBarry Smith   PetscValidIntPointer(maxFails,2);
8843d4c4710SBarry Smith   *maxFails = snes->maxLinearSolveFailures;
8853d4c4710SBarry Smith   PetscFunctionReturn(0);
8863d4c4710SBarry Smith }
8873d4c4710SBarry Smith 
8883d4c4710SBarry Smith #undef __FUNCT__
889b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations"
890c96a6f78SLois Curfman McInnes /*@
891b850b91aSLisandro Dalcin    SNESGetLinearSolveIterations - Gets the total number of linear iterations
892c96a6f78SLois Curfman McInnes    used by the nonlinear solver.
893c96a6f78SLois Curfman McInnes 
894c7afd0dbSLois Curfman McInnes    Not Collective
895c7afd0dbSLois Curfman McInnes 
896c96a6f78SLois Curfman McInnes    Input Parameter:
897c96a6f78SLois Curfman McInnes .  snes - SNES context
898c96a6f78SLois Curfman McInnes 
899c96a6f78SLois Curfman McInnes    Output Parameter:
900c96a6f78SLois Curfman McInnes .  lits - number of linear iterations
901c96a6f78SLois Curfman McInnes 
902c96a6f78SLois Curfman McInnes    Notes:
903c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
904c96a6f78SLois Curfman McInnes 
90536851e7fSLois Curfman McInnes    Level: intermediate
90636851e7fSLois Curfman McInnes 
907c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations
9082b668275SBarry Smith 
9098c7482ecSBarry Smith .seealso:  SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures()
910c96a6f78SLois Curfman McInnes @*/
9117087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveIterations(SNES snes,PetscInt* lits)
912c96a6f78SLois Curfman McInnes {
9133a40ed3dSBarry Smith   PetscFunctionBegin;
9140700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9154482741eSBarry Smith   PetscValidIntPointer(lits,2);
916c96a6f78SLois Curfman McInnes   *lits = snes->linear_its;
9173a40ed3dSBarry Smith   PetscFunctionReturn(0);
918c96a6f78SLois Curfman McInnes }
919c96a6f78SLois Curfman McInnes 
9204a2ae208SSatish Balay #undef __FUNCT__
92194b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP"
92252baeb72SSatish Balay /*@
92394b7f48cSBarry Smith    SNESGetKSP - Returns the KSP context for a SNES solver.
9249b94acceSBarry Smith 
92594b7f48cSBarry Smith    Not Collective, but if SNES object is parallel, then KSP object is parallel
926c7afd0dbSLois Curfman McInnes 
9279b94acceSBarry Smith    Input Parameter:
9289b94acceSBarry Smith .  snes - the SNES context
9299b94acceSBarry Smith 
9309b94acceSBarry Smith    Output Parameter:
93194b7f48cSBarry Smith .  ksp - the KSP context
9329b94acceSBarry Smith 
9339b94acceSBarry Smith    Notes:
93494b7f48cSBarry Smith    The user can then directly manipulate the KSP context to set various
9359b94acceSBarry Smith    options, etc.  Likewise, the user can then extract and manipulate the
9362999313aSBarry Smith    PC contexts as well.
9379b94acceSBarry Smith 
93836851e7fSLois Curfman McInnes    Level: beginner
93936851e7fSLois Curfman McInnes 
94094b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
9419b94acceSBarry Smith 
9422999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
9439b94acceSBarry Smith @*/
9447087cfbeSBarry Smith PetscErrorCode  SNESGetKSP(SNES snes,KSP *ksp)
9459b94acceSBarry Smith {
9461cee3971SBarry Smith   PetscErrorCode ierr;
9471cee3971SBarry Smith 
9483a40ed3dSBarry Smith   PetscFunctionBegin;
9490700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9504482741eSBarry Smith   PetscValidPointer(ksp,2);
9511cee3971SBarry Smith 
9521cee3971SBarry Smith   if (!snes->ksp) {
9531cee3971SBarry Smith     ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr);
9541cee3971SBarry Smith     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr);
9551cee3971SBarry Smith     ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr);
9561cee3971SBarry Smith   }
95794b7f48cSBarry Smith   *ksp = snes->ksp;
9583a40ed3dSBarry Smith   PetscFunctionReturn(0);
9599b94acceSBarry Smith }
96082bf6240SBarry Smith 
9614a2ae208SSatish Balay #undef __FUNCT__
9622999313aSBarry Smith #define __FUNCT__ "SNESSetKSP"
9632999313aSBarry Smith /*@
9642999313aSBarry Smith    SNESSetKSP - Sets a KSP context for the SNES object to use
9652999313aSBarry Smith 
9662999313aSBarry Smith    Not Collective, but the SNES and KSP objects must live on the same MPI_Comm
9672999313aSBarry Smith 
9682999313aSBarry Smith    Input Parameters:
9692999313aSBarry Smith +  snes - the SNES context
9702999313aSBarry Smith -  ksp - the KSP context
9712999313aSBarry Smith 
9722999313aSBarry Smith    Notes:
9732999313aSBarry Smith    The SNES object already has its KSP object, you can obtain with SNESGetKSP()
9742999313aSBarry Smith    so this routine is rarely needed.
9752999313aSBarry Smith 
9762999313aSBarry Smith    The KSP object that is already in the SNES object has its reference count
9772999313aSBarry Smith    decreased by one.
9782999313aSBarry Smith 
9792999313aSBarry Smith    Level: developer
9802999313aSBarry Smith 
9812999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
9822999313aSBarry Smith 
9832999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
9842999313aSBarry Smith @*/
9857087cfbeSBarry Smith PetscErrorCode  SNESSetKSP(SNES snes,KSP ksp)
9862999313aSBarry Smith {
9872999313aSBarry Smith   PetscErrorCode ierr;
9882999313aSBarry Smith 
9892999313aSBarry Smith   PetscFunctionBegin;
9900700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9910700a824SBarry Smith   PetscValidHeaderSpecific(ksp,KSP_CLASSID,2);
9922999313aSBarry Smith   PetscCheckSameComm(snes,1,ksp,2);
9937dcf0eaaSdalcinl   ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr);
994906ed7ccSBarry Smith   if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);}
9952999313aSBarry Smith   snes->ksp = ksp;
9962999313aSBarry Smith   PetscFunctionReturn(0);
9972999313aSBarry Smith }
9982999313aSBarry Smith 
9997adad957SLisandro Dalcin #if 0
10002999313aSBarry Smith #undef __FUNCT__
10014a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc"
10026849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj)
1003e24b481bSBarry Smith {
1004e24b481bSBarry Smith   PetscFunctionBegin;
1005e24b481bSBarry Smith   PetscFunctionReturn(0);
1006e24b481bSBarry Smith }
10077adad957SLisandro Dalcin #endif
1008e24b481bSBarry Smith 
10099b94acceSBarry Smith /* -----------------------------------------------------------*/
10104a2ae208SSatish Balay #undef __FUNCT__
10114a2ae208SSatish Balay #define __FUNCT__ "SNESCreate"
101252baeb72SSatish Balay /*@
10139b94acceSBarry Smith    SNESCreate - Creates a nonlinear solver context.
10149b94acceSBarry Smith 
1015c7afd0dbSLois Curfman McInnes    Collective on MPI_Comm
1016c7afd0dbSLois Curfman McInnes 
1017c7afd0dbSLois Curfman McInnes    Input Parameters:
1018906ed7ccSBarry Smith .  comm - MPI communicator
10199b94acceSBarry Smith 
10209b94acceSBarry Smith    Output Parameter:
10219b94acceSBarry Smith .  outsnes - the new SNES context
10229b94acceSBarry Smith 
1023c7afd0dbSLois Curfman McInnes    Options Database Keys:
1024c7afd0dbSLois Curfman McInnes +   -snes_mf - Activates default matrix-free Jacobian-vector products,
1025c7afd0dbSLois Curfman McInnes                and no preconditioning matrix
1026c7afd0dbSLois Curfman McInnes .   -snes_mf_operator - Activates default matrix-free Jacobian-vector
1027c7afd0dbSLois Curfman McInnes                products, and a user-provided preconditioning matrix
1028c7afd0dbSLois Curfman McInnes                as set by SNESSetJacobian()
1029c7afd0dbSLois Curfman McInnes -   -snes_fd - Uses (slow!) finite differences to compute Jacobian
1030c1f60f51SBarry Smith 
103136851e7fSLois Curfman McInnes    Level: beginner
103236851e7fSLois Curfman McInnes 
10339b94acceSBarry Smith .keywords: SNES, nonlinear, create, context
10349b94acceSBarry Smith 
1035a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner()
1036a8054027SBarry Smith 
10379b94acceSBarry Smith @*/
10387087cfbeSBarry Smith PetscErrorCode  SNESCreate(MPI_Comm comm,SNES *outsnes)
10399b94acceSBarry Smith {
1040dfbe8321SBarry Smith   PetscErrorCode      ierr;
10419b94acceSBarry Smith   SNES                snes;
1042fa9f3622SBarry Smith   SNESKSPEW           *kctx;
104337fcc0dbSBarry Smith 
10443a40ed3dSBarry Smith   PetscFunctionBegin;
1045ed1caa07SMatthew Knepley   PetscValidPointer(outsnes,2);
10468ba1e511SMatthew Knepley   *outsnes = PETSC_NULL;
10478ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES
10488ba1e511SMatthew Knepley   ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr);
10498ba1e511SMatthew Knepley #endif
10508ba1e511SMatthew Knepley 
10510700a824SBarry Smith   ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr);
10527adad957SLisandro Dalcin 
105385385478SLisandro Dalcin   snes->ops->converged    = SNESDefaultConverged;
10549b94acceSBarry Smith   snes->max_its           = 50;
10559750a799SBarry Smith   snes->max_funcs	  = 10000;
10569b94acceSBarry Smith   snes->norm		  = 0.0;
1057b4874afaSBarry Smith   snes->rtol		  = 1.e-8;
1058b4874afaSBarry Smith   snes->ttol              = 0.0;
105970441072SBarry Smith   snes->abstol		  = 1.e-50;
10609b94acceSBarry Smith   snes->xtol		  = 1.e-8;
10614b27c08aSLois Curfman McInnes   snes->deltatol	  = 1.e-12;
10629b94acceSBarry Smith   snes->nfuncs            = 0;
106350ffb88aSMatthew Knepley   snes->numFailures       = 0;
106450ffb88aSMatthew Knepley   snes->maxFailures       = 1;
10657a00f4a9SLois Curfman McInnes   snes->linear_its        = 0;
1066e35cf81dSBarry Smith   snes->lagjacobian       = 1;
1067a8054027SBarry Smith   snes->lagpreconditioner = 1;
1068639f9d9dSBarry Smith   snes->numbermonitors    = 0;
10699b94acceSBarry Smith   snes->data              = 0;
10704dc4c822SBarry Smith   snes->setupcalled       = PETSC_FALSE;
1071186905e3SBarry Smith   snes->ksp_ewconv        = PETSC_FALSE;
10726f24a144SLois Curfman McInnes   snes->nwork             = 0;
107358c9b817SLisandro Dalcin   snes->work              = 0;
107458c9b817SLisandro Dalcin   snes->nvwork            = 0;
107558c9b817SLisandro Dalcin   snes->vwork             = 0;
1076758f92a0SBarry Smith   snes->conv_hist_len     = 0;
1077758f92a0SBarry Smith   snes->conv_hist_max     = 0;
1078758f92a0SBarry Smith   snes->conv_hist         = PETSC_NULL;
1079758f92a0SBarry Smith   snes->conv_hist_its     = PETSC_NULL;
1080758f92a0SBarry Smith   snes->conv_hist_reset   = PETSC_TRUE;
1081184914b5SBarry Smith   snes->reason            = SNES_CONVERGED_ITERATING;
10829b94acceSBarry Smith 
10833d4c4710SBarry Smith   snes->numLinearSolveFailures = 0;
10843d4c4710SBarry Smith   snes->maxLinearSolveFailures = 1;
10853d4c4710SBarry Smith 
10869b94acceSBarry Smith   /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
108738f2d2fdSLisandro Dalcin   ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr);
10889b94acceSBarry Smith   snes->kspconvctx  = (void*)kctx;
10899b94acceSBarry Smith   kctx->version     = 2;
10909b94acceSBarry Smith   kctx->rtol_0      = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
10919b94acceSBarry Smith                              this was too large for some test cases */
109275567043SBarry Smith   kctx->rtol_last   = 0.0;
10939b94acceSBarry Smith   kctx->rtol_max    = .9;
10949b94acceSBarry Smith   kctx->gamma       = 1.0;
109571f87433Sdalcinl   kctx->alpha       = .5*(1.0 + sqrt(5.0));
109671f87433Sdalcinl   kctx->alpha2      = kctx->alpha;
10979b94acceSBarry Smith   kctx->threshold   = .1;
109875567043SBarry Smith   kctx->lresid_last = 0.0;
109975567043SBarry Smith   kctx->norm_last   = 0.0;
11009b94acceSBarry Smith 
11019b94acceSBarry Smith   *outsnes = snes;
11023a40ed3dSBarry Smith   PetscFunctionReturn(0);
11039b94acceSBarry Smith }
11049b94acceSBarry Smith 
11054a2ae208SSatish Balay #undef __FUNCT__
11064a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction"
11079b94acceSBarry Smith /*@C
11089b94acceSBarry Smith    SNESSetFunction - Sets the function evaluation routine and function
11099b94acceSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
11109b94acceSBarry Smith    equations.
11119b94acceSBarry Smith 
11123f9fe445SBarry Smith    Logically Collective on SNES
1113fee21e36SBarry Smith 
1114c7afd0dbSLois Curfman McInnes    Input Parameters:
1115c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1116c7afd0dbSLois Curfman McInnes .  r - vector to store function value
1117de044059SHong Zhang .  func - function evaluation routine
1118c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
1119c7afd0dbSLois Curfman McInnes          function evaluation routine (may be PETSC_NULL)
11209b94acceSBarry Smith 
1121c7afd0dbSLois Curfman McInnes    Calling sequence of func:
11228d76a1e5SLois Curfman McInnes $    func (SNES snes,Vec x,Vec f,void *ctx);
1123c7afd0dbSLois Curfman McInnes 
1124313e4042SLois Curfman McInnes .  f - function vector
1125c7afd0dbSLois Curfman McInnes -  ctx - optional user-defined function context
11269b94acceSBarry Smith 
11279b94acceSBarry Smith    Notes:
11289b94acceSBarry Smith    The Newton-like methods typically solve linear systems of the form
11299b94acceSBarry Smith $      f'(x) x = -f(x),
1130c7afd0dbSLois Curfman McInnes    where f'(x) denotes the Jacobian matrix and f(x) is the function.
11319b94acceSBarry Smith 
113236851e7fSLois Curfman McInnes    Level: beginner
113336851e7fSLois Curfman McInnes 
11349b94acceSBarry Smith .keywords: SNES, nonlinear, set, function
11359b94acceSBarry Smith 
1136a86d99e1SLois Curfman McInnes .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
11379b94acceSBarry Smith @*/
11387087cfbeSBarry Smith PetscErrorCode  SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx)
11399b94acceSBarry Smith {
114085385478SLisandro Dalcin   PetscErrorCode ierr;
11413a40ed3dSBarry Smith   PetscFunctionBegin;
11420700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1143d2a683ecSLisandro Dalcin   if (r) {
1144d2a683ecSLisandro Dalcin     PetscValidHeaderSpecific(r,VEC_CLASSID,2);
1145d2a683ecSLisandro Dalcin     PetscCheckSameComm(snes,1,r,2);
114685385478SLisandro Dalcin     ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr);
11476bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
114885385478SLisandro Dalcin     snes->vec_func = r;
1149d2a683ecSLisandro Dalcin   } else if (!snes->vec_func && snes->dm) {
1150d2a683ecSLisandro Dalcin     ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr);
1151d2a683ecSLisandro Dalcin   }
1152d2a683ecSLisandro Dalcin   if (func) snes->ops->computefunction = func;
1153d2a683ecSLisandro Dalcin   if (ctx)  snes->funP                 = ctx;
11543a40ed3dSBarry Smith   PetscFunctionReturn(0);
11559b94acceSBarry Smith }
11569b94acceSBarry Smith 
1157d25893d9SBarry Smith #undef __FUNCT__
1158d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess"
1159d25893d9SBarry Smith /*@C
1160d25893d9SBarry Smith    SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem
1161d25893d9SBarry Smith 
1162d25893d9SBarry Smith    Logically Collective on SNES
1163d25893d9SBarry Smith 
1164d25893d9SBarry Smith    Input Parameters:
1165d25893d9SBarry Smith +  snes - the SNES context
1166d25893d9SBarry Smith .  func - function evaluation routine
1167d25893d9SBarry Smith -  ctx - [optional] user-defined context for private data for the
1168d25893d9SBarry Smith          function evaluation routine (may be PETSC_NULL)
1169d25893d9SBarry Smith 
1170d25893d9SBarry Smith    Calling sequence of func:
1171d25893d9SBarry Smith $    func (SNES snes,Vec x,void *ctx);
1172d25893d9SBarry Smith 
1173d25893d9SBarry Smith .  f - function vector
1174d25893d9SBarry Smith -  ctx - optional user-defined function context
1175d25893d9SBarry Smith 
1176d25893d9SBarry Smith    Level: intermediate
1177d25893d9SBarry Smith 
1178d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function
1179d25893d9SBarry Smith 
1180d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
1181d25893d9SBarry Smith @*/
1182d25893d9SBarry Smith PetscErrorCode  SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx)
1183d25893d9SBarry Smith {
1184d25893d9SBarry Smith   PetscFunctionBegin;
1185d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1186d25893d9SBarry Smith   if (func) snes->ops->computeinitialguess = func;
1187d25893d9SBarry Smith   if (ctx)  snes->initialguessP            = ctx;
1188d25893d9SBarry Smith   PetscFunctionReturn(0);
1189d25893d9SBarry Smith }
1190d25893d9SBarry Smith 
11913ab0aad5SBarry Smith /* --------------------------------------------------------------- */
11923ab0aad5SBarry Smith #undef __FUNCT__
11931096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs"
11941096aae1SMatthew Knepley /*@C
11951096aae1SMatthew Knepley    SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
11961096aae1SMatthew Knepley    it assumes a zero right hand side.
11971096aae1SMatthew Knepley 
11983f9fe445SBarry Smith    Logically Collective on SNES
11991096aae1SMatthew Knepley 
12001096aae1SMatthew Knepley    Input Parameter:
12011096aae1SMatthew Knepley .  snes - the SNES context
12021096aae1SMatthew Knepley 
12031096aae1SMatthew Knepley    Output Parameter:
1204bc08b0f1SBarry Smith .  rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null
12051096aae1SMatthew Knepley 
12061096aae1SMatthew Knepley    Level: intermediate
12071096aae1SMatthew Knepley 
12081096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side
12091096aae1SMatthew Knepley 
121085385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
12111096aae1SMatthew Knepley @*/
12127087cfbeSBarry Smith PetscErrorCode  SNESGetRhs(SNES snes,Vec *rhs)
12131096aae1SMatthew Knepley {
12141096aae1SMatthew Knepley   PetscFunctionBegin;
12150700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
12161096aae1SMatthew Knepley   PetscValidPointer(rhs,2);
121785385478SLisandro Dalcin   *rhs = snes->vec_rhs;
12181096aae1SMatthew Knepley   PetscFunctionReturn(0);
12191096aae1SMatthew Knepley }
12201096aae1SMatthew Knepley 
12211096aae1SMatthew Knepley #undef __FUNCT__
12224a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction"
12239b94acceSBarry Smith /*@
122436851e7fSLois Curfman McInnes    SNESComputeFunction - Calls the function that has been set with
12259b94acceSBarry Smith                          SNESSetFunction().
12269b94acceSBarry Smith 
1227c7afd0dbSLois Curfman McInnes    Collective on SNES
1228c7afd0dbSLois Curfman McInnes 
12299b94acceSBarry Smith    Input Parameters:
1230c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1231c7afd0dbSLois Curfman McInnes -  x - input vector
12329b94acceSBarry Smith 
12339b94acceSBarry Smith    Output Parameter:
12343638b69dSLois Curfman McInnes .  y - function vector, as set by SNESSetFunction()
12359b94acceSBarry Smith 
12361bffabb2SLois Curfman McInnes    Notes:
123736851e7fSLois Curfman McInnes    SNESComputeFunction() is typically used within nonlinear solvers
123836851e7fSLois Curfman McInnes    implementations, so most users would not generally call this routine
123936851e7fSLois Curfman McInnes    themselves.
124036851e7fSLois Curfman McInnes 
124136851e7fSLois Curfman McInnes    Level: developer
124236851e7fSLois Curfman McInnes 
12439b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function
12449b94acceSBarry Smith 
1245a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction()
12469b94acceSBarry Smith @*/
12477087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction(SNES snes,Vec x,Vec y)
12489b94acceSBarry Smith {
1249dfbe8321SBarry Smith   PetscErrorCode ierr;
12509b94acceSBarry Smith 
12513a40ed3dSBarry Smith   PetscFunctionBegin;
12520700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
12530700a824SBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
12540700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
1255c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,x,2);
1256c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,3);
1257184914b5SBarry Smith 
1258d5ba7fb7SMatthew Knepley   ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
1259e7788613SBarry Smith   if (snes->ops->computefunction) {
1260d64ed03dSBarry Smith     PetscStackPush("SNES user function");
126139d508bbSBarry Smith     ierr = (*snes->ops->computefunction)(snes,x,y,snes->funP);CHKERRQ(ierr);
1262d64ed03dSBarry Smith     PetscStackPop;
126385385478SLisandro Dalcin   } else if (snes->vec_rhs) {
12641096aae1SMatthew Knepley     ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr);
126573250ac0SBarry Smith   } else if (snes->dm) {
1266644e2e5bSBarry Smith     ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr);
1267644e2e5bSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve().");
126885385478SLisandro Dalcin   if (snes->vec_rhs) {
126985385478SLisandro Dalcin     ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr);
12703ab0aad5SBarry Smith   }
1271ae3c334cSLois Curfman McInnes   snes->nfuncs++;
1272d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
12733a40ed3dSBarry Smith   PetscFunctionReturn(0);
12749b94acceSBarry Smith }
12759b94acceSBarry Smith 
12764a2ae208SSatish Balay #undef __FUNCT__
12774a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian"
127862fef451SLois Curfman McInnes /*@
127962fef451SLois Curfman McInnes    SNESComputeJacobian - Computes the Jacobian matrix that has been
128062fef451SLois Curfman McInnes    set with SNESSetJacobian().
128162fef451SLois Curfman McInnes 
1282c7afd0dbSLois Curfman McInnes    Collective on SNES and Mat
1283c7afd0dbSLois Curfman McInnes 
128462fef451SLois Curfman McInnes    Input Parameters:
1285c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1286c7afd0dbSLois Curfman McInnes -  x - input vector
128762fef451SLois Curfman McInnes 
128862fef451SLois Curfman McInnes    Output Parameters:
1289c7afd0dbSLois Curfman McInnes +  A - Jacobian matrix
129062fef451SLois Curfman McInnes .  B - optional preconditioning matrix
12912b668275SBarry Smith -  flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER)
1292fee21e36SBarry Smith 
1293e35cf81dSBarry Smith   Options Database Keys:
1294e35cf81dSBarry Smith +    -snes_lag_preconditioner <lag>
1295693365a8SJed Brown .    -snes_lag_jacobian <lag>
1296693365a8SJed Brown .    -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences
1297693365a8SJed Brown .    -snes_compare_explicit_draw  - Compare the computed Jacobian to the finite difference Jacobian and draw the result
1298693365a8SJed Brown .    -snes_compare_explicit_contour  - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result
1299693365a8SJed Brown -    -snes_compare_operator  - Make the comparison options above use the operator instead of the preconditioning matrix
1300e35cf81dSBarry Smith 
130162fef451SLois Curfman McInnes    Notes:
130262fef451SLois Curfman McInnes    Most users should not need to explicitly call this routine, as it
130362fef451SLois Curfman McInnes    is used internally within the nonlinear solvers.
130462fef451SLois Curfman McInnes 
130594b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the
1306dc5a77f8SLois Curfman McInnes    flag parameter.
130762fef451SLois Curfman McInnes 
130836851e7fSLois Curfman McInnes    Level: developer
130936851e7fSLois Curfman McInnes 
131062fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix
131162fef451SLois Curfman McInnes 
1312e35cf81dSBarry Smith .seealso:  SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian()
131362fef451SLois Curfman McInnes @*/
13147087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg)
13159b94acceSBarry Smith {
1316dfbe8321SBarry Smith   PetscErrorCode ierr;
1317ace3abfcSBarry Smith   PetscBool      flag;
13183a40ed3dSBarry Smith 
13193a40ed3dSBarry Smith   PetscFunctionBegin;
13200700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
13210700a824SBarry Smith   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
13224482741eSBarry Smith   PetscValidPointer(flg,5);
1323c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,X,2);
1324e7788613SBarry Smith   if (!snes->ops->computejacobian) PetscFunctionReturn(0);
1325ebd3b9afSBarry Smith 
1326ebd3b9afSBarry Smith   /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */
1327ebd3b9afSBarry Smith 
1328fe3ffe1eSBarry Smith   if (snes->lagjacobian == -2) {
1329fe3ffe1eSBarry Smith     snes->lagjacobian = -1;
1330fe3ffe1eSBarry Smith     ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr);
1331fe3ffe1eSBarry Smith   } else if (snes->lagjacobian == -1) {
1332e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
1333e35cf81dSBarry Smith     ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr);
1334ebd3b9afSBarry Smith     ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
1335ebd3b9afSBarry Smith     if (flag) {
1336ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1337ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1338ebd3b9afSBarry Smith     }
1339e35cf81dSBarry Smith     PetscFunctionReturn(0);
1340e35cf81dSBarry Smith   } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) {
1341e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
1342e35cf81dSBarry Smith     ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr);
1343ebd3b9afSBarry Smith     ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
1344ebd3b9afSBarry Smith     if (flag) {
1345ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1346ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1347ebd3b9afSBarry Smith     }
1348e35cf81dSBarry Smith     PetscFunctionReturn(0);
1349e35cf81dSBarry Smith   }
1350e35cf81dSBarry Smith 
1351c4fc05e7SBarry Smith   *flg = DIFFERENT_NONZERO_PATTERN;
1352e35cf81dSBarry Smith   ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
1353d64ed03dSBarry Smith   PetscStackPush("SNES user Jacobian function");
1354e7788613SBarry Smith   ierr = (*snes->ops->computejacobian)(snes,X,A,B,flg,snes->jacP);CHKERRQ(ierr);
1355d64ed03dSBarry Smith   PetscStackPop;
1356d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
1357a8054027SBarry Smith 
13583b4f5425SBarry Smith   if (snes->lagpreconditioner == -2) {
13593b4f5425SBarry Smith     ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr);
13603b4f5425SBarry Smith     snes->lagpreconditioner = -1;
13613b4f5425SBarry Smith   } else if (snes->lagpreconditioner == -1) {
1362a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
1363a8054027SBarry Smith     ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr);
1364a8054027SBarry Smith   } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) {
1365a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
1366a8054027SBarry Smith     ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr);
1367a8054027SBarry Smith   }
1368a8054027SBarry Smith 
13696d84be18SBarry Smith   /* make sure user returned a correct Jacobian and preconditioner */
13700700a824SBarry Smith   /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3);
13710700a824SBarry Smith     PetscValidHeaderSpecific(*B,MAT_CLASSID,4);   */
1372693365a8SJed Brown   {
1373693365a8SJed Brown     PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE;
1374693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr);
1375693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr);
1376693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr);
1377693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr);
1378693365a8SJed Brown     if (flag || flag_draw || flag_contour) {
1379693365a8SJed Brown       Mat Bexp_mine = PETSC_NULL,Bexp,FDexp;
1380693365a8SJed Brown       MatStructure mstruct;
1381693365a8SJed Brown       PetscViewer vdraw,vstdout;
13826b3a5b13SJed Brown       PetscBool flg;
1383693365a8SJed Brown       if (flag_operator) {
1384693365a8SJed Brown         ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr);
1385693365a8SJed Brown         Bexp = Bexp_mine;
1386693365a8SJed Brown       } else {
1387693365a8SJed Brown         /* See if the preconditioning matrix can be viewed and added directly */
1388693365a8SJed Brown         ierr = PetscTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr);
1389693365a8SJed Brown         if (flg) Bexp = *B;
1390693365a8SJed Brown         else {
1391693365a8SJed Brown           /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */
1392693365a8SJed Brown           ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr);
1393693365a8SJed Brown           Bexp = Bexp_mine;
1394693365a8SJed Brown         }
1395693365a8SJed Brown       }
1396693365a8SJed Brown       ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr);
1397693365a8SJed Brown       ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr);
1398693365a8SJed Brown       ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr);
1399693365a8SJed Brown       if (flag_draw || flag_contour) {
1400693365a8SJed Brown         ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
1401693365a8SJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
1402693365a8SJed Brown       } else vdraw = PETSC_NULL;
1403693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr);
1404693365a8SJed Brown       if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);}
1405693365a8SJed Brown       if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);}
1406693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr);
1407693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
1408693365a8SJed Brown       if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);}
1409693365a8SJed Brown       ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
1410693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr);
1411693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
1412693365a8SJed Brown       if (vdraw) {              /* Always use contour for the difference */
1413693365a8SJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
1414693365a8SJed Brown         ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);
1415693365a8SJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
1416693365a8SJed Brown       }
1417693365a8SJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
1418693365a8SJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
1419693365a8SJed Brown       ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr);
1420693365a8SJed Brown       ierr = MatDestroy(&FDexp);CHKERRQ(ierr);
1421693365a8SJed Brown     }
1422693365a8SJed Brown   }
14233a40ed3dSBarry Smith   PetscFunctionReturn(0);
14249b94acceSBarry Smith }
14259b94acceSBarry Smith 
14264a2ae208SSatish Balay #undef __FUNCT__
14274a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian"
14289b94acceSBarry Smith /*@C
14299b94acceSBarry Smith    SNESSetJacobian - Sets the function to compute Jacobian as well as the
1430044dda88SLois Curfman McInnes    location to store the matrix.
14319b94acceSBarry Smith 
14323f9fe445SBarry Smith    Logically Collective on SNES and Mat
1433c7afd0dbSLois Curfman McInnes 
14349b94acceSBarry Smith    Input Parameters:
1435c7afd0dbSLois Curfman McInnes +  snes - the SNES context
14369b94acceSBarry Smith .  A - Jacobian matrix
14379b94acceSBarry Smith .  B - preconditioner matrix (usually same as the Jacobian)
1438efd51863SBarry Smith .  func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value)
1439c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
1440efd51863SBarry Smith          Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value)
14419b94acceSBarry Smith 
14429b94acceSBarry Smith    Calling sequence of func:
14438d76a1e5SLois Curfman McInnes $     func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx);
14449b94acceSBarry Smith 
1445c7afd0dbSLois Curfman McInnes +  x - input vector
14469b94acceSBarry Smith .  A - Jacobian matrix
14479b94acceSBarry Smith .  B - preconditioner matrix, usually the same as A
1448ac21db08SLois Curfman McInnes .  flag - flag indicating information about the preconditioner matrix
14492b668275SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
1450c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined Jacobian context
14519b94acceSBarry Smith 
14529b94acceSBarry Smith    Notes:
145394b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the flag
14542cd2dfdcSLois Curfman McInnes    output parameter in the routine func().  Be sure to read this information!
1455ac21db08SLois Curfman McInnes 
1456ac21db08SLois Curfman McInnes    The routine func() takes Mat * as the matrix arguments rather than Mat.
14579b94acceSBarry Smith    This allows the Jacobian evaluation routine to replace A and/or B with a
14589b94acceSBarry Smith    completely new new matrix structure (not just different matrix elements)
14599b94acceSBarry Smith    when appropriate, for instance, if the nonzero structure is changing
14609b94acceSBarry Smith    throughout the global iterations.
14619b94acceSBarry Smith 
146216913363SBarry Smith    If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on
146316913363SBarry Smith    each matrix.
146416913363SBarry Smith 
1465a8a26c1eSJed Brown    If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument
1466a8a26c1eSJed Brown    must be a MatFDColoring.
1467a8a26c1eSJed Brown 
146836851e7fSLois Curfman McInnes    Level: beginner
146936851e7fSLois Curfman McInnes 
14709b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix
14719b94acceSBarry Smith 
14723ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure
14739b94acceSBarry Smith @*/
14747087cfbeSBarry Smith PetscErrorCode  SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
14759b94acceSBarry Smith {
1476dfbe8321SBarry Smith   PetscErrorCode ierr;
14773a7fca6bSBarry Smith 
14783a40ed3dSBarry Smith   PetscFunctionBegin;
14790700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
14800700a824SBarry Smith   if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2);
14810700a824SBarry Smith   if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3);
1482c9780b6fSBarry Smith   if (A) PetscCheckSameComm(snes,1,A,2);
148306975374SJed Brown   if (B) PetscCheckSameComm(snes,1,B,3);
1484e7788613SBarry Smith   if (func) snes->ops->computejacobian = func;
14853a7fca6bSBarry Smith   if (ctx)  snes->jacP                 = ctx;
14863a7fca6bSBarry Smith   if (A) {
14877dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
14886bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
14899b94acceSBarry Smith     snes->jacobian = A;
14903a7fca6bSBarry Smith   }
14913a7fca6bSBarry Smith   if (B) {
14927dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr);
14936bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
14949b94acceSBarry Smith     snes->jacobian_pre = B;
14953a7fca6bSBarry Smith   }
14963a40ed3dSBarry Smith   PetscFunctionReturn(0);
14979b94acceSBarry Smith }
149862fef451SLois Curfman McInnes 
14994a2ae208SSatish Balay #undef __FUNCT__
15004a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian"
1501c2aafc4cSSatish Balay /*@C
1502b4fd4287SBarry Smith    SNESGetJacobian - Returns the Jacobian matrix and optionally the user
1503b4fd4287SBarry Smith    provided context for evaluating the Jacobian.
1504b4fd4287SBarry Smith 
1505c7afd0dbSLois Curfman McInnes    Not Collective, but Mat object will be parallel if SNES object is
1506c7afd0dbSLois Curfman McInnes 
1507b4fd4287SBarry Smith    Input Parameter:
1508b4fd4287SBarry Smith .  snes - the nonlinear solver context
1509b4fd4287SBarry Smith 
1510b4fd4287SBarry Smith    Output Parameters:
1511c7afd0dbSLois Curfman McInnes +  A - location to stash Jacobian matrix (or PETSC_NULL)
1512b4fd4287SBarry Smith .  B - location to stash preconditioner matrix (or PETSC_NULL)
151370e92668SMatthew Knepley .  func - location to put Jacobian function (or PETSC_NULL)
151470e92668SMatthew Knepley -  ctx - location to stash Jacobian ctx (or PETSC_NULL)
1515fee21e36SBarry Smith 
151636851e7fSLois Curfman McInnes    Level: advanced
151736851e7fSLois Curfman McInnes 
1518b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian()
1519b4fd4287SBarry Smith @*/
15207087cfbeSBarry Smith PetscErrorCode  SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
1521b4fd4287SBarry Smith {
15223a40ed3dSBarry Smith   PetscFunctionBegin;
15230700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1524b4fd4287SBarry Smith   if (A)    *A    = snes->jacobian;
1525b4fd4287SBarry Smith   if (B)    *B    = snes->jacobian_pre;
1526e7788613SBarry Smith   if (func) *func = snes->ops->computejacobian;
152770e92668SMatthew Knepley   if (ctx)  *ctx  = snes->jacP;
15283a40ed3dSBarry Smith   PetscFunctionReturn(0);
1529b4fd4287SBarry Smith }
1530b4fd4287SBarry Smith 
15319b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */
15329b94acceSBarry Smith 
15334a2ae208SSatish Balay #undef __FUNCT__
15344a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp"
15359b94acceSBarry Smith /*@
15369b94acceSBarry Smith    SNESSetUp - Sets up the internal data structures for the later use
1537272ac6f2SLois Curfman McInnes    of a nonlinear solver.
15389b94acceSBarry Smith 
1539fee21e36SBarry Smith    Collective on SNES
1540fee21e36SBarry Smith 
1541c7afd0dbSLois Curfman McInnes    Input Parameters:
154270e92668SMatthew Knepley .  snes - the SNES context
1543c7afd0dbSLois Curfman McInnes 
1544272ac6f2SLois Curfman McInnes    Notes:
1545272ac6f2SLois Curfman McInnes    For basic use of the SNES solvers the user need not explicitly call
1546272ac6f2SLois Curfman McInnes    SNESSetUp(), since these actions will automatically occur during
1547272ac6f2SLois Curfman McInnes    the call to SNESSolve().  However, if one wishes to control this
1548272ac6f2SLois Curfman McInnes    phase separately, SNESSetUp() should be called after SNESCreate()
1549272ac6f2SLois Curfman McInnes    and optional routines of the form SNESSetXXX(), but before SNESSolve().
1550272ac6f2SLois Curfman McInnes 
155136851e7fSLois Curfman McInnes    Level: advanced
155236851e7fSLois Curfman McInnes 
15539b94acceSBarry Smith .keywords: SNES, nonlinear, setup
15549b94acceSBarry Smith 
15559b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
15569b94acceSBarry Smith @*/
15577087cfbeSBarry Smith PetscErrorCode  SNESSetUp(SNES snes)
15589b94acceSBarry Smith {
1559dfbe8321SBarry Smith   PetscErrorCode ierr;
15603a40ed3dSBarry Smith 
15613a40ed3dSBarry Smith   PetscFunctionBegin;
15620700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
15634dc4c822SBarry Smith   if (snes->setupcalled) PetscFunctionReturn(0);
15649b94acceSBarry Smith 
15657adad957SLisandro Dalcin   if (!((PetscObject)snes)->type_name) {
156685385478SLisandro Dalcin     ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr);
156785385478SLisandro Dalcin   }
156885385478SLisandro Dalcin 
1569efd51863SBarry Smith   if (!snes->vec_func && snes->dm && !snes->vec_rhs) {
1570efd51863SBarry Smith     ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr);
1571efd51863SBarry Smith   }
157217186662SBarry Smith   if (!snes->vec_func && !snes->vec_rhs) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() first");
1573644e2e5bSBarry Smith   if (!snes->ops->computefunction && !snes->vec_rhs && !snes->dm) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() or SNESSetDM() first");
157417186662SBarry Smith   if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
157558c9b817SLisandro Dalcin   if (snes->vec_rhs  == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector");
157658c9b817SLisandro Dalcin 
157758c9b817SLisandro Dalcin   if (!snes->vec_func && snes->vec_rhs) {
157858c9b817SLisandro Dalcin     ierr = VecDuplicate(snes->vec_rhs, &snes->vec_func);CHKERRQ(ierr);
157958c9b817SLisandro Dalcin   }
158058c9b817SLisandro Dalcin   if (!snes->vec_sol_update /* && snes->vec_sol */) {
158158c9b817SLisandro Dalcin     ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr);
158258c9b817SLisandro Dalcin     ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr);
158358c9b817SLisandro Dalcin   }
158458c9b817SLisandro Dalcin 
1585ef8dffc7SBarry Smith   if (!snes->ops->computejacobian && snes->dm) {
1586ef8dffc7SBarry Smith     Mat           J;
1587ef8dffc7SBarry Smith     ierr = DMGetMatrix(snes->dm,MATAIJ,&J);CHKERRQ(ierr);
1588cab2e9ccSBarry Smith     ierr = SNESSetJacobian(snes,J,J,SNESDMComputeJacobian,PETSC_NULL);CHKERRQ(ierr);
1589cab2e9ccSBarry Smith     ierr = MatDestroy(&J);CHKERRQ(ierr);
1590efd51863SBarry Smith   } else if (snes->dm && !snes->jacobian_pre){
1591efd51863SBarry Smith     Mat J;
1592efd51863SBarry Smith     ierr = DMGetMatrix(snes->dm,MATAIJ,&J);CHKERRQ(ierr);
1593efd51863SBarry Smith     ierr = SNESSetJacobian(snes,J,J,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
1594efd51863SBarry Smith     ierr = MatDestroy(&J);CHKERRQ(ierr);
1595ef8dffc7SBarry Smith   }
1596efd51863SBarry Smith 
1597b710008aSBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);}
1598b710008aSBarry Smith 
1599d25893d9SBarry Smith   if (snes->ops->usercompute && !snes->user) {
1600d25893d9SBarry Smith     ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr);
1601d25893d9SBarry Smith   }
1602d25893d9SBarry Smith 
1603410397dcSLisandro Dalcin   if (snes->ops->setup) {
1604410397dcSLisandro Dalcin     ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr);
1605410397dcSLisandro Dalcin   }
160658c9b817SLisandro Dalcin 
16077aaed0d8SBarry Smith   snes->setupcalled = PETSC_TRUE;
16083a40ed3dSBarry Smith   PetscFunctionReturn(0);
16099b94acceSBarry Smith }
16109b94acceSBarry Smith 
16114a2ae208SSatish Balay #undef __FUNCT__
161237596af1SLisandro Dalcin #define __FUNCT__ "SNESReset"
161337596af1SLisandro Dalcin /*@
161437596af1SLisandro Dalcin    SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats
161537596af1SLisandro Dalcin 
161637596af1SLisandro Dalcin    Collective on SNES
161737596af1SLisandro Dalcin 
161837596af1SLisandro Dalcin    Input Parameter:
161937596af1SLisandro Dalcin .  snes - iterative context obtained from SNESCreate()
162037596af1SLisandro Dalcin 
1621d25893d9SBarry Smith    Level: intermediate
1622d25893d9SBarry Smith 
1623d25893d9SBarry Smith    Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext()
162437596af1SLisandro Dalcin 
162537596af1SLisandro Dalcin .keywords: SNES, destroy
162637596af1SLisandro Dalcin 
162737596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve()
162837596af1SLisandro Dalcin @*/
162937596af1SLisandro Dalcin PetscErrorCode  SNESReset(SNES snes)
163037596af1SLisandro Dalcin {
163137596af1SLisandro Dalcin   PetscErrorCode ierr;
163237596af1SLisandro Dalcin 
163337596af1SLisandro Dalcin   PetscFunctionBegin;
163437596af1SLisandro Dalcin   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1635d25893d9SBarry Smith   if (snes->ops->userdestroy && snes->user) {
1636d25893d9SBarry Smith     ierr       = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr);
1637d25893d9SBarry Smith     snes->user = PETSC_NULL;
1638d25893d9SBarry Smith   }
1639644e2e5bSBarry Smith   if (snes->ops->computejacobian == SNESDefaultComputeJacobianColor && snes->dm) {
1640644e2e5bSBarry Smith     ierr = MatFDColoringDestroy((MatFDColoring*)&snes->jacP);CHKERRQ(ierr);
1641644e2e5bSBarry Smith     snes->ops->computejacobian = PETSC_NULL;
1642644e2e5bSBarry Smith   }
1643d25893d9SBarry Smith 
164437596af1SLisandro Dalcin   if (snes->ops->reset) {
164537596af1SLisandro Dalcin     ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr);
164637596af1SLisandro Dalcin   }
164737596af1SLisandro Dalcin   if (snes->ksp) {ierr = KSPReset(snes->ksp);CHKERRQ(ierr);}
16486bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
16496bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
16506bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr);
16516bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
16526bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
16536bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
165437596af1SLisandro Dalcin   if (snes->work) {ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);}
165537596af1SLisandro Dalcin   if (snes->vwork) {ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);}
165637596af1SLisandro Dalcin   snes->nwork = snes->nvwork = 0;
165737596af1SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
165837596af1SLisandro Dalcin   PetscFunctionReturn(0);
165937596af1SLisandro Dalcin }
166037596af1SLisandro Dalcin 
166137596af1SLisandro Dalcin #undef __FUNCT__
16624a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy"
166352baeb72SSatish Balay /*@
16649b94acceSBarry Smith    SNESDestroy - Destroys the nonlinear solver context that was created
16659b94acceSBarry Smith    with SNESCreate().
16669b94acceSBarry Smith 
1667c7afd0dbSLois Curfman McInnes    Collective on SNES
1668c7afd0dbSLois Curfman McInnes 
16699b94acceSBarry Smith    Input Parameter:
16709b94acceSBarry Smith .  snes - the SNES context
16719b94acceSBarry Smith 
167236851e7fSLois Curfman McInnes    Level: beginner
167336851e7fSLois Curfman McInnes 
16749b94acceSBarry Smith .keywords: SNES, nonlinear, destroy
16759b94acceSBarry Smith 
167663a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve()
16779b94acceSBarry Smith @*/
16786bf464f9SBarry Smith PetscErrorCode  SNESDestroy(SNES *snes)
16799b94acceSBarry Smith {
16806849ba73SBarry Smith   PetscErrorCode ierr;
16813a40ed3dSBarry Smith 
16823a40ed3dSBarry Smith   PetscFunctionBegin;
16836bf464f9SBarry Smith   if (!*snes) PetscFunctionReturn(0);
16846bf464f9SBarry Smith   PetscValidHeaderSpecific((*snes),SNES_CLASSID,1);
16856bf464f9SBarry Smith   if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);}
1686d4bb536fSBarry Smith 
16876bf464f9SBarry Smith   ierr = SNESReset((*snes));CHKERRQ(ierr);
16886b8b9a38SLisandro Dalcin 
1689be0abb6dSBarry Smith   /* if memory was published with AMS then destroy it */
16906bf464f9SBarry Smith   ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr);
16916bf464f9SBarry Smith   if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);}
16926d4c513bSLisandro Dalcin 
16936bf464f9SBarry Smith   ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr);
16946bf464f9SBarry Smith   ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr);
16956b8b9a38SLisandro Dalcin 
16966bf464f9SBarry Smith   ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr);
16976bf464f9SBarry Smith   if ((*snes)->ops->convergeddestroy) {
16986bf464f9SBarry Smith     ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr);
16996b8b9a38SLisandro Dalcin   }
17006bf464f9SBarry Smith   if ((*snes)->conv_malloc) {
17016bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr);
17026bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr);
170358c9b817SLisandro Dalcin   }
17046bf464f9SBarry Smith   ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr);
1705a79aaaedSSatish Balay   ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr);
17063a40ed3dSBarry Smith   PetscFunctionReturn(0);
17079b94acceSBarry Smith }
17089b94acceSBarry Smith 
17099b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */
17109b94acceSBarry Smith 
17114a2ae208SSatish Balay #undef __FUNCT__
1712a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner"
1713a8054027SBarry Smith /*@
1714a8054027SBarry Smith    SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.
1715a8054027SBarry Smith 
17163f9fe445SBarry Smith    Logically Collective on SNES
1717a8054027SBarry Smith 
1718a8054027SBarry Smith    Input Parameters:
1719a8054027SBarry Smith +  snes - the SNES context
1720a8054027SBarry 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
17213b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
1722a8054027SBarry Smith 
1723a8054027SBarry Smith    Options Database Keys:
1724a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
1725a8054027SBarry Smith 
1726a8054027SBarry Smith    Notes:
1727a8054027SBarry Smith    The default is 1
1728a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
1729a8054027SBarry Smith    If  -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use
1730a8054027SBarry Smith 
1731a8054027SBarry Smith    Level: intermediate
1732a8054027SBarry Smith 
1733a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
1734a8054027SBarry Smith 
1735e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
1736a8054027SBarry Smith 
1737a8054027SBarry Smith @*/
17387087cfbeSBarry Smith PetscErrorCode  SNESSetLagPreconditioner(SNES snes,PetscInt lag)
1739a8054027SBarry Smith {
1740a8054027SBarry Smith   PetscFunctionBegin;
17410700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1742e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
1743e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
1744c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
1745a8054027SBarry Smith   snes->lagpreconditioner = lag;
1746a8054027SBarry Smith   PetscFunctionReturn(0);
1747a8054027SBarry Smith }
1748a8054027SBarry Smith 
1749a8054027SBarry Smith #undef __FUNCT__
1750efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence"
1751efd51863SBarry Smith /*@
1752efd51863SBarry Smith    SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does
1753efd51863SBarry Smith 
1754efd51863SBarry Smith    Logically Collective on SNES
1755efd51863SBarry Smith 
1756efd51863SBarry Smith    Input Parameters:
1757efd51863SBarry Smith +  snes - the SNES context
1758efd51863SBarry Smith -  steps - the number of refinements to do, defaults to 0
1759efd51863SBarry Smith 
1760efd51863SBarry Smith    Options Database Keys:
1761efd51863SBarry Smith .    -snes_grid_sequence <steps>
1762efd51863SBarry Smith 
1763efd51863SBarry Smith    Level: intermediate
1764efd51863SBarry Smith 
1765efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
1766efd51863SBarry Smith 
1767efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
1768efd51863SBarry Smith 
1769efd51863SBarry Smith @*/
1770efd51863SBarry Smith PetscErrorCode  SNESSetGridSequence(SNES snes,PetscInt steps)
1771efd51863SBarry Smith {
1772efd51863SBarry Smith   PetscFunctionBegin;
1773efd51863SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1774efd51863SBarry Smith   PetscValidLogicalCollectiveInt(snes,steps,2);
1775efd51863SBarry Smith   snes->gridsequence = steps;
1776efd51863SBarry Smith   PetscFunctionReturn(0);
1777efd51863SBarry Smith }
1778efd51863SBarry Smith 
1779efd51863SBarry Smith #undef __FUNCT__
1780a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner"
1781a8054027SBarry Smith /*@
1782a8054027SBarry Smith    SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt
1783a8054027SBarry Smith 
17843f9fe445SBarry Smith    Not Collective
1785a8054027SBarry Smith 
1786a8054027SBarry Smith    Input Parameter:
1787a8054027SBarry Smith .  snes - the SNES context
1788a8054027SBarry Smith 
1789a8054027SBarry Smith    Output Parameter:
1790a8054027SBarry 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
17913b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
1792a8054027SBarry Smith 
1793a8054027SBarry Smith    Options Database Keys:
1794a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
1795a8054027SBarry Smith 
1796a8054027SBarry Smith    Notes:
1797a8054027SBarry Smith    The default is 1
1798a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
1799a8054027SBarry Smith 
1800a8054027SBarry Smith    Level: intermediate
1801a8054027SBarry Smith 
1802a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
1803a8054027SBarry Smith 
1804a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner()
1805a8054027SBarry Smith 
1806a8054027SBarry Smith @*/
18077087cfbeSBarry Smith PetscErrorCode  SNESGetLagPreconditioner(SNES snes,PetscInt *lag)
1808a8054027SBarry Smith {
1809a8054027SBarry Smith   PetscFunctionBegin;
18100700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1811a8054027SBarry Smith   *lag = snes->lagpreconditioner;
1812a8054027SBarry Smith   PetscFunctionReturn(0);
1813a8054027SBarry Smith }
1814a8054027SBarry Smith 
1815a8054027SBarry Smith #undef __FUNCT__
1816e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian"
1817e35cf81dSBarry Smith /*@
1818e35cf81dSBarry Smith    SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how
1819e35cf81dSBarry Smith      often the preconditioner is rebuilt.
1820e35cf81dSBarry Smith 
18213f9fe445SBarry Smith    Logically Collective on SNES
1822e35cf81dSBarry Smith 
1823e35cf81dSBarry Smith    Input Parameters:
1824e35cf81dSBarry Smith +  snes - the SNES context
1825e35cf81dSBarry 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
1826fe3ffe1eSBarry Smith          the Jacobian is built etc. -2 means rebuild at next chance but then never again
1827e35cf81dSBarry Smith 
1828e35cf81dSBarry Smith    Options Database Keys:
1829e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
1830e35cf81dSBarry Smith 
1831e35cf81dSBarry Smith    Notes:
1832e35cf81dSBarry Smith    The default is 1
1833e35cf81dSBarry Smith    The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
1834fe3ffe1eSBarry 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
1835fe3ffe1eSBarry Smith    at the next Newton step but never again (unless it is reset to another value)
1836e35cf81dSBarry Smith 
1837e35cf81dSBarry Smith    Level: intermediate
1838e35cf81dSBarry Smith 
1839e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
1840e35cf81dSBarry Smith 
1841e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian()
1842e35cf81dSBarry Smith 
1843e35cf81dSBarry Smith @*/
18447087cfbeSBarry Smith PetscErrorCode  SNESSetLagJacobian(SNES snes,PetscInt lag)
1845e35cf81dSBarry Smith {
1846e35cf81dSBarry Smith   PetscFunctionBegin;
18470700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1848e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
1849e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
1850c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
1851e35cf81dSBarry Smith   snes->lagjacobian = lag;
1852e35cf81dSBarry Smith   PetscFunctionReturn(0);
1853e35cf81dSBarry Smith }
1854e35cf81dSBarry Smith 
1855e35cf81dSBarry Smith #undef __FUNCT__
1856e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian"
1857e35cf81dSBarry Smith /*@
1858e35cf81dSBarry Smith    SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt
1859e35cf81dSBarry Smith 
18603f9fe445SBarry Smith    Not Collective
1861e35cf81dSBarry Smith 
1862e35cf81dSBarry Smith    Input Parameter:
1863e35cf81dSBarry Smith .  snes - the SNES context
1864e35cf81dSBarry Smith 
1865e35cf81dSBarry Smith    Output Parameter:
1866e35cf81dSBarry 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
1867e35cf81dSBarry Smith          the Jacobian is built etc.
1868e35cf81dSBarry Smith 
1869e35cf81dSBarry Smith    Options Database Keys:
1870e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
1871e35cf81dSBarry Smith 
1872e35cf81dSBarry Smith    Notes:
1873e35cf81dSBarry Smith    The default is 1
1874e35cf81dSBarry Smith    The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
1875e35cf81dSBarry Smith 
1876e35cf81dSBarry Smith    Level: intermediate
1877e35cf81dSBarry Smith 
1878e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
1879e35cf81dSBarry Smith 
1880e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner()
1881e35cf81dSBarry Smith 
1882e35cf81dSBarry Smith @*/
18837087cfbeSBarry Smith PetscErrorCode  SNESGetLagJacobian(SNES snes,PetscInt *lag)
1884e35cf81dSBarry Smith {
1885e35cf81dSBarry Smith   PetscFunctionBegin;
18860700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1887e35cf81dSBarry Smith   *lag = snes->lagjacobian;
1888e35cf81dSBarry Smith   PetscFunctionReturn(0);
1889e35cf81dSBarry Smith }
1890e35cf81dSBarry Smith 
1891e35cf81dSBarry Smith #undef __FUNCT__
18924a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances"
18939b94acceSBarry Smith /*@
1894d7a720efSLois Curfman McInnes    SNESSetTolerances - Sets various parameters used in convergence tests.
18959b94acceSBarry Smith 
18963f9fe445SBarry Smith    Logically Collective on SNES
1897c7afd0dbSLois Curfman McInnes 
18989b94acceSBarry Smith    Input Parameters:
1899c7afd0dbSLois Curfman McInnes +  snes - the SNES context
190070441072SBarry Smith .  abstol - absolute convergence tolerance
190133174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
190233174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
190333174efeSLois Curfman McInnes            of the change in the solution between steps
190433174efeSLois Curfman McInnes .  maxit - maximum number of iterations
1905c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
1906fee21e36SBarry Smith 
190733174efeSLois Curfman McInnes    Options Database Keys:
190870441072SBarry Smith +    -snes_atol <abstol> - Sets abstol
1909c7afd0dbSLois Curfman McInnes .    -snes_rtol <rtol> - Sets rtol
1910c7afd0dbSLois Curfman McInnes .    -snes_stol <stol> - Sets stol
1911c7afd0dbSLois Curfman McInnes .    -snes_max_it <maxit> - Sets maxit
1912c7afd0dbSLois Curfman McInnes -    -snes_max_funcs <maxf> - Sets maxf
19139b94acceSBarry Smith 
1914d7a720efSLois Curfman McInnes    Notes:
19159b94acceSBarry Smith    The default maximum number of iterations is 50.
19169b94acceSBarry Smith    The default maximum number of function evaluations is 1000.
19179b94acceSBarry Smith 
191836851e7fSLois Curfman McInnes    Level: intermediate
191936851e7fSLois Curfman McInnes 
192033174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances
19219b94acceSBarry Smith 
19222492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance()
19239b94acceSBarry Smith @*/
19247087cfbeSBarry Smith PetscErrorCode  SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
19259b94acceSBarry Smith {
19263a40ed3dSBarry Smith   PetscFunctionBegin;
19270700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1928c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,abstol,2);
1929c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol,3);
1930c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,stol,4);
1931c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxit,5);
1932c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxf,6);
1933c5eb9154SBarry Smith 
193470441072SBarry Smith   if (abstol != PETSC_DEFAULT)  snes->abstol      = abstol;
1935d7a720efSLois Curfman McInnes   if (rtol != PETSC_DEFAULT)  snes->rtol      = rtol;
1936d7a720efSLois Curfman McInnes   if (stol != PETSC_DEFAULT)  snes->xtol      = stol;
1937d7a720efSLois Curfman McInnes   if (maxit != PETSC_DEFAULT) snes->max_its   = maxit;
1938d7a720efSLois Curfman McInnes   if (maxf != PETSC_DEFAULT)  snes->max_funcs = maxf;
19393a40ed3dSBarry Smith   PetscFunctionReturn(0);
19409b94acceSBarry Smith }
19419b94acceSBarry Smith 
19424a2ae208SSatish Balay #undef __FUNCT__
19434a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances"
19449b94acceSBarry Smith /*@
194533174efeSLois Curfman McInnes    SNESGetTolerances - Gets various parameters used in convergence tests.
194633174efeSLois Curfman McInnes 
1947c7afd0dbSLois Curfman McInnes    Not Collective
1948c7afd0dbSLois Curfman McInnes 
194933174efeSLois Curfman McInnes    Input Parameters:
1950c7afd0dbSLois Curfman McInnes +  snes - the SNES context
195185385478SLisandro Dalcin .  atol - absolute convergence tolerance
195233174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
195333174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
195433174efeSLois Curfman McInnes            of the change in the solution between steps
195533174efeSLois Curfman McInnes .  maxit - maximum number of iterations
1956c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
1957fee21e36SBarry Smith 
195833174efeSLois Curfman McInnes    Notes:
195933174efeSLois Curfman McInnes    The user can specify PETSC_NULL for any parameter that is not needed.
196033174efeSLois Curfman McInnes 
196136851e7fSLois Curfman McInnes    Level: intermediate
196236851e7fSLois Curfman McInnes 
196333174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances
196433174efeSLois Curfman McInnes 
196533174efeSLois Curfman McInnes .seealso: SNESSetTolerances()
196633174efeSLois Curfman McInnes @*/
19677087cfbeSBarry Smith PetscErrorCode  SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
196833174efeSLois Curfman McInnes {
19693a40ed3dSBarry Smith   PetscFunctionBegin;
19700700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
197185385478SLisandro Dalcin   if (atol)  *atol  = snes->abstol;
197233174efeSLois Curfman McInnes   if (rtol)  *rtol  = snes->rtol;
197333174efeSLois Curfman McInnes   if (stol)  *stol  = snes->xtol;
197433174efeSLois Curfman McInnes   if (maxit) *maxit = snes->max_its;
197533174efeSLois Curfman McInnes   if (maxf)  *maxf  = snes->max_funcs;
19763a40ed3dSBarry Smith   PetscFunctionReturn(0);
197733174efeSLois Curfman McInnes }
197833174efeSLois Curfman McInnes 
19794a2ae208SSatish Balay #undef __FUNCT__
19804a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance"
198133174efeSLois Curfman McInnes /*@
19829b94acceSBarry Smith    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
19839b94acceSBarry Smith 
19843f9fe445SBarry Smith    Logically Collective on SNES
1985fee21e36SBarry Smith 
1986c7afd0dbSLois Curfman McInnes    Input Parameters:
1987c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1988c7afd0dbSLois Curfman McInnes -  tol - tolerance
1989c7afd0dbSLois Curfman McInnes 
19909b94acceSBarry Smith    Options Database Key:
1991c7afd0dbSLois Curfman McInnes .  -snes_trtol <tol> - Sets tol
19929b94acceSBarry Smith 
199336851e7fSLois Curfman McInnes    Level: intermediate
199436851e7fSLois Curfman McInnes 
19959b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance
19969b94acceSBarry Smith 
19972492ecdbSBarry Smith .seealso: SNESSetTolerances()
19989b94acceSBarry Smith @*/
19997087cfbeSBarry Smith PetscErrorCode  SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
20009b94acceSBarry Smith {
20013a40ed3dSBarry Smith   PetscFunctionBegin;
20020700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2003c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,tol,2);
20049b94acceSBarry Smith   snes->deltatol = tol;
20053a40ed3dSBarry Smith   PetscFunctionReturn(0);
20069b94acceSBarry Smith }
20079b94acceSBarry Smith 
2008df9fa365SBarry Smith /*
2009df9fa365SBarry Smith    Duplicate the lg monitors for SNES from KSP; for some reason with
2010df9fa365SBarry Smith    dynamic libraries things don't work under Sun4 if we just use
2011df9fa365SBarry Smith    macros instead of functions
2012df9fa365SBarry Smith */
20134a2ae208SSatish Balay #undef __FUNCT__
2014a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG"
20157087cfbeSBarry Smith PetscErrorCode  SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx)
2016ce1608b8SBarry Smith {
2017dfbe8321SBarry Smith   PetscErrorCode ierr;
2018ce1608b8SBarry Smith 
2019ce1608b8SBarry Smith   PetscFunctionBegin;
20200700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2021a6570f20SBarry Smith   ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr);
2022ce1608b8SBarry Smith   PetscFunctionReturn(0);
2023ce1608b8SBarry Smith }
2024ce1608b8SBarry Smith 
20254a2ae208SSatish Balay #undef __FUNCT__
2026a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate"
20277087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2028df9fa365SBarry Smith {
2029dfbe8321SBarry Smith   PetscErrorCode ierr;
2030df9fa365SBarry Smith 
2031df9fa365SBarry Smith   PetscFunctionBegin;
2032a6570f20SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2033df9fa365SBarry Smith   PetscFunctionReturn(0);
2034df9fa365SBarry Smith }
2035df9fa365SBarry Smith 
20364a2ae208SSatish Balay #undef __FUNCT__
2037a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy"
20386bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGDestroy(PetscDrawLG *draw)
2039df9fa365SBarry Smith {
2040dfbe8321SBarry Smith   PetscErrorCode ierr;
2041df9fa365SBarry Smith 
2042df9fa365SBarry Smith   PetscFunctionBegin;
2043a6570f20SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2044df9fa365SBarry Smith   PetscFunctionReturn(0);
2045df9fa365SBarry Smith }
2046df9fa365SBarry Smith 
20477087cfbeSBarry Smith extern PetscErrorCode  SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
2048b271bb04SBarry Smith #undef __FUNCT__
2049b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange"
20507087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx)
2051b271bb04SBarry Smith {
2052b271bb04SBarry Smith   PetscDrawLG      lg;
2053b271bb04SBarry Smith   PetscErrorCode   ierr;
2054b271bb04SBarry Smith   PetscReal        x,y,per;
2055b271bb04SBarry Smith   PetscViewer      v = (PetscViewer)monctx;
2056b271bb04SBarry Smith   static PetscReal prev; /* should be in the context */
2057b271bb04SBarry Smith   PetscDraw        draw;
2058b271bb04SBarry Smith   PetscFunctionBegin;
2059b271bb04SBarry Smith   if (!monctx) {
2060b271bb04SBarry Smith     MPI_Comm    comm;
2061b271bb04SBarry Smith 
2062b271bb04SBarry Smith     ierr   = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
2063b271bb04SBarry Smith     v      = PETSC_VIEWER_DRAW_(comm);
2064b271bb04SBarry Smith   }
2065b271bb04SBarry Smith   ierr   = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr);
2066b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2067b271bb04SBarry Smith   ierr   = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2068b271bb04SBarry Smith   ierr   = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr);
2069b271bb04SBarry Smith   x = (PetscReal) n;
2070b271bb04SBarry Smith   if (rnorm > 0.0) y = log10(rnorm); else y = -15.0;
2071b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2072b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2073b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2074b271bb04SBarry Smith   }
2075b271bb04SBarry Smith 
2076b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr);
2077b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2078b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2079b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr);
2080b271bb04SBarry Smith   ierr =  SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr);
2081b271bb04SBarry Smith   x = (PetscReal) n;
2082b271bb04SBarry Smith   y = 100.0*per;
2083b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2084b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2085b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2086b271bb04SBarry Smith   }
2087b271bb04SBarry Smith 
2088b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr);
2089b271bb04SBarry Smith   if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2090b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2091b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr);
2092b271bb04SBarry Smith   x = (PetscReal) n;
2093b271bb04SBarry Smith   y = (prev - rnorm)/prev;
2094b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2095b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2096b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2097b271bb04SBarry Smith   }
2098b271bb04SBarry Smith 
2099b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr);
2100b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2101b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2102b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr);
2103b271bb04SBarry Smith   x = (PetscReal) n;
2104b271bb04SBarry Smith   y = (prev - rnorm)/(prev*per);
2105b271bb04SBarry Smith   if (n > 2) { /*skip initial crazy value */
2106b271bb04SBarry Smith     ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2107b271bb04SBarry Smith   }
2108b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2109b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2110b271bb04SBarry Smith   }
2111b271bb04SBarry Smith   prev = rnorm;
2112b271bb04SBarry Smith   PetscFunctionReturn(0);
2113b271bb04SBarry Smith }
2114b271bb04SBarry Smith 
2115b271bb04SBarry Smith #undef __FUNCT__
2116b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate"
21177087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2118b271bb04SBarry Smith {
2119b271bb04SBarry Smith   PetscErrorCode ierr;
2120b271bb04SBarry Smith 
2121b271bb04SBarry Smith   PetscFunctionBegin;
2122b271bb04SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2123b271bb04SBarry Smith   PetscFunctionReturn(0);
2124b271bb04SBarry Smith }
2125b271bb04SBarry Smith 
2126b271bb04SBarry Smith #undef __FUNCT__
2127b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy"
21286bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGRangeDestroy(PetscDrawLG *draw)
2129b271bb04SBarry Smith {
2130b271bb04SBarry Smith   PetscErrorCode ierr;
2131b271bb04SBarry Smith 
2132b271bb04SBarry Smith   PetscFunctionBegin;
2133b271bb04SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2134b271bb04SBarry Smith   PetscFunctionReturn(0);
2135b271bb04SBarry Smith }
2136b271bb04SBarry Smith 
21377a03ce2fSLisandro Dalcin #undef __FUNCT__
21387a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor"
21397a03ce2fSLisandro Dalcin /*
21407a03ce2fSLisandro Dalcin      Runs the user provided monitor routines, if they exists.
21417a03ce2fSLisandro Dalcin */
21427a03ce2fSLisandro Dalcin PetscErrorCode  SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm)
21437a03ce2fSLisandro Dalcin {
21447a03ce2fSLisandro Dalcin   PetscErrorCode ierr;
21457a03ce2fSLisandro Dalcin   PetscInt       i,n = snes->numbermonitors;
21467a03ce2fSLisandro Dalcin 
21477a03ce2fSLisandro Dalcin   PetscFunctionBegin;
21487a03ce2fSLisandro Dalcin   for (i=0; i<n; i++) {
21497a03ce2fSLisandro Dalcin     ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr);
21507a03ce2fSLisandro Dalcin   }
21517a03ce2fSLisandro Dalcin   PetscFunctionReturn(0);
21527a03ce2fSLisandro Dalcin }
21537a03ce2fSLisandro Dalcin 
21549b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */
21559b94acceSBarry Smith 
21564a2ae208SSatish Balay #undef __FUNCT__
2157a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet"
21589b94acceSBarry Smith /*@C
2159a6570f20SBarry Smith    SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
21609b94acceSBarry Smith    iteration of the nonlinear solver to display the iteration's
21619b94acceSBarry Smith    progress.
21629b94acceSBarry Smith 
21633f9fe445SBarry Smith    Logically Collective on SNES
2164fee21e36SBarry Smith 
2165c7afd0dbSLois Curfman McInnes    Input Parameters:
2166c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2167c7afd0dbSLois Curfman McInnes .  func - monitoring routine
2168b8a78c4aSBarry Smith .  mctx - [optional] user-defined context for private data for the
2169e8105e01SRichard Katz           monitor routine (use PETSC_NULL if no context is desired)
2170b3006f0bSLois Curfman McInnes -  monitordestroy - [optional] routine that frees monitor context
2171b3006f0bSLois Curfman McInnes           (may be PETSC_NULL)
21729b94acceSBarry Smith 
2173c7afd0dbSLois Curfman McInnes    Calling sequence of func:
2174a7cc72afSBarry Smith $     int func(SNES snes,PetscInt its, PetscReal norm,void *mctx)
2175c7afd0dbSLois Curfman McInnes 
2176c7afd0dbSLois Curfman McInnes +    snes - the SNES context
2177c7afd0dbSLois Curfman McInnes .    its - iteration number
2178c7afd0dbSLois Curfman McInnes .    norm - 2-norm function value (may be estimated)
217940a0c1c6SLois Curfman McInnes -    mctx - [optional] monitoring context
21809b94acceSBarry Smith 
21819665c990SLois Curfman McInnes    Options Database Keys:
2182a6570f20SBarry Smith +    -snes_monitor        - sets SNESMonitorDefault()
2183a6570f20SBarry Smith .    -snes_monitor_draw    - sets line graph monitor,
2184a6570f20SBarry Smith                             uses SNESMonitorLGCreate()
2185cca6129bSJed Brown -    -snes_monitor_cancel - cancels all monitors that have
2186c7afd0dbSLois Curfman McInnes                             been hardwired into a code by
2187a6570f20SBarry Smith                             calls to SNESMonitorSet(), but
2188c7afd0dbSLois Curfman McInnes                             does not cancel those set via
2189c7afd0dbSLois Curfman McInnes                             the options database.
21909665c990SLois Curfman McInnes 
2191639f9d9dSBarry Smith    Notes:
21926bc08f3fSLois Curfman McInnes    Several different monitoring routines may be set by calling
2193a6570f20SBarry Smith    SNESMonitorSet() multiple times; all will be called in the
21946bc08f3fSLois Curfman McInnes    order in which they were set.
2195639f9d9dSBarry Smith 
2196025f1a04SBarry Smith    Fortran notes: Only a single monitor function can be set for each SNES object
2197025f1a04SBarry Smith 
219836851e7fSLois Curfman McInnes    Level: intermediate
219936851e7fSLois Curfman McInnes 
22009b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor
22019b94acceSBarry Smith 
2202a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel()
22039b94acceSBarry Smith @*/
2204c2efdce3SBarry Smith PetscErrorCode  SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
22059b94acceSBarry Smith {
2206b90d0a6eSBarry Smith   PetscInt       i;
2207649052a6SBarry Smith   PetscErrorCode ierr;
2208b90d0a6eSBarry Smith 
22093a40ed3dSBarry Smith   PetscFunctionBegin;
22100700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
221117186662SBarry Smith   if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
2212b90d0a6eSBarry Smith   for (i=0; i<snes->numbermonitors;i++) {
2213649052a6SBarry Smith     if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) {
2214649052a6SBarry Smith       if (monitordestroy) {
2215c2efdce3SBarry Smith         ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr);
2216649052a6SBarry Smith       }
2217b90d0a6eSBarry Smith       PetscFunctionReturn(0);
2218b90d0a6eSBarry Smith     }
2219b90d0a6eSBarry Smith   }
2220b90d0a6eSBarry Smith   snes->monitor[snes->numbermonitors]           = monitor;
2221b8a78c4aSBarry Smith   snes->monitordestroy[snes->numbermonitors]    = monitordestroy;
2222639f9d9dSBarry Smith   snes->monitorcontext[snes->numbermonitors++]  = (void*)mctx;
22233a40ed3dSBarry Smith   PetscFunctionReturn(0);
22249b94acceSBarry Smith }
22259b94acceSBarry Smith 
22264a2ae208SSatish Balay #undef __FUNCT__
2227a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel"
22285cd90555SBarry Smith /*@C
2229a6570f20SBarry Smith    SNESMonitorCancel - Clears all the monitor functions for a SNES object.
22305cd90555SBarry Smith 
22313f9fe445SBarry Smith    Logically Collective on SNES
2232c7afd0dbSLois Curfman McInnes 
22335cd90555SBarry Smith    Input Parameters:
22345cd90555SBarry Smith .  snes - the SNES context
22355cd90555SBarry Smith 
22361a480d89SAdministrator    Options Database Key:
2237a6570f20SBarry Smith .  -snes_monitor_cancel - cancels all monitors that have been hardwired
2238a6570f20SBarry Smith     into a code by calls to SNESMonitorSet(), but does not cancel those
2239c7afd0dbSLois Curfman McInnes     set via the options database
22405cd90555SBarry Smith 
22415cd90555SBarry Smith    Notes:
22425cd90555SBarry Smith    There is no way to clear one specific monitor from a SNES object.
22435cd90555SBarry Smith 
224436851e7fSLois Curfman McInnes    Level: intermediate
224536851e7fSLois Curfman McInnes 
22465cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor
22475cd90555SBarry Smith 
2248a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet()
22495cd90555SBarry Smith @*/
22507087cfbeSBarry Smith PetscErrorCode  SNESMonitorCancel(SNES snes)
22515cd90555SBarry Smith {
2252d952e501SBarry Smith   PetscErrorCode ierr;
2253d952e501SBarry Smith   PetscInt       i;
2254d952e501SBarry Smith 
22555cd90555SBarry Smith   PetscFunctionBegin;
22560700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2257d952e501SBarry Smith   for (i=0; i<snes->numbermonitors; i++) {
2258d952e501SBarry Smith     if (snes->monitordestroy[i]) {
22593c4aec1bSBarry Smith       ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr);
2260d952e501SBarry Smith     }
2261d952e501SBarry Smith   }
22625cd90555SBarry Smith   snes->numbermonitors = 0;
22635cd90555SBarry Smith   PetscFunctionReturn(0);
22645cd90555SBarry Smith }
22655cd90555SBarry Smith 
22664a2ae208SSatish Balay #undef __FUNCT__
22674a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest"
22689b94acceSBarry Smith /*@C
22699b94acceSBarry Smith    SNESSetConvergenceTest - Sets the function that is to be used
22709b94acceSBarry Smith    to test for convergence of the nonlinear iterative solution.
22719b94acceSBarry Smith 
22723f9fe445SBarry Smith    Logically Collective on SNES
2273fee21e36SBarry Smith 
2274c7afd0dbSLois Curfman McInnes    Input Parameters:
2275c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2276c7afd0dbSLois Curfman McInnes .  func - routine to test for convergence
22777f7931b9SBarry Smith .  cctx - [optional] context for private data for the convergence routine  (may be PETSC_NULL)
22787f7931b9SBarry Smith -  destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran)
22799b94acceSBarry Smith 
2280c7afd0dbSLois Curfman McInnes    Calling sequence of func:
228106ee9f85SBarry Smith $     PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
2282c7afd0dbSLois Curfman McInnes 
2283c7afd0dbSLois Curfman McInnes +    snes - the SNES context
228406ee9f85SBarry Smith .    it - current iteration (0 is the first and is before any Newton step)
2285c7afd0dbSLois Curfman McInnes .    cctx - [optional] convergence context
2286184914b5SBarry Smith .    reason - reason for convergence/divergence
2287c7afd0dbSLois Curfman McInnes .    xnorm - 2-norm of current iterate
22884b27c08aSLois Curfman McInnes .    gnorm - 2-norm of current step
22894b27c08aSLois Curfman McInnes -    f - 2-norm of function
22909b94acceSBarry Smith 
229136851e7fSLois Curfman McInnes    Level: advanced
229236851e7fSLois Curfman McInnes 
22939b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test
22949b94acceSBarry Smith 
229585385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged()
22969b94acceSBarry Smith @*/
22977087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
22989b94acceSBarry Smith {
22997f7931b9SBarry Smith   PetscErrorCode ierr;
23007f7931b9SBarry Smith 
23013a40ed3dSBarry Smith   PetscFunctionBegin;
23020700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
230385385478SLisandro Dalcin   if (!func) func = SNESSkipConverged;
23047f7931b9SBarry Smith   if (snes->ops->convergeddestroy) {
23057f7931b9SBarry Smith     ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr);
23067f7931b9SBarry Smith   }
230785385478SLisandro Dalcin   snes->ops->converged        = func;
23087f7931b9SBarry Smith   snes->ops->convergeddestroy = destroy;
230985385478SLisandro Dalcin   snes->cnvP                  = cctx;
23103a40ed3dSBarry Smith   PetscFunctionReturn(0);
23119b94acceSBarry Smith }
23129b94acceSBarry Smith 
23134a2ae208SSatish Balay #undef __FUNCT__
23144a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason"
231552baeb72SSatish Balay /*@
2316184914b5SBarry Smith    SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
2317184914b5SBarry Smith 
2318184914b5SBarry Smith    Not Collective
2319184914b5SBarry Smith 
2320184914b5SBarry Smith    Input Parameter:
2321184914b5SBarry Smith .  snes - the SNES context
2322184914b5SBarry Smith 
2323184914b5SBarry Smith    Output Parameter:
23244d0a8057SBarry Smith .  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
2325184914b5SBarry Smith             manual pages for the individual convergence tests for complete lists
2326184914b5SBarry Smith 
2327184914b5SBarry Smith    Level: intermediate
2328184914b5SBarry Smith 
2329184914b5SBarry Smith    Notes: Can only be called after the call the SNESSolve() is complete.
2330184914b5SBarry Smith 
2331184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test
2332184914b5SBarry Smith 
233385385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason
2334184914b5SBarry Smith @*/
23357087cfbeSBarry Smith PetscErrorCode  SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
2336184914b5SBarry Smith {
2337184914b5SBarry Smith   PetscFunctionBegin;
23380700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
23394482741eSBarry Smith   PetscValidPointer(reason,2);
2340184914b5SBarry Smith   *reason = snes->reason;
2341184914b5SBarry Smith   PetscFunctionReturn(0);
2342184914b5SBarry Smith }
2343184914b5SBarry Smith 
23444a2ae208SSatish Balay #undef __FUNCT__
23454a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory"
2346c9005455SLois Curfman McInnes /*@
2347c9005455SLois Curfman McInnes    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
2348c9005455SLois Curfman McInnes 
23493f9fe445SBarry Smith    Logically Collective on SNES
2350fee21e36SBarry Smith 
2351c7afd0dbSLois Curfman McInnes    Input Parameters:
2352c7afd0dbSLois Curfman McInnes +  snes - iterative context obtained from SNESCreate()
23538c7482ecSBarry Smith .  a   - array to hold history, this array will contain the function norms computed at each step
2354cd5578b5SBarry Smith .  its - integer array holds the number of linear iterations for each solve.
2355758f92a0SBarry Smith .  na  - size of a and its
235664731454SLois Curfman McInnes -  reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
2357758f92a0SBarry Smith            else it continues storing new values for new nonlinear solves after the old ones
2358c7afd0dbSLois Curfman McInnes 
2359308dcc3eSBarry Smith    Notes:
2360308dcc3eSBarry Smith    If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a
2361308dcc3eSBarry Smith    default array of length 10000 is allocated.
2362308dcc3eSBarry Smith 
2363c9005455SLois Curfman McInnes    This routine is useful, e.g., when running a code for purposes
2364c9005455SLois Curfman McInnes    of accurate performance monitoring, when no I/O should be done
2365c9005455SLois Curfman McInnes    during the section of code that is being timed.
2366c9005455SLois Curfman McInnes 
236736851e7fSLois Curfman McInnes    Level: intermediate
236836851e7fSLois Curfman McInnes 
2369c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history
2370758f92a0SBarry Smith 
237108405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory()
2372758f92a0SBarry Smith 
2373c9005455SLois Curfman McInnes @*/
23747087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool  reset)
2375c9005455SLois Curfman McInnes {
2376308dcc3eSBarry Smith   PetscErrorCode ierr;
2377308dcc3eSBarry Smith 
23783a40ed3dSBarry Smith   PetscFunctionBegin;
23790700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
23804482741eSBarry Smith   if (na)  PetscValidScalarPointer(a,2);
2381a562a398SLisandro Dalcin   if (its) PetscValidIntPointer(its,3);
2382308dcc3eSBarry Smith   if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) {
2383308dcc3eSBarry Smith     if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
2384308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr);
2385308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr);
2386308dcc3eSBarry Smith     snes->conv_malloc   = PETSC_TRUE;
2387308dcc3eSBarry Smith   }
2388c9005455SLois Curfman McInnes   snes->conv_hist       = a;
2389758f92a0SBarry Smith   snes->conv_hist_its   = its;
2390758f92a0SBarry Smith   snes->conv_hist_max   = na;
2391a12bc48fSLisandro Dalcin   snes->conv_hist_len   = 0;
2392758f92a0SBarry Smith   snes->conv_hist_reset = reset;
2393758f92a0SBarry Smith   PetscFunctionReturn(0);
2394758f92a0SBarry Smith }
2395758f92a0SBarry Smith 
2396308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
2397c6db04a5SJed Brown #include <engine.h>   /* MATLAB include file */
2398c6db04a5SJed Brown #include <mex.h>      /* MATLAB include file */
2399308dcc3eSBarry Smith EXTERN_C_BEGIN
2400308dcc3eSBarry Smith #undef __FUNCT__
2401308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab"
2402308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes)
2403308dcc3eSBarry Smith {
2404308dcc3eSBarry Smith   mxArray        *mat;
2405308dcc3eSBarry Smith   PetscInt       i;
2406308dcc3eSBarry Smith   PetscReal      *ar;
2407308dcc3eSBarry Smith 
2408308dcc3eSBarry Smith   PetscFunctionBegin;
2409308dcc3eSBarry Smith   mat  = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL);
2410308dcc3eSBarry Smith   ar   = (PetscReal*) mxGetData(mat);
2411308dcc3eSBarry Smith   for (i=0; i<snes->conv_hist_len; i++) {
2412308dcc3eSBarry Smith     ar[i] = snes->conv_hist[i];
2413308dcc3eSBarry Smith   }
2414308dcc3eSBarry Smith   PetscFunctionReturn(mat);
2415308dcc3eSBarry Smith }
2416308dcc3eSBarry Smith EXTERN_C_END
2417308dcc3eSBarry Smith #endif
2418308dcc3eSBarry Smith 
2419308dcc3eSBarry Smith 
24204a2ae208SSatish Balay #undef __FUNCT__
24214a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory"
24220c4c9dddSBarry Smith /*@C
2423758f92a0SBarry Smith    SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
2424758f92a0SBarry Smith 
24253f9fe445SBarry Smith    Not Collective
2426758f92a0SBarry Smith 
2427758f92a0SBarry Smith    Input Parameter:
2428758f92a0SBarry Smith .  snes - iterative context obtained from SNESCreate()
2429758f92a0SBarry Smith 
2430758f92a0SBarry Smith    Output Parameters:
2431758f92a0SBarry Smith .  a   - array to hold history
2432758f92a0SBarry Smith .  its - integer array holds the number of linear iterations (or
2433758f92a0SBarry Smith          negative if not converged) for each solve.
2434758f92a0SBarry Smith -  na  - size of a and its
2435758f92a0SBarry Smith 
2436758f92a0SBarry Smith    Notes:
2437758f92a0SBarry Smith     The calling sequence for this routine in Fortran is
2438758f92a0SBarry Smith $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
2439758f92a0SBarry Smith 
2440758f92a0SBarry Smith    This routine is useful, e.g., when running a code for purposes
2441758f92a0SBarry Smith    of accurate performance monitoring, when no I/O should be done
2442758f92a0SBarry Smith    during the section of code that is being timed.
2443758f92a0SBarry Smith 
2444758f92a0SBarry Smith    Level: intermediate
2445758f92a0SBarry Smith 
2446758f92a0SBarry Smith .keywords: SNES, get, convergence, history
2447758f92a0SBarry Smith 
2448758f92a0SBarry Smith .seealso: SNESSetConvergencHistory()
2449758f92a0SBarry Smith 
2450758f92a0SBarry Smith @*/
24517087cfbeSBarry Smith PetscErrorCode  SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
2452758f92a0SBarry Smith {
2453758f92a0SBarry Smith   PetscFunctionBegin;
24540700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2455758f92a0SBarry Smith   if (a)   *a   = snes->conv_hist;
2456758f92a0SBarry Smith   if (its) *its = snes->conv_hist_its;
2457758f92a0SBarry Smith   if (na)  *na  = snes->conv_hist_len;
24583a40ed3dSBarry Smith   PetscFunctionReturn(0);
2459c9005455SLois Curfman McInnes }
2460c9005455SLois Curfman McInnes 
2461e74ef692SMatthew Knepley #undef __FUNCT__
2462e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate"
2463ac226902SBarry Smith /*@C
246476b2cf59SMatthew Knepley   SNESSetUpdate - Sets the general-purpose update function called
2465eec8f646SJed Brown   at the beginning of every iteration of the nonlinear solve. Specifically
24667e4bb74cSBarry Smith   it is called just before the Jacobian is "evaluated".
246776b2cf59SMatthew Knepley 
24683f9fe445SBarry Smith   Logically Collective on SNES
246976b2cf59SMatthew Knepley 
247076b2cf59SMatthew Knepley   Input Parameters:
247176b2cf59SMatthew Knepley . snes - The nonlinear solver context
247276b2cf59SMatthew Knepley . func - The function
247376b2cf59SMatthew Knepley 
247476b2cf59SMatthew Knepley   Calling sequence of func:
2475b5d30489SBarry Smith . func (SNES snes, PetscInt step);
247676b2cf59SMatthew Knepley 
247776b2cf59SMatthew Knepley . step - The current step of the iteration
247876b2cf59SMatthew Knepley 
2479fe97e370SBarry Smith   Level: advanced
2480fe97e370SBarry Smith 
2481fe97e370SBarry 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()
2482fe97e370SBarry Smith         This is not used by most users.
248376b2cf59SMatthew Knepley 
248476b2cf59SMatthew Knepley .keywords: SNES, update
2485b5d30489SBarry Smith 
248685385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve()
248776b2cf59SMatthew Knepley @*/
24887087cfbeSBarry Smith PetscErrorCode  SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
248976b2cf59SMatthew Knepley {
249076b2cf59SMatthew Knepley   PetscFunctionBegin;
24910700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID,1);
2492e7788613SBarry Smith   snes->ops->update = func;
249376b2cf59SMatthew Knepley   PetscFunctionReturn(0);
249476b2cf59SMatthew Knepley }
249576b2cf59SMatthew Knepley 
2496e74ef692SMatthew Knepley #undef __FUNCT__
2497e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate"
249876b2cf59SMatthew Knepley /*@
249976b2cf59SMatthew Knepley   SNESDefaultUpdate - The default update function which does nothing.
250076b2cf59SMatthew Knepley 
250176b2cf59SMatthew Knepley   Not collective
250276b2cf59SMatthew Knepley 
250376b2cf59SMatthew Knepley   Input Parameters:
250476b2cf59SMatthew Knepley . snes - The nonlinear solver context
250576b2cf59SMatthew Knepley . step - The current step of the iteration
250676b2cf59SMatthew Knepley 
2507205452f4SMatthew Knepley   Level: intermediate
2508205452f4SMatthew Knepley 
250976b2cf59SMatthew Knepley .keywords: SNES, update
2510a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC()
251176b2cf59SMatthew Knepley @*/
25127087cfbeSBarry Smith PetscErrorCode  SNESDefaultUpdate(SNES snes, PetscInt step)
251376b2cf59SMatthew Knepley {
251476b2cf59SMatthew Knepley   PetscFunctionBegin;
251576b2cf59SMatthew Knepley   PetscFunctionReturn(0);
251676b2cf59SMatthew Knepley }
251776b2cf59SMatthew Knepley 
25184a2ae208SSatish Balay #undef __FUNCT__
25194a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private"
25209b94acceSBarry Smith /*
25219b94acceSBarry Smith    SNESScaleStep_Private - Scales a step so that its length is less than the
25229b94acceSBarry Smith    positive parameter delta.
25239b94acceSBarry Smith 
25249b94acceSBarry Smith     Input Parameters:
2525c7afd0dbSLois Curfman McInnes +   snes - the SNES context
25269b94acceSBarry Smith .   y - approximate solution of linear system
25279b94acceSBarry Smith .   fnorm - 2-norm of current function
2528c7afd0dbSLois Curfman McInnes -   delta - trust region size
25299b94acceSBarry Smith 
25309b94acceSBarry Smith     Output Parameters:
2531c7afd0dbSLois Curfman McInnes +   gpnorm - predicted function norm at the new point, assuming local
25329b94acceSBarry Smith     linearization.  The value is zero if the step lies within the trust
25339b94acceSBarry Smith     region, and exceeds zero otherwise.
2534c7afd0dbSLois Curfman McInnes -   ynorm - 2-norm of the step
25359b94acceSBarry Smith 
25369b94acceSBarry Smith     Note:
25374b27c08aSLois Curfman McInnes     For non-trust region methods such as SNESLS, the parameter delta
25389b94acceSBarry Smith     is set to be the maximum allowable step size.
25399b94acceSBarry Smith 
25409b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step
25419b94acceSBarry Smith */
2542dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
25439b94acceSBarry Smith {
2544064f8208SBarry Smith   PetscReal      nrm;
2545ea709b57SSatish Balay   PetscScalar    cnorm;
2546dfbe8321SBarry Smith   PetscErrorCode ierr;
25473a40ed3dSBarry Smith 
25483a40ed3dSBarry Smith   PetscFunctionBegin;
25490700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
25500700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
2551c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,2);
2552184914b5SBarry Smith 
2553064f8208SBarry Smith   ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr);
2554064f8208SBarry Smith   if (nrm > *delta) {
2555064f8208SBarry Smith      nrm = *delta/nrm;
2556064f8208SBarry Smith      *gpnorm = (1.0 - nrm)*(*fnorm);
2557064f8208SBarry Smith      cnorm = nrm;
25582dcb1b2aSMatthew Knepley      ierr = VecScale(y,cnorm);CHKERRQ(ierr);
25599b94acceSBarry Smith      *ynorm = *delta;
25609b94acceSBarry Smith   } else {
25619b94acceSBarry Smith      *gpnorm = 0.0;
2562064f8208SBarry Smith      *ynorm = nrm;
25639b94acceSBarry Smith   }
25643a40ed3dSBarry Smith   PetscFunctionReturn(0);
25659b94acceSBarry Smith }
25669b94acceSBarry Smith 
25674a2ae208SSatish Balay #undef __FUNCT__
25684a2ae208SSatish Balay #define __FUNCT__ "SNESSolve"
25696ce558aeSBarry Smith /*@C
2570f69a0ea3SMatthew Knepley    SNESSolve - Solves a nonlinear system F(x) = b.
2571f69a0ea3SMatthew Knepley    Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
25729b94acceSBarry Smith 
2573c7afd0dbSLois Curfman McInnes    Collective on SNES
2574c7afd0dbSLois Curfman McInnes 
2575b2002411SLois Curfman McInnes    Input Parameters:
2576c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2577f69a0ea3SMatthew Knepley .  b - the constant part of the equation, or PETSC_NULL to use zero.
257885385478SLisandro Dalcin -  x - the solution vector.
25799b94acceSBarry Smith 
2580b2002411SLois Curfman McInnes    Notes:
25818ddd3da0SLois Curfman McInnes    The user should initialize the vector,x, with the initial guess
25828ddd3da0SLois Curfman McInnes    for the nonlinear solve prior to calling SNESSolve.  In particular,
25838ddd3da0SLois Curfman McInnes    to employ an initial guess of zero, the user should explicitly set
25848ddd3da0SLois Curfman McInnes    this vector to zero by calling VecSet().
25858ddd3da0SLois Curfman McInnes 
258636851e7fSLois Curfman McInnes    Level: beginner
258736851e7fSLois Curfman McInnes 
25889b94acceSBarry Smith .keywords: SNES, nonlinear, solve
25899b94acceSBarry Smith 
259085385478SLisandro Dalcin .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian()
25919b94acceSBarry Smith @*/
25927087cfbeSBarry Smith PetscErrorCode  SNESSolve(SNES snes,Vec b,Vec x)
25939b94acceSBarry Smith {
2594dfbe8321SBarry Smith   PetscErrorCode ierr;
2595ace3abfcSBarry Smith   PetscBool      flg;
2596eabae89aSBarry Smith   char           filename[PETSC_MAX_PATH_LEN];
2597eabae89aSBarry Smith   PetscViewer    viewer;
2598efd51863SBarry Smith   PetscInt       grid;
2599052efed2SBarry Smith 
26003a40ed3dSBarry Smith   PetscFunctionBegin;
26010700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
26020700a824SBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
2603f69a0ea3SMatthew Knepley   PetscCheckSameComm(snes,1,x,3);
26040700a824SBarry Smith   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2);
260585385478SLisandro Dalcin   if (b) PetscCheckSameComm(snes,1,b,2);
260685385478SLisandro Dalcin 
2607efd51863SBarry Smith   for (grid=0; grid<snes->gridsequence+1; grid++) {
2608efd51863SBarry Smith 
260985385478SLisandro Dalcin     /* set solution vector */
2610efd51863SBarry Smith     if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);}
26116bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
261285385478SLisandro Dalcin     snes->vec_sol = x;
261385385478SLisandro Dalcin     /* set afine vector if provided */
261485385478SLisandro Dalcin     if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); }
26156bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
261685385478SLisandro Dalcin     snes->vec_rhs = b;
261785385478SLisandro Dalcin 
261870e92668SMatthew Knepley     ierr = SNESSetUp(snes);CHKERRQ(ierr);
26193f149594SLisandro Dalcin 
2620d25893d9SBarry Smith     if (!grid && snes->ops->computeinitialguess) {
2621d25893d9SBarry Smith       ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr);
2622d25893d9SBarry Smith     }
2623d25893d9SBarry Smith 
2624abc0a331SBarry Smith     if (snes->conv_hist_reset) snes->conv_hist_len = 0;
262550ffb88aSMatthew Knepley     snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;
2626d5e45103SBarry Smith 
26273f149594SLisandro Dalcin     ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
26284936397dSBarry Smith     ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr);
262985385478SLisandro Dalcin     ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
26304936397dSBarry Smith     if (snes->domainerror){
26314936397dSBarry Smith       snes->reason      = SNES_DIVERGED_FUNCTION_DOMAIN;
26324936397dSBarry Smith       snes->domainerror = PETSC_FALSE;
26334936397dSBarry Smith     }
263417186662SBarry Smith     if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
26353f149594SLisandro Dalcin 
26367adad957SLisandro Dalcin     ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
2637eabae89aSBarry Smith     if (flg && !PetscPreLoadingOn) {
26387adad957SLisandro Dalcin       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr);
2639eabae89aSBarry Smith       ierr = SNESView(snes,viewer);CHKERRQ(ierr);
26406bf464f9SBarry Smith       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
2641eabae89aSBarry Smith     }
2642eabae89aSBarry Smith 
264390d69ab7SBarry Smith     flg  = PETSC_FALSE;
2644acfcf0e5SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr);
2645da9b6338SBarry Smith     if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); }
26465968eb51SBarry Smith     if (snes->printreason) {
26475968eb51SBarry Smith       if (snes->reason > 0) {
26487adad957SLisandro Dalcin         ierr = PetscPrintf(((PetscObject)snes)->comm,"Nonlinear solve converged due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr);
26495968eb51SBarry Smith       } else {
26507adad957SLisandro Dalcin         ierr = PetscPrintf(((PetscObject)snes)->comm,"Nonlinear solve did not converge due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr);
26515968eb51SBarry Smith       }
26525968eb51SBarry Smith     }
26535968eb51SBarry Smith 
2654e113a28aSBarry Smith     if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged");
2655efd51863SBarry Smith     if (grid <  snes->gridsequence) {
2656efd51863SBarry Smith       DM  fine;
2657efd51863SBarry Smith       Vec xnew;
2658efd51863SBarry Smith       Mat interp;
2659efd51863SBarry Smith 
2660efd51863SBarry Smith       ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr);
2661efd51863SBarry Smith       ierr = DMGetInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr);
2662efd51863SBarry Smith       ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr);
2663efd51863SBarry Smith       ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr);
2664efd51863SBarry Smith       ierr = MatDestroy(&interp);CHKERRQ(ierr);
2665efd51863SBarry Smith       x    = xnew;
2666efd51863SBarry Smith 
2667efd51863SBarry Smith       ierr = SNESReset(snes);CHKERRQ(ierr);
2668efd51863SBarry Smith       ierr = SNESSetDM(snes,fine);CHKERRQ(ierr);
2669efd51863SBarry Smith       ierr = DMDestroy(&fine);CHKERRQ(ierr);
2670efd51863SBarry Smith     }
2671efd51863SBarry Smith   }
26723a40ed3dSBarry Smith   PetscFunctionReturn(0);
26739b94acceSBarry Smith }
26749b94acceSBarry Smith 
26759b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */
26769b94acceSBarry Smith 
26774a2ae208SSatish Balay #undef __FUNCT__
26784a2ae208SSatish Balay #define __FUNCT__ "SNESSetType"
267982bf6240SBarry Smith /*@C
26804b0e389bSBarry Smith    SNESSetType - Sets the method for the nonlinear solver.
26819b94acceSBarry Smith 
2682fee21e36SBarry Smith    Collective on SNES
2683fee21e36SBarry Smith 
2684c7afd0dbSLois Curfman McInnes    Input Parameters:
2685c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2686454a90a3SBarry Smith -  type - a known method
2687c7afd0dbSLois Curfman McInnes 
2688c7afd0dbSLois Curfman McInnes    Options Database Key:
2689454a90a3SBarry Smith .  -snes_type <type> - Sets the method; use -help for a list
2690c7afd0dbSLois Curfman McInnes    of available methods (for instance, ls or tr)
2691ae12b187SLois Curfman McInnes 
26929b94acceSBarry Smith    Notes:
2693e090d566SSatish Balay    See "petsc/include/petscsnes.h" for available methods (for instance)
26944b27c08aSLois Curfman McInnes +    SNESLS - Newton's method with line search
2695c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
26964b27c08aSLois Curfman McInnes .    SNESTR - Newton's method with trust region
2697c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
26989b94acceSBarry Smith 
2699ae12b187SLois Curfman McInnes   Normally, it is best to use the SNESSetFromOptions() command and then
2700ae12b187SLois Curfman McInnes   set the SNES solver type from the options database rather than by using
2701ae12b187SLois Curfman McInnes   this routine.  Using the options database provides the user with
2702ae12b187SLois Curfman McInnes   maximum flexibility in evaluating the many nonlinear solvers.
2703ae12b187SLois Curfman McInnes   The SNESSetType() routine is provided for those situations where it
2704ae12b187SLois Curfman McInnes   is necessary to set the nonlinear solver independently of the command
2705ae12b187SLois Curfman McInnes   line or options database.  This might be the case, for example, when
2706ae12b187SLois Curfman McInnes   the choice of solver changes during the execution of the program,
2707ae12b187SLois Curfman McInnes   and the user's application is taking responsibility for choosing the
2708b0a32e0cSBarry Smith   appropriate method.
270936851e7fSLois Curfman McInnes 
271036851e7fSLois Curfman McInnes   Level: intermediate
2711a703fe33SLois Curfman McInnes 
2712454a90a3SBarry Smith .keywords: SNES, set, type
2713435da068SBarry Smith 
2714435da068SBarry Smith .seealso: SNESType, SNESCreate()
2715435da068SBarry Smith 
27169b94acceSBarry Smith @*/
27177087cfbeSBarry Smith PetscErrorCode  SNESSetType(SNES snes,const SNESType type)
27189b94acceSBarry Smith {
2719dfbe8321SBarry Smith   PetscErrorCode ierr,(*r)(SNES);
2720ace3abfcSBarry Smith   PetscBool      match;
27213a40ed3dSBarry Smith 
27223a40ed3dSBarry Smith   PetscFunctionBegin;
27230700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
27244482741eSBarry Smith   PetscValidCharPointer(type,2);
272582bf6240SBarry Smith 
27266831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr);
27270f5bd95cSBarry Smith   if (match) PetscFunctionReturn(0);
272892ff6ae8SBarry Smith 
27294b91b6eaSBarry Smith   ierr =  PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr);
2730e32f2f54SBarry Smith   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
273175396ef9SLisandro Dalcin   /* Destroy the previous private SNES context */
273275396ef9SLisandro Dalcin   if (snes->ops->destroy) { ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); }
273375396ef9SLisandro Dalcin   /* Reinitialize function pointers in SNESOps structure */
273475396ef9SLisandro Dalcin   snes->ops->setup          = 0;
273575396ef9SLisandro Dalcin   snes->ops->solve          = 0;
273675396ef9SLisandro Dalcin   snes->ops->view           = 0;
273775396ef9SLisandro Dalcin   snes->ops->setfromoptions = 0;
273875396ef9SLisandro Dalcin   snes->ops->destroy        = 0;
273975396ef9SLisandro Dalcin   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
274075396ef9SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
2741454a90a3SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr);
274203bfa161SLisandro Dalcin   ierr = (*r)(snes);CHKERRQ(ierr);
27439fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS)
27449fb22e1aSBarry Smith   if (PetscAMSPublishAll) {
27459fb22e1aSBarry Smith     ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr);
27469fb22e1aSBarry Smith   }
27479fb22e1aSBarry Smith #endif
27483a40ed3dSBarry Smith   PetscFunctionReturn(0);
27499b94acceSBarry Smith }
27509b94acceSBarry Smith 
2751a847f771SSatish Balay 
27529b94acceSBarry Smith /* --------------------------------------------------------------------- */
27534a2ae208SSatish Balay #undef __FUNCT__
27544a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy"
275552baeb72SSatish Balay /*@
27569b94acceSBarry Smith    SNESRegisterDestroy - Frees the list of nonlinear solvers that were
2757f1af5d2fSBarry Smith    registered by SNESRegisterDynamic().
27589b94acceSBarry Smith 
2759fee21e36SBarry Smith    Not Collective
2760fee21e36SBarry Smith 
276136851e7fSLois Curfman McInnes    Level: advanced
276236851e7fSLois Curfman McInnes 
27639b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy
27649b94acceSBarry Smith 
27659b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll()
27669b94acceSBarry Smith @*/
27677087cfbeSBarry Smith PetscErrorCode  SNESRegisterDestroy(void)
27689b94acceSBarry Smith {
2769dfbe8321SBarry Smith   PetscErrorCode ierr;
277082bf6240SBarry Smith 
27713a40ed3dSBarry Smith   PetscFunctionBegin;
27721441b1d3SBarry Smith   ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr);
27734c49b128SBarry Smith   SNESRegisterAllCalled = PETSC_FALSE;
27743a40ed3dSBarry Smith   PetscFunctionReturn(0);
27759b94acceSBarry Smith }
27769b94acceSBarry Smith 
27774a2ae208SSatish Balay #undef __FUNCT__
27784a2ae208SSatish Balay #define __FUNCT__ "SNESGetType"
27799b94acceSBarry Smith /*@C
27809a28b0a6SLois Curfman McInnes    SNESGetType - Gets the SNES method type and name (as a string).
27819b94acceSBarry Smith 
2782c7afd0dbSLois Curfman McInnes    Not Collective
2783c7afd0dbSLois Curfman McInnes 
27849b94acceSBarry Smith    Input Parameter:
27854b0e389bSBarry Smith .  snes - nonlinear solver context
27869b94acceSBarry Smith 
27879b94acceSBarry Smith    Output Parameter:
27883a7fca6bSBarry Smith .  type - SNES method (a character string)
27899b94acceSBarry Smith 
279036851e7fSLois Curfman McInnes    Level: intermediate
279136851e7fSLois Curfman McInnes 
2792454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name
27939b94acceSBarry Smith @*/
27947087cfbeSBarry Smith PetscErrorCode  SNESGetType(SNES snes,const SNESType *type)
27959b94acceSBarry Smith {
27963a40ed3dSBarry Smith   PetscFunctionBegin;
27970700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
27984482741eSBarry Smith   PetscValidPointer(type,2);
27997adad957SLisandro Dalcin   *type = ((PetscObject)snes)->type_name;
28003a40ed3dSBarry Smith   PetscFunctionReturn(0);
28019b94acceSBarry Smith }
28029b94acceSBarry Smith 
28034a2ae208SSatish Balay #undef __FUNCT__
28044a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution"
280552baeb72SSatish Balay /*@
28069b94acceSBarry Smith    SNESGetSolution - Returns the vector where the approximate solution is
28079b94acceSBarry Smith    stored.
28089b94acceSBarry Smith 
2809c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
2810c7afd0dbSLois Curfman McInnes 
28119b94acceSBarry Smith    Input Parameter:
28129b94acceSBarry Smith .  snes - the SNES context
28139b94acceSBarry Smith 
28149b94acceSBarry Smith    Output Parameter:
28159b94acceSBarry Smith .  x - the solution
28169b94acceSBarry Smith 
281770e92668SMatthew Knepley    Level: intermediate
281836851e7fSLois Curfman McInnes 
28199b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution
28209b94acceSBarry Smith 
282185385478SLisandro Dalcin .seealso:  SNESGetSolutionUpdate(), SNESGetFunction()
28229b94acceSBarry Smith @*/
28237087cfbeSBarry Smith PetscErrorCode  SNESGetSolution(SNES snes,Vec *x)
28249b94acceSBarry Smith {
28253a40ed3dSBarry Smith   PetscFunctionBegin;
28260700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
28274482741eSBarry Smith   PetscValidPointer(x,2);
282885385478SLisandro Dalcin   *x = snes->vec_sol;
282970e92668SMatthew Knepley   PetscFunctionReturn(0);
283070e92668SMatthew Knepley }
283170e92668SMatthew Knepley 
283270e92668SMatthew Knepley #undef __FUNCT__
28334a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate"
283452baeb72SSatish Balay /*@
28359b94acceSBarry Smith    SNESGetSolutionUpdate - Returns the vector where the solution update is
28369b94acceSBarry Smith    stored.
28379b94acceSBarry Smith 
2838c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
2839c7afd0dbSLois Curfman McInnes 
28409b94acceSBarry Smith    Input Parameter:
28419b94acceSBarry Smith .  snes - the SNES context
28429b94acceSBarry Smith 
28439b94acceSBarry Smith    Output Parameter:
28449b94acceSBarry Smith .  x - the solution update
28459b94acceSBarry Smith 
284636851e7fSLois Curfman McInnes    Level: advanced
284736851e7fSLois Curfman McInnes 
28489b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update
28499b94acceSBarry Smith 
285085385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction()
28519b94acceSBarry Smith @*/
28527087cfbeSBarry Smith PetscErrorCode  SNESGetSolutionUpdate(SNES snes,Vec *x)
28539b94acceSBarry Smith {
28543a40ed3dSBarry Smith   PetscFunctionBegin;
28550700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
28564482741eSBarry Smith   PetscValidPointer(x,2);
285785385478SLisandro Dalcin   *x = snes->vec_sol_update;
28583a40ed3dSBarry Smith   PetscFunctionReturn(0);
28599b94acceSBarry Smith }
28609b94acceSBarry Smith 
28614a2ae208SSatish Balay #undef __FUNCT__
28624a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction"
28639b94acceSBarry Smith /*@C
28643638b69dSLois Curfman McInnes    SNESGetFunction - Returns the vector where the function is stored.
28659b94acceSBarry Smith 
2866c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
2867c7afd0dbSLois Curfman McInnes 
28689b94acceSBarry Smith    Input Parameter:
28699b94acceSBarry Smith .  snes - the SNES context
28709b94acceSBarry Smith 
28719b94acceSBarry Smith    Output Parameter:
28727bf4e008SBarry Smith +  r - the function (or PETSC_NULL)
287370e92668SMatthew Knepley .  func - the function (or PETSC_NULL)
287470e92668SMatthew Knepley -  ctx - the function context (or PETSC_NULL)
28759b94acceSBarry Smith 
287636851e7fSLois Curfman McInnes    Level: advanced
287736851e7fSLois Curfman McInnes 
2878a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function
28799b94acceSBarry Smith 
28804b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution()
28819b94acceSBarry Smith @*/
28827087cfbeSBarry Smith PetscErrorCode  SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
28839b94acceSBarry Smith {
28843a40ed3dSBarry Smith   PetscFunctionBegin;
28850700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
288685385478SLisandro Dalcin   if (r)    *r    = snes->vec_func;
2887e7788613SBarry Smith   if (func) *func = snes->ops->computefunction;
288870e92668SMatthew Knepley   if (ctx)  *ctx  = snes->funP;
28893a40ed3dSBarry Smith   PetscFunctionReturn(0);
28909b94acceSBarry Smith }
28919b94acceSBarry Smith 
28924a2ae208SSatish Balay #undef __FUNCT__
28934a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix"
28943c7409f5SSatish Balay /*@C
28953c7409f5SSatish Balay    SNESSetOptionsPrefix - Sets the prefix used for searching for all
2896d850072dSLois Curfman McInnes    SNES options in the database.
28973c7409f5SSatish Balay 
28983f9fe445SBarry Smith    Logically Collective on SNES
2899fee21e36SBarry Smith 
2900c7afd0dbSLois Curfman McInnes    Input Parameter:
2901c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2902c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
2903c7afd0dbSLois Curfman McInnes 
2904d850072dSLois Curfman McInnes    Notes:
2905a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
2906c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
2907d850072dSLois Curfman McInnes 
290836851e7fSLois Curfman McInnes    Level: advanced
290936851e7fSLois Curfman McInnes 
29103c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database
2911a86d99e1SLois Curfman McInnes 
2912a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions()
29133c7409f5SSatish Balay @*/
29147087cfbeSBarry Smith PetscErrorCode  SNESSetOptionsPrefix(SNES snes,const char prefix[])
29153c7409f5SSatish Balay {
2916dfbe8321SBarry Smith   PetscErrorCode ierr;
29173c7409f5SSatish Balay 
29183a40ed3dSBarry Smith   PetscFunctionBegin;
29190700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2920639f9d9dSBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
29211cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
292294b7f48cSBarry Smith   ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
29233a40ed3dSBarry Smith   PetscFunctionReturn(0);
29243c7409f5SSatish Balay }
29253c7409f5SSatish Balay 
29264a2ae208SSatish Balay #undef __FUNCT__
29274a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix"
29283c7409f5SSatish Balay /*@C
2929f525115eSLois Curfman McInnes    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
2930d850072dSLois Curfman McInnes    SNES options in the database.
29313c7409f5SSatish Balay 
29323f9fe445SBarry Smith    Logically Collective on SNES
2933fee21e36SBarry Smith 
2934c7afd0dbSLois Curfman McInnes    Input Parameters:
2935c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2936c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
2937c7afd0dbSLois Curfman McInnes 
2938d850072dSLois Curfman McInnes    Notes:
2939a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
2940c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
2941d850072dSLois Curfman McInnes 
294236851e7fSLois Curfman McInnes    Level: advanced
294336851e7fSLois Curfman McInnes 
29443c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database
2945a86d99e1SLois Curfman McInnes 
2946a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix()
29473c7409f5SSatish Balay @*/
29487087cfbeSBarry Smith PetscErrorCode  SNESAppendOptionsPrefix(SNES snes,const char prefix[])
29493c7409f5SSatish Balay {
2950dfbe8321SBarry Smith   PetscErrorCode ierr;
29513c7409f5SSatish Balay 
29523a40ed3dSBarry Smith   PetscFunctionBegin;
29530700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2954639f9d9dSBarry Smith   ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
29551cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
295694b7f48cSBarry Smith   ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
29573a40ed3dSBarry Smith   PetscFunctionReturn(0);
29583c7409f5SSatish Balay }
29593c7409f5SSatish Balay 
29604a2ae208SSatish Balay #undef __FUNCT__
29614a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix"
29629ab63eb5SSatish Balay /*@C
29633c7409f5SSatish Balay    SNESGetOptionsPrefix - Sets the prefix used for searching for all
29643c7409f5SSatish Balay    SNES options in the database.
29653c7409f5SSatish Balay 
2966c7afd0dbSLois Curfman McInnes    Not Collective
2967c7afd0dbSLois Curfman McInnes 
29683c7409f5SSatish Balay    Input Parameter:
29693c7409f5SSatish Balay .  snes - the SNES context
29703c7409f5SSatish Balay 
29713c7409f5SSatish Balay    Output Parameter:
29723c7409f5SSatish Balay .  prefix - pointer to the prefix string used
29733c7409f5SSatish Balay 
29744ef407dbSRichard Tran Mills    Notes: On the fortran side, the user should pass in a string 'prefix' of
29759ab63eb5SSatish Balay    sufficient length to hold the prefix.
29769ab63eb5SSatish Balay 
297736851e7fSLois Curfman McInnes    Level: advanced
297836851e7fSLois Curfman McInnes 
29793c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database
2980a86d99e1SLois Curfman McInnes 
2981a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix()
29823c7409f5SSatish Balay @*/
29837087cfbeSBarry Smith PetscErrorCode  SNESGetOptionsPrefix(SNES snes,const char *prefix[])
29843c7409f5SSatish Balay {
2985dfbe8321SBarry Smith   PetscErrorCode ierr;
29863c7409f5SSatish Balay 
29873a40ed3dSBarry Smith   PetscFunctionBegin;
29880700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2989639f9d9dSBarry Smith   ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
29903a40ed3dSBarry Smith   PetscFunctionReturn(0);
29913c7409f5SSatish Balay }
29923c7409f5SSatish Balay 
2993b2002411SLois Curfman McInnes 
29944a2ae208SSatish Balay #undef __FUNCT__
29954a2ae208SSatish Balay #define __FUNCT__ "SNESRegister"
29963cea93caSBarry Smith /*@C
29973cea93caSBarry Smith   SNESRegister - See SNESRegisterDynamic()
29983cea93caSBarry Smith 
29997f6c08e0SMatthew Knepley   Level: advanced
30003cea93caSBarry Smith @*/
30017087cfbeSBarry Smith PetscErrorCode  SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES))
3002b2002411SLois Curfman McInnes {
3003e2d1d2b7SBarry Smith   char           fullname[PETSC_MAX_PATH_LEN];
3004dfbe8321SBarry Smith   PetscErrorCode ierr;
3005b2002411SLois Curfman McInnes 
3006b2002411SLois Curfman McInnes   PetscFunctionBegin;
3007b0a32e0cSBarry Smith   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
3008c134de8dSSatish Balay   ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
3009b2002411SLois Curfman McInnes   PetscFunctionReturn(0);
3010b2002411SLois Curfman McInnes }
3011da9b6338SBarry Smith 
3012da9b6338SBarry Smith #undef __FUNCT__
3013da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin"
30147087cfbeSBarry Smith PetscErrorCode  SNESTestLocalMin(SNES snes)
3015da9b6338SBarry Smith {
3016dfbe8321SBarry Smith   PetscErrorCode ierr;
301777431f27SBarry Smith   PetscInt       N,i,j;
3018da9b6338SBarry Smith   Vec            u,uh,fh;
3019da9b6338SBarry Smith   PetscScalar    value;
3020da9b6338SBarry Smith   PetscReal      norm;
3021da9b6338SBarry Smith 
3022da9b6338SBarry Smith   PetscFunctionBegin;
3023da9b6338SBarry Smith   ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr);
3024da9b6338SBarry Smith   ierr = VecDuplicate(u,&uh);CHKERRQ(ierr);
3025da9b6338SBarry Smith   ierr = VecDuplicate(u,&fh);CHKERRQ(ierr);
3026da9b6338SBarry Smith 
3027da9b6338SBarry Smith   /* currently only works for sequential */
3028da9b6338SBarry Smith   ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");
3029da9b6338SBarry Smith   ierr = VecGetSize(u,&N);CHKERRQ(ierr);
3030da9b6338SBarry Smith   for (i=0; i<N; i++) {
3031da9b6338SBarry Smith     ierr = VecCopy(u,uh);CHKERRQ(ierr);
303277431f27SBarry Smith     ierr  = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr);
3033da9b6338SBarry Smith     for (j=-10; j<11; j++) {
3034ccae9161SBarry Smith       value = PetscSign(j)*exp(PetscAbs(j)-10.0);
3035da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
30363ab0aad5SBarry Smith       ierr  = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr);
3037da9b6338SBarry Smith       ierr  = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr);
303877431f27SBarry Smith       ierr  = PetscPrintf(PETSC_COMM_WORLD,"       j norm %D %18.16e\n",j,norm);CHKERRQ(ierr);
3039da9b6338SBarry Smith       value = -value;
3040da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
3041da9b6338SBarry Smith     }
3042da9b6338SBarry Smith   }
30436bf464f9SBarry Smith   ierr = VecDestroy(&uh);CHKERRQ(ierr);
30446bf464f9SBarry Smith   ierr = VecDestroy(&fh);CHKERRQ(ierr);
3045da9b6338SBarry Smith   PetscFunctionReturn(0);
3046da9b6338SBarry Smith }
304771f87433Sdalcinl 
304871f87433Sdalcinl #undef __FUNCT__
3049fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW"
305071f87433Sdalcinl /*@
3051fa9f3622SBarry Smith    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
305271f87433Sdalcinl    computing relative tolerance for linear solvers within an inexact
305371f87433Sdalcinl    Newton method.
305471f87433Sdalcinl 
30553f9fe445SBarry Smith    Logically Collective on SNES
305671f87433Sdalcinl 
305771f87433Sdalcinl    Input Parameters:
305871f87433Sdalcinl +  snes - SNES context
305971f87433Sdalcinl -  flag - PETSC_TRUE or PETSC_FALSE
306071f87433Sdalcinl 
306164ba62caSBarry Smith     Options Database:
306264ba62caSBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
306364ba62caSBarry Smith .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
306464ba62caSBarry Smith .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
306564ba62caSBarry Smith .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
306664ba62caSBarry Smith .  -snes_ksp_ew_gamma <gamma> - Sets gamma
306764ba62caSBarry Smith .  -snes_ksp_ew_alpha <alpha> - Sets alpha
306864ba62caSBarry Smith .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
306964ba62caSBarry Smith -  -snes_ksp_ew_threshold <threshold> - Sets threshold
307064ba62caSBarry Smith 
307171f87433Sdalcinl    Notes:
307271f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
307371f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
307471f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
307571f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
307671f87433Sdalcinl    solver.
307771f87433Sdalcinl 
307871f87433Sdalcinl    Level: advanced
307971f87433Sdalcinl 
308071f87433Sdalcinl    Reference:
308171f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
308271f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
308371f87433Sdalcinl 
308471f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
308571f87433Sdalcinl 
3086fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
308771f87433Sdalcinl @*/
30887087cfbeSBarry Smith PetscErrorCode  SNESKSPSetUseEW(SNES snes,PetscBool  flag)
308971f87433Sdalcinl {
309071f87433Sdalcinl   PetscFunctionBegin;
30910700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3092acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flag,2);
309371f87433Sdalcinl   snes->ksp_ewconv = flag;
309471f87433Sdalcinl   PetscFunctionReturn(0);
309571f87433Sdalcinl }
309671f87433Sdalcinl 
309771f87433Sdalcinl #undef __FUNCT__
3098fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW"
309971f87433Sdalcinl /*@
3100fa9f3622SBarry Smith    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
310171f87433Sdalcinl    for computing relative tolerance for linear solvers within an
310271f87433Sdalcinl    inexact Newton method.
310371f87433Sdalcinl 
310471f87433Sdalcinl    Not Collective
310571f87433Sdalcinl 
310671f87433Sdalcinl    Input Parameter:
310771f87433Sdalcinl .  snes - SNES context
310871f87433Sdalcinl 
310971f87433Sdalcinl    Output Parameter:
311071f87433Sdalcinl .  flag - PETSC_TRUE or PETSC_FALSE
311171f87433Sdalcinl 
311271f87433Sdalcinl    Notes:
311371f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
311471f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
311571f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
311671f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
311771f87433Sdalcinl    solver.
311871f87433Sdalcinl 
311971f87433Sdalcinl    Level: advanced
312071f87433Sdalcinl 
312171f87433Sdalcinl    Reference:
312271f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
312371f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
312471f87433Sdalcinl 
312571f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
312671f87433Sdalcinl 
3127fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
312871f87433Sdalcinl @*/
31297087cfbeSBarry Smith PetscErrorCode  SNESKSPGetUseEW(SNES snes, PetscBool  *flag)
313071f87433Sdalcinl {
313171f87433Sdalcinl   PetscFunctionBegin;
31320700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
313371f87433Sdalcinl   PetscValidPointer(flag,2);
313471f87433Sdalcinl   *flag = snes->ksp_ewconv;
313571f87433Sdalcinl   PetscFunctionReturn(0);
313671f87433Sdalcinl }
313771f87433Sdalcinl 
313871f87433Sdalcinl #undef __FUNCT__
3139fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW"
314071f87433Sdalcinl /*@
3141fa9f3622SBarry Smith    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
314271f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
314371f87433Sdalcinl    Newton method.
314471f87433Sdalcinl 
31453f9fe445SBarry Smith    Logically Collective on SNES
314671f87433Sdalcinl 
314771f87433Sdalcinl    Input Parameters:
314871f87433Sdalcinl +    snes - SNES context
314971f87433Sdalcinl .    version - version 1, 2 (default is 2) or 3
315071f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
315171f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
315271f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
315371f87433Sdalcinl              (0 <= gamma2 <= 1)
315471f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
315571f87433Sdalcinl .    alpha2 - power for safeguard
315671f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
315771f87433Sdalcinl 
315871f87433Sdalcinl    Note:
315971f87433Sdalcinl    Version 3 was contributed by Luis Chacon, June 2006.
316071f87433Sdalcinl 
316171f87433Sdalcinl    Use PETSC_DEFAULT to retain the default for any of the parameters.
316271f87433Sdalcinl 
316371f87433Sdalcinl    Level: advanced
316471f87433Sdalcinl 
316571f87433Sdalcinl    Reference:
316671f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
316771f87433Sdalcinl    inexact Newton method", Utah State University Math. Stat. Dept. Res.
316871f87433Sdalcinl    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
316971f87433Sdalcinl 
317071f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
317171f87433Sdalcinl 
3172fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
317371f87433Sdalcinl @*/
31747087cfbeSBarry Smith PetscErrorCode  SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,
317571f87433Sdalcinl 							    PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
317671f87433Sdalcinl {
3177fa9f3622SBarry Smith   SNESKSPEW *kctx;
317871f87433Sdalcinl   PetscFunctionBegin;
31790700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3180fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
3181e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
3182c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,version,2);
3183c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_0,3);
3184c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_max,4);
3185c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,gamma,5);
3186c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha,6);
3187c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha2,7);
3188c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,threshold,8);
318971f87433Sdalcinl 
319071f87433Sdalcinl   if (version != PETSC_DEFAULT)   kctx->version   = version;
319171f87433Sdalcinl   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
319271f87433Sdalcinl   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
319371f87433Sdalcinl   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
319471f87433Sdalcinl   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
319571f87433Sdalcinl   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
319671f87433Sdalcinl   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
319771f87433Sdalcinl 
319871f87433Sdalcinl   if (kctx->version < 1 || kctx->version > 3) {
3199e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version);
320071f87433Sdalcinl   }
320171f87433Sdalcinl   if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
3202e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0);
320371f87433Sdalcinl   }
320471f87433Sdalcinl   if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
3205e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max);
320671f87433Sdalcinl   }
320771f87433Sdalcinl   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
3208e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma);
320971f87433Sdalcinl   }
321071f87433Sdalcinl   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
3211e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha);
321271f87433Sdalcinl   }
321371f87433Sdalcinl   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
3214e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold);
321571f87433Sdalcinl   }
321671f87433Sdalcinl   PetscFunctionReturn(0);
321771f87433Sdalcinl }
321871f87433Sdalcinl 
321971f87433Sdalcinl #undef __FUNCT__
3220fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW"
322171f87433Sdalcinl /*@
3222fa9f3622SBarry Smith    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
322371f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
322471f87433Sdalcinl    Newton method.
322571f87433Sdalcinl 
322671f87433Sdalcinl    Not Collective
322771f87433Sdalcinl 
322871f87433Sdalcinl    Input Parameters:
322971f87433Sdalcinl      snes - SNES context
323071f87433Sdalcinl 
323171f87433Sdalcinl    Output Parameters:
323271f87433Sdalcinl +    version - version 1, 2 (default is 2) or 3
323371f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
323471f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
323571f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
323671f87433Sdalcinl              (0 <= gamma2 <= 1)
323771f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
323871f87433Sdalcinl .    alpha2 - power for safeguard
323971f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
324071f87433Sdalcinl 
324171f87433Sdalcinl    Level: advanced
324271f87433Sdalcinl 
324371f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters
324471f87433Sdalcinl 
3245fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
324671f87433Sdalcinl @*/
32477087cfbeSBarry Smith PetscErrorCode  SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,
324871f87433Sdalcinl 							    PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
324971f87433Sdalcinl {
3250fa9f3622SBarry Smith   SNESKSPEW *kctx;
325171f87433Sdalcinl   PetscFunctionBegin;
32520700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3253fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
3254e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
325571f87433Sdalcinl   if(version)   *version   = kctx->version;
325671f87433Sdalcinl   if(rtol_0)    *rtol_0    = kctx->rtol_0;
325771f87433Sdalcinl   if(rtol_max)  *rtol_max  = kctx->rtol_max;
325871f87433Sdalcinl   if(gamma)     *gamma     = kctx->gamma;
325971f87433Sdalcinl   if(alpha)     *alpha     = kctx->alpha;
326071f87433Sdalcinl   if(alpha2)    *alpha2    = kctx->alpha2;
326171f87433Sdalcinl   if(threshold) *threshold = kctx->threshold;
326271f87433Sdalcinl   PetscFunctionReturn(0);
326371f87433Sdalcinl }
326471f87433Sdalcinl 
326571f87433Sdalcinl #undef __FUNCT__
3266fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve"
3267fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x)
326871f87433Sdalcinl {
326971f87433Sdalcinl   PetscErrorCode ierr;
3270fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
327171f87433Sdalcinl   PetscReal      rtol=PETSC_DEFAULT,stol;
327271f87433Sdalcinl 
327371f87433Sdalcinl   PetscFunctionBegin;
3274e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
327571f87433Sdalcinl   if (!snes->iter) { /* first time in, so use the original user rtol */
327671f87433Sdalcinl     rtol = kctx->rtol_0;
327771f87433Sdalcinl   } else {
327871f87433Sdalcinl     if (kctx->version == 1) {
327971f87433Sdalcinl       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
328071f87433Sdalcinl       if (rtol < 0.0) rtol = -rtol;
328171f87433Sdalcinl       stol = pow(kctx->rtol_last,kctx->alpha2);
328271f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
328371f87433Sdalcinl     } else if (kctx->version == 2) {
328471f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
328571f87433Sdalcinl       stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
328671f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
328771f87433Sdalcinl     } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */
328871f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
328971f87433Sdalcinl       /* safeguard: avoid sharp decrease of rtol */
329071f87433Sdalcinl       stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha);
329171f87433Sdalcinl       stol = PetscMax(rtol,stol);
329271f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
329371f87433Sdalcinl       /* safeguard: avoid oversolving */
329471f87433Sdalcinl       stol = kctx->gamma*(snes->ttol)/snes->norm;
329571f87433Sdalcinl       stol = PetscMax(rtol,stol);
329671f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
3297e32f2f54SBarry Smith     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
329871f87433Sdalcinl   }
329971f87433Sdalcinl   /* safeguard: avoid rtol greater than one */
330071f87433Sdalcinl   rtol = PetscMin(rtol,kctx->rtol_max);
330171f87433Sdalcinl   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
330271f87433Sdalcinl   ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr);
330371f87433Sdalcinl   PetscFunctionReturn(0);
330471f87433Sdalcinl }
330571f87433Sdalcinl 
330671f87433Sdalcinl #undef __FUNCT__
3307fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve"
3308fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x)
330971f87433Sdalcinl {
331071f87433Sdalcinl   PetscErrorCode ierr;
3311fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
331271f87433Sdalcinl   PCSide         pcside;
331371f87433Sdalcinl   Vec            lres;
331471f87433Sdalcinl 
331571f87433Sdalcinl   PetscFunctionBegin;
3316e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
331771f87433Sdalcinl   ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr);
331871f87433Sdalcinl   ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr);
331971f87433Sdalcinl   if (kctx->version == 1) {
3320b037da10SBarry Smith     ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr);
332171f87433Sdalcinl     if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
332271f87433Sdalcinl       /* KSP residual is true linear residual */
332371f87433Sdalcinl       ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr);
332471f87433Sdalcinl     } else {
332571f87433Sdalcinl       /* KSP residual is preconditioned residual */
332671f87433Sdalcinl       /* compute true linear residual norm */
332771f87433Sdalcinl       ierr = VecDuplicate(b,&lres);CHKERRQ(ierr);
332871f87433Sdalcinl       ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr);
332971f87433Sdalcinl       ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr);
333071f87433Sdalcinl       ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr);
33316bf464f9SBarry Smith       ierr = VecDestroy(&lres);CHKERRQ(ierr);
333271f87433Sdalcinl     }
333371f87433Sdalcinl   }
333471f87433Sdalcinl   PetscFunctionReturn(0);
333571f87433Sdalcinl }
333671f87433Sdalcinl 
333771f87433Sdalcinl #undef __FUNCT__
333871f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve"
333971f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x)
334071f87433Sdalcinl {
334171f87433Sdalcinl   PetscErrorCode ierr;
334271f87433Sdalcinl 
334371f87433Sdalcinl   PetscFunctionBegin;
3344fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr);  }
334571f87433Sdalcinl   ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr);
3346fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); }
334771f87433Sdalcinl   PetscFunctionReturn(0);
334871f87433Sdalcinl }
33496c699258SBarry Smith 
33506c699258SBarry Smith #undef __FUNCT__
33516c699258SBarry Smith #define __FUNCT__ "SNESSetDM"
33526c699258SBarry Smith /*@
33536c699258SBarry Smith    SNESSetDM - Sets the DM that may be used by some preconditioners
33546c699258SBarry Smith 
33553f9fe445SBarry Smith    Logically Collective on SNES
33566c699258SBarry Smith 
33576c699258SBarry Smith    Input Parameters:
33586c699258SBarry Smith +  snes - the preconditioner context
33596c699258SBarry Smith -  dm - the dm
33606c699258SBarry Smith 
33616c699258SBarry Smith    Level: intermediate
33626c699258SBarry Smith 
33636c699258SBarry Smith 
33646c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM()
33656c699258SBarry Smith @*/
33667087cfbeSBarry Smith PetscErrorCode  SNESSetDM(SNES snes,DM dm)
33676c699258SBarry Smith {
33686c699258SBarry Smith   PetscErrorCode ierr;
3369345fed2cSBarry Smith   KSP            ksp;
33706c699258SBarry Smith 
33716c699258SBarry Smith   PetscFunctionBegin;
33720700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3373d0660788SBarry Smith   if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);}
33746bf464f9SBarry Smith   ierr = DMDestroy(&snes->dm);CHKERRQ(ierr);
33756c699258SBarry Smith   snes->dm = dm;
3376345fed2cSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
3377345fed2cSBarry Smith   ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr);
3378f22f69f0SBarry Smith   ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr);
33796c699258SBarry Smith   PetscFunctionReturn(0);
33806c699258SBarry Smith }
33816c699258SBarry Smith 
33826c699258SBarry Smith #undef __FUNCT__
33836c699258SBarry Smith #define __FUNCT__ "SNESGetDM"
33846c699258SBarry Smith /*@
33856c699258SBarry Smith    SNESGetDM - Gets the DM that may be used by some preconditioners
33866c699258SBarry Smith 
33873f9fe445SBarry Smith    Not Collective but DM obtained is parallel on SNES
33886c699258SBarry Smith 
33896c699258SBarry Smith    Input Parameter:
33906c699258SBarry Smith . snes - the preconditioner context
33916c699258SBarry Smith 
33926c699258SBarry Smith    Output Parameter:
33936c699258SBarry Smith .  dm - the dm
33946c699258SBarry Smith 
33956c699258SBarry Smith    Level: intermediate
33966c699258SBarry Smith 
33976c699258SBarry Smith 
33986c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM()
33996c699258SBarry Smith @*/
34007087cfbeSBarry Smith PetscErrorCode  SNESGetDM(SNES snes,DM *dm)
34016c699258SBarry Smith {
34026c699258SBarry Smith   PetscFunctionBegin;
34030700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
34046c699258SBarry Smith   *dm = snes->dm;
34056c699258SBarry Smith   PetscFunctionReturn(0);
34066c699258SBarry Smith }
34070807856dSBarry Smith 
340831823bd8SMatthew G Knepley #undef __FUNCT__
340931823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC"
341031823bd8SMatthew G Knepley /*@
341131823bd8SMatthew G Knepley   SNESSetPC - Sets the preconditioner to be used.
341231823bd8SMatthew G Knepley 
341331823bd8SMatthew G Knepley   Collective on SNES
341431823bd8SMatthew G Knepley 
341531823bd8SMatthew G Knepley   Input Parameters:
341631823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate()
341731823bd8SMatthew G Knepley - pc   - the preconditioner object
341831823bd8SMatthew G Knepley 
341931823bd8SMatthew G Knepley   Notes:
342031823bd8SMatthew G Knepley   Use SNESGetPC() to retrieve the preconditioner context (for example,
342131823bd8SMatthew G Knepley   to configure it using the API).
342231823bd8SMatthew G Knepley 
342331823bd8SMatthew G Knepley   Level: developer
342431823bd8SMatthew G Knepley 
342531823bd8SMatthew G Knepley .keywords: SNES, set, precondition
342631823bd8SMatthew G Knepley .seealso: SNESGetPC()
342731823bd8SMatthew G Knepley @*/
342831823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc)
342931823bd8SMatthew G Knepley {
343031823bd8SMatthew G Knepley   PetscErrorCode ierr;
343131823bd8SMatthew G Knepley 
343231823bd8SMatthew G Knepley   PetscFunctionBegin;
343331823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
343431823bd8SMatthew G Knepley   PetscValidHeaderSpecific(pc, SNES_CLASSID, 2);
343531823bd8SMatthew G Knepley   PetscCheckSameComm(snes, 1, pc, 2);
343631823bd8SMatthew G Knepley   ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr);
3437bf11d3b6SBarry Smith   ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr);
343831823bd8SMatthew G Knepley   snes->pc = pc;
343931823bd8SMatthew G Knepley   ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr);
344031823bd8SMatthew G Knepley   PetscFunctionReturn(0);
344131823bd8SMatthew G Knepley }
344231823bd8SMatthew G Knepley 
344331823bd8SMatthew G Knepley #undef __FUNCT__
344431823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC"
344531823bd8SMatthew G Knepley /*@
344631823bd8SMatthew G Knepley   SNESGetPC - Returns a pointer to the preconditioner context set with SNESSetPC().
344731823bd8SMatthew G Knepley 
344831823bd8SMatthew G Knepley   Not Collective
344931823bd8SMatthew G Knepley 
345031823bd8SMatthew G Knepley   Input Parameter:
345131823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate()
345231823bd8SMatthew G Knepley 
345331823bd8SMatthew G Knepley   Output Parameter:
345431823bd8SMatthew G Knepley . pc - preconditioner context
345531823bd8SMatthew G Knepley 
345631823bd8SMatthew G Knepley   Level: developer
345731823bd8SMatthew G Knepley 
345831823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner
345931823bd8SMatthew G Knepley .seealso: SNESSetPC()
346031823bd8SMatthew G Knepley @*/
346131823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc)
346231823bd8SMatthew G Knepley {
346331823bd8SMatthew G Knepley   PetscErrorCode ierr;
346431823bd8SMatthew G Knepley 
346531823bd8SMatthew G Knepley   PetscFunctionBegin;
346631823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
346731823bd8SMatthew G Knepley   PetscValidPointer(pc, 2);
346831823bd8SMatthew G Knepley   if (!snes->pc) {
346931823bd8SMatthew G Knepley     ierr = SNESCreate(((PetscObject) snes)->comm, &snes->pc);CHKERRQ(ierr);
3470*4a0c5b0cSMatthew G Knepley     ierr = PetscObjectIncrementTabLevel((PetscObject) snes->pc, (PetscObject) snes, 1);CHKERRQ(ierr);
347131823bd8SMatthew G Knepley     ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr);
347231823bd8SMatthew G Knepley   }
347331823bd8SMatthew G Knepley   *pc = snes->pc;
347431823bd8SMatthew G Knepley   PetscFunctionReturn(0);
347531823bd8SMatthew G Knepley }
347631823bd8SMatthew G Knepley 
347769b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3478c6db04a5SJed Brown #include <mex.h>
347969b4f73cSBarry Smith 
34808f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext;
34818f6e6473SBarry Smith 
34820807856dSBarry Smith #undef __FUNCT__
34830807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab"
34840807856dSBarry Smith /*
34850807856dSBarry Smith    SNESComputeFunction_Matlab - Calls the function that has been set with
34860807856dSBarry Smith                          SNESSetFunctionMatlab().
34870807856dSBarry Smith 
34880807856dSBarry Smith    Collective on SNES
34890807856dSBarry Smith 
34900807856dSBarry Smith    Input Parameters:
34910807856dSBarry Smith +  snes - the SNES context
34920807856dSBarry Smith -  x - input vector
34930807856dSBarry Smith 
34940807856dSBarry Smith    Output Parameter:
34950807856dSBarry Smith .  y - function vector, as set by SNESSetFunction()
34960807856dSBarry Smith 
34970807856dSBarry Smith    Notes:
34980807856dSBarry Smith    SNESComputeFunction() is typically used within nonlinear solvers
34990807856dSBarry Smith    implementations, so most users would not generally call this routine
35000807856dSBarry Smith    themselves.
35010807856dSBarry Smith 
35020807856dSBarry Smith    Level: developer
35030807856dSBarry Smith 
35040807856dSBarry Smith .keywords: SNES, nonlinear, compute, function
35050807856dSBarry Smith 
35060807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
350761b2408cSBarry Smith */
35087087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx)
35090807856dSBarry Smith {
3510e650e774SBarry Smith   PetscErrorCode    ierr;
35118f6e6473SBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
35128f6e6473SBarry Smith   int               nlhs = 1,nrhs = 5;
35138f6e6473SBarry Smith   mxArray	    *plhs[1],*prhs[5];
351491621f2eSBarry Smith   long long int     lx = 0,ly = 0,ls = 0;
3515e650e774SBarry Smith 
35160807856dSBarry Smith   PetscFunctionBegin;
35170807856dSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
35180807856dSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
35190807856dSBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
35200807856dSBarry Smith   PetscCheckSameComm(snes,1,x,2);
35210807856dSBarry Smith   PetscCheckSameComm(snes,1,y,3);
35220807856dSBarry Smith 
35230807856dSBarry Smith   /* call Matlab function in ctx with arguments x and y */
3524e650e774SBarry Smith 
352591621f2eSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
3526e650e774SBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
3527e650e774SBarry Smith   ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr);
352891621f2eSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
352991621f2eSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
353091621f2eSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)ly);
35318f6e6473SBarry Smith   prhs[3] =  mxCreateString(sctx->funcname);
35328f6e6473SBarry Smith   prhs[4] =  sctx->ctx;
3533b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr);
3534e650e774SBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
3535e650e774SBarry Smith   mxDestroyArray(prhs[0]);
3536e650e774SBarry Smith   mxDestroyArray(prhs[1]);
3537e650e774SBarry Smith   mxDestroyArray(prhs[2]);
35388f6e6473SBarry Smith   mxDestroyArray(prhs[3]);
3539e650e774SBarry Smith   mxDestroyArray(plhs[0]);
35400807856dSBarry Smith   PetscFunctionReturn(0);
35410807856dSBarry Smith }
35420807856dSBarry Smith 
35430807856dSBarry Smith 
35440807856dSBarry Smith #undef __FUNCT__
35450807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab"
354661b2408cSBarry Smith /*
35470807856dSBarry Smith    SNESSetFunctionMatlab - Sets the function evaluation routine and function
35480807856dSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
3549e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
35500807856dSBarry Smith 
35510807856dSBarry Smith    Logically Collective on SNES
35520807856dSBarry Smith 
35530807856dSBarry Smith    Input Parameters:
35540807856dSBarry Smith +  snes - the SNES context
35550807856dSBarry Smith .  r - vector to store function value
35560807856dSBarry Smith -  func - function evaluation routine
35570807856dSBarry Smith 
35580807856dSBarry Smith    Calling sequence of func:
355961b2408cSBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
35600807856dSBarry Smith 
35610807856dSBarry Smith 
35620807856dSBarry Smith    Notes:
35630807856dSBarry Smith    The Newton-like methods typically solve linear systems of the form
35640807856dSBarry Smith $      f'(x) x = -f(x),
35650807856dSBarry Smith    where f'(x) denotes the Jacobian matrix and f(x) is the function.
35660807856dSBarry Smith 
35670807856dSBarry Smith    Level: beginner
35680807856dSBarry Smith 
35690807856dSBarry Smith .keywords: SNES, nonlinear, set, function
35700807856dSBarry Smith 
35710807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
357261b2408cSBarry Smith */
35737087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx)
35740807856dSBarry Smith {
35750807856dSBarry Smith   PetscErrorCode    ierr;
35768f6e6473SBarry Smith   SNESMatlabContext *sctx;
35770807856dSBarry Smith 
35780807856dSBarry Smith   PetscFunctionBegin;
35798f6e6473SBarry Smith   /* currently sctx is memory bleed */
35808f6e6473SBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
35818f6e6473SBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
35828f6e6473SBarry Smith   /*
35838f6e6473SBarry Smith      This should work, but it doesn't
35848f6e6473SBarry Smith   sctx->ctx = ctx;
35858f6e6473SBarry Smith   mexMakeArrayPersistent(sctx->ctx);
35868f6e6473SBarry Smith   */
35878f6e6473SBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
35888f6e6473SBarry Smith   ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr);
35890807856dSBarry Smith   PetscFunctionReturn(0);
35900807856dSBarry Smith }
359169b4f73cSBarry Smith 
359261b2408cSBarry Smith #undef __FUNCT__
359361b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab"
359461b2408cSBarry Smith /*
359561b2408cSBarry Smith    SNESComputeJacobian_Matlab - Calls the function that has been set with
359661b2408cSBarry Smith                          SNESSetJacobianMatlab().
359761b2408cSBarry Smith 
359861b2408cSBarry Smith    Collective on SNES
359961b2408cSBarry Smith 
360061b2408cSBarry Smith    Input Parameters:
360161b2408cSBarry Smith +  snes - the SNES context
360261b2408cSBarry Smith .  x - input vector
360361b2408cSBarry Smith .  A, B - the matrices
360461b2408cSBarry Smith -  ctx - user context
360561b2408cSBarry Smith 
360661b2408cSBarry Smith    Output Parameter:
360761b2408cSBarry Smith .  flag - structure of the matrix
360861b2408cSBarry Smith 
360961b2408cSBarry Smith    Level: developer
361061b2408cSBarry Smith 
361161b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function
361261b2408cSBarry Smith 
361361b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
361461b2408cSBarry Smith @*/
36157087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx)
361661b2408cSBarry Smith {
361761b2408cSBarry Smith   PetscErrorCode    ierr;
361861b2408cSBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
361961b2408cSBarry Smith   int               nlhs = 2,nrhs = 6;
362061b2408cSBarry Smith   mxArray	    *plhs[2],*prhs[6];
362161b2408cSBarry Smith   long long int     lx = 0,lA = 0,ls = 0, lB = 0;
362261b2408cSBarry Smith 
362361b2408cSBarry Smith   PetscFunctionBegin;
362461b2408cSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
362561b2408cSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
362661b2408cSBarry Smith 
362761b2408cSBarry Smith   /* call Matlab function in ctx with arguments x and y */
362861b2408cSBarry Smith 
362961b2408cSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
363061b2408cSBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
363161b2408cSBarry Smith   ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr);
363261b2408cSBarry Smith   ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr);
363361b2408cSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
363461b2408cSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
363561b2408cSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)lA);
363661b2408cSBarry Smith   prhs[3] =  mxCreateDoubleScalar((double)lB);
363761b2408cSBarry Smith   prhs[4] =  mxCreateString(sctx->funcname);
363861b2408cSBarry Smith   prhs[5] =  sctx->ctx;
3639b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr);
364061b2408cSBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
364161b2408cSBarry Smith   *flag   =  (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr);
364261b2408cSBarry Smith   mxDestroyArray(prhs[0]);
364361b2408cSBarry Smith   mxDestroyArray(prhs[1]);
364461b2408cSBarry Smith   mxDestroyArray(prhs[2]);
364561b2408cSBarry Smith   mxDestroyArray(prhs[3]);
364661b2408cSBarry Smith   mxDestroyArray(prhs[4]);
364761b2408cSBarry Smith   mxDestroyArray(plhs[0]);
364861b2408cSBarry Smith   mxDestroyArray(plhs[1]);
364961b2408cSBarry Smith   PetscFunctionReturn(0);
365061b2408cSBarry Smith }
365161b2408cSBarry Smith 
365261b2408cSBarry Smith 
365361b2408cSBarry Smith #undef __FUNCT__
365461b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab"
365561b2408cSBarry Smith /*
365661b2408cSBarry Smith    SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
365761b2408cSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
3658e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
365961b2408cSBarry Smith 
366061b2408cSBarry Smith    Logically Collective on SNES
366161b2408cSBarry Smith 
366261b2408cSBarry Smith    Input Parameters:
366361b2408cSBarry Smith +  snes - the SNES context
366461b2408cSBarry Smith .  A,B - Jacobian matrices
366561b2408cSBarry Smith .  func - function evaluation routine
366661b2408cSBarry Smith -  ctx - user context
366761b2408cSBarry Smith 
366861b2408cSBarry Smith    Calling sequence of func:
366961b2408cSBarry Smith $    flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx);
367061b2408cSBarry Smith 
367161b2408cSBarry Smith 
367261b2408cSBarry Smith    Level: developer
367361b2408cSBarry Smith 
367461b2408cSBarry Smith .keywords: SNES, nonlinear, set, function
367561b2408cSBarry Smith 
367661b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
367761b2408cSBarry Smith */
36787087cfbeSBarry Smith PetscErrorCode  SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx)
367961b2408cSBarry Smith {
368061b2408cSBarry Smith   PetscErrorCode    ierr;
368161b2408cSBarry Smith   SNESMatlabContext *sctx;
368261b2408cSBarry Smith 
368361b2408cSBarry Smith   PetscFunctionBegin;
368461b2408cSBarry Smith   /* currently sctx is memory bleed */
368561b2408cSBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
368661b2408cSBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
368761b2408cSBarry Smith   /*
368861b2408cSBarry Smith      This should work, but it doesn't
368961b2408cSBarry Smith   sctx->ctx = ctx;
369061b2408cSBarry Smith   mexMakeArrayPersistent(sctx->ctx);
369161b2408cSBarry Smith   */
369261b2408cSBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
369361b2408cSBarry Smith   ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
369461b2408cSBarry Smith   PetscFunctionReturn(0);
369561b2408cSBarry Smith }
369669b4f73cSBarry Smith 
3697f9eb7ae2SShri Abhyankar #undef __FUNCT__
3698f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab"
3699f9eb7ae2SShri Abhyankar /*
3700f9eb7ae2SShri Abhyankar    SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab().
3701f9eb7ae2SShri Abhyankar 
3702f9eb7ae2SShri Abhyankar    Collective on SNES
3703f9eb7ae2SShri Abhyankar 
3704f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction()
3705f9eb7ae2SShri Abhyankar @*/
37067087cfbeSBarry Smith PetscErrorCode  SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx)
3707f9eb7ae2SShri Abhyankar {
3708f9eb7ae2SShri Abhyankar   PetscErrorCode  ierr;
370948f37e70SShri Abhyankar   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
3710f9eb7ae2SShri Abhyankar   int             nlhs = 1,nrhs = 6;
3711f9eb7ae2SShri Abhyankar   mxArray	  *plhs[1],*prhs[6];
3712f9eb7ae2SShri Abhyankar   long long int   lx = 0,ls = 0;
3713f9eb7ae2SShri Abhyankar   Vec             x=snes->vec_sol;
3714f9eb7ae2SShri Abhyankar 
3715f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
3716f9eb7ae2SShri Abhyankar   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3717f9eb7ae2SShri Abhyankar 
3718f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
3719f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
3720f9eb7ae2SShri Abhyankar   prhs[0] =  mxCreateDoubleScalar((double)ls);
3721f9eb7ae2SShri Abhyankar   prhs[1] =  mxCreateDoubleScalar((double)it);
3722f9eb7ae2SShri Abhyankar   prhs[2] =  mxCreateDoubleScalar((double)fnorm);
3723f9eb7ae2SShri Abhyankar   prhs[3] =  mxCreateDoubleScalar((double)lx);
3724f9eb7ae2SShri Abhyankar   prhs[4] =  mxCreateString(sctx->funcname);
3725f9eb7ae2SShri Abhyankar   prhs[5] =  sctx->ctx;
3726f9eb7ae2SShri Abhyankar   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr);
3727f9eb7ae2SShri Abhyankar   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
3728f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[0]);
3729f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[1]);
3730f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[2]);
3731f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[3]);
3732f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[4]);
3733f9eb7ae2SShri Abhyankar   mxDestroyArray(plhs[0]);
3734f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
3735f9eb7ae2SShri Abhyankar }
3736f9eb7ae2SShri Abhyankar 
3737f9eb7ae2SShri Abhyankar 
3738f9eb7ae2SShri Abhyankar #undef __FUNCT__
3739f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab"
3740f9eb7ae2SShri Abhyankar /*
3741e3c5b3baSBarry Smith    SNESMonitorSetMatlab - Sets the monitor function from MATLAB
3742f9eb7ae2SShri Abhyankar 
3743f9eb7ae2SShri Abhyankar    Level: developer
3744f9eb7ae2SShri Abhyankar 
3745f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function
3746f9eb7ae2SShri Abhyankar 
3747f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
3748f9eb7ae2SShri Abhyankar */
37497087cfbeSBarry Smith PetscErrorCode  SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx)
3750f9eb7ae2SShri Abhyankar {
3751f9eb7ae2SShri Abhyankar   PetscErrorCode    ierr;
3752f9eb7ae2SShri Abhyankar   SNESMatlabContext *sctx;
3753f9eb7ae2SShri Abhyankar 
3754f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
3755f9eb7ae2SShri Abhyankar   /* currently sctx is memory bleed */
3756f9eb7ae2SShri Abhyankar   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
3757f9eb7ae2SShri Abhyankar   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
3758f9eb7ae2SShri Abhyankar   /*
3759f9eb7ae2SShri Abhyankar      This should work, but it doesn't
3760f9eb7ae2SShri Abhyankar   sctx->ctx = ctx;
3761f9eb7ae2SShri Abhyankar   mexMakeArrayPersistent(sctx->ctx);
3762f9eb7ae2SShri Abhyankar   */
3763f9eb7ae2SShri Abhyankar   sctx->ctx = mxDuplicateArray(ctx);
3764f9eb7ae2SShri Abhyankar   ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr);
3765f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
3766f9eb7ae2SShri Abhyankar }
3767f9eb7ae2SShri Abhyankar 
376869b4f73cSBarry Smith #endif
3769