xref: /petsc/src/snes/interface/snes.c (revision 2b93b426a98a109954b61e7bf04c3676e7065ba2)
1af0996ceSBarry Smith #include <petsc/private/snesimpl.h>      /*I "petscsnes.h"  I*/
207475bc1SBarry Smith #include <petscdmshell.h>
3d96771aaSLisandro Dalcin #include <petscdraw.h>
4a01aa210SMatthew G. Knepley #include <petscds.h>
534b4d3a8SMatthew G. Knepley #include <petscdmadaptor.h>
606fc46c8SMatthew G. Knepley #include <petscconvest.h>
79b94acceSBarry Smith 
8ace3abfcSBarry Smith PetscBool         SNESRegisterAllCalled = PETSC_FALSE;
90298fd71SBarry Smith PetscFunctionList SNESList              = NULL;
108ba1e511SMatthew Knepley 
118ba1e511SMatthew Knepley /* Logging support */
1222c6f798SBarry Smith PetscClassId  SNES_CLASSID, DMSNES_CLASSID;
1394db00ebSBarry Smith PetscLogEvent SNES_Solve, SNES_FunctionEval, SNES_JacobianEval, SNES_NGSEval, SNES_NGSFuncEval, SNES_NPCSolve, SNES_ObjectiveEval;
14a09944afSBarry Smith 
15e113a28aSBarry Smith /*@
16e113a28aSBarry Smith    SNESSetErrorIfNotConverged - Causes SNESSolve() to generate an error if the solver has not converged.
17e113a28aSBarry Smith 
183f9fe445SBarry Smith    Logically Collective on SNES
19e113a28aSBarry Smith 
20e113a28aSBarry Smith    Input Parameters:
21e113a28aSBarry Smith +  snes - iterative context obtained from SNESCreate()
22e113a28aSBarry Smith -  flg - PETSC_TRUE indicates you want the error generated
23e113a28aSBarry Smith 
24e113a28aSBarry Smith    Options database keys:
25e113a28aSBarry Smith .  -snes_error_if_not_converged : this takes an optional truth value (0/1/no/yes/true/false)
26e113a28aSBarry Smith 
27e113a28aSBarry Smith    Level: intermediate
28e113a28aSBarry Smith 
29e113a28aSBarry Smith    Notes:
30e113a28aSBarry Smith     Normally PETSc continues if a linear solver fails to converge, you can call SNESGetConvergedReason() after a SNESSolve()
31e113a28aSBarry Smith     to determine if it has converged.
32e113a28aSBarry Smith 
33e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero
34e113a28aSBarry Smith 
35e113a28aSBarry Smith .seealso: SNESGetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged()
36e113a28aSBarry Smith @*/
377087cfbeSBarry Smith PetscErrorCode  SNESSetErrorIfNotConverged(SNES snes,PetscBool flg)
38e113a28aSBarry Smith {
39e113a28aSBarry Smith   PetscFunctionBegin;
40e113a28aSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
41acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flg,2);
42e113a28aSBarry Smith   snes->errorifnotconverged = flg;
43e113a28aSBarry Smith   PetscFunctionReturn(0);
44e113a28aSBarry Smith }
45e113a28aSBarry Smith 
46e113a28aSBarry Smith /*@
47e113a28aSBarry Smith    SNESGetErrorIfNotConverged - Will SNESSolve() generate an error if the solver does not converge?
48e113a28aSBarry Smith 
49e113a28aSBarry Smith    Not Collective
50e113a28aSBarry Smith 
51e113a28aSBarry Smith    Input Parameter:
52e113a28aSBarry Smith .  snes - iterative context obtained from SNESCreate()
53e113a28aSBarry Smith 
54e113a28aSBarry Smith    Output Parameter:
55e113a28aSBarry Smith .  flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE
56e113a28aSBarry Smith 
57e113a28aSBarry Smith    Level: intermediate
58e113a28aSBarry Smith 
59e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero
60e113a28aSBarry Smith 
61e113a28aSBarry Smith .seealso:  SNESSetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged()
62e113a28aSBarry Smith @*/
637087cfbeSBarry Smith PetscErrorCode  SNESGetErrorIfNotConverged(SNES snes,PetscBool  *flag)
64e113a28aSBarry Smith {
65e113a28aSBarry Smith   PetscFunctionBegin;
66e113a28aSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
67e113a28aSBarry Smith   PetscValidPointer(flag,2);
68e113a28aSBarry Smith   *flag = snes->errorifnotconverged;
69e113a28aSBarry Smith   PetscFunctionReturn(0);
70e113a28aSBarry Smith }
71e113a28aSBarry Smith 
724fc747eaSLawrence Mitchell /*@
734fc747eaSLawrence Mitchell     SNESSetAlwaysComputesFinalResidual - does the SNES always compute the residual at the final solution?
744fc747eaSLawrence Mitchell 
754fc747eaSLawrence Mitchell    Logically Collective on SNES
764fc747eaSLawrence Mitchell 
774fc747eaSLawrence Mitchell     Input Parameters:
784fc747eaSLawrence Mitchell +   snes - the shell SNES
794fc747eaSLawrence Mitchell -   flg - is the residual computed?
804fc747eaSLawrence Mitchell 
814fc747eaSLawrence Mitchell    Level: advanced
824fc747eaSLawrence Mitchell 
834fc747eaSLawrence Mitchell .seealso: SNESGetAlwaysComputesFinalResidual()
844fc747eaSLawrence Mitchell @*/
854fc747eaSLawrence Mitchell PetscErrorCode  SNESSetAlwaysComputesFinalResidual(SNES snes, PetscBool flg)
864fc747eaSLawrence Mitchell {
874fc747eaSLawrence Mitchell   PetscFunctionBegin;
884fc747eaSLawrence Mitchell   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
894fc747eaSLawrence Mitchell   snes->alwayscomputesfinalresidual = flg;
904fc747eaSLawrence Mitchell   PetscFunctionReturn(0);
914fc747eaSLawrence Mitchell }
924fc747eaSLawrence Mitchell 
934fc747eaSLawrence Mitchell /*@
944fc747eaSLawrence Mitchell     SNESGetAlwaysComputesFinalResidual - does the SNES always compute the residual at the final solution?
954fc747eaSLawrence Mitchell 
964fc747eaSLawrence Mitchell    Logically Collective on SNES
974fc747eaSLawrence Mitchell 
984fc747eaSLawrence Mitchell     Input Parameter:
994fc747eaSLawrence Mitchell .   snes - the shell SNES
1004fc747eaSLawrence Mitchell 
1014fc747eaSLawrence Mitchell     Output Parameter:
1024fc747eaSLawrence Mitchell .   flg - is the residual computed?
1034fc747eaSLawrence Mitchell 
1044fc747eaSLawrence Mitchell    Level: advanced
1054fc747eaSLawrence Mitchell 
1064fc747eaSLawrence Mitchell .seealso: SNESSetAlwaysComputesFinalResidual()
1074fc747eaSLawrence Mitchell @*/
1084fc747eaSLawrence Mitchell PetscErrorCode  SNESGetAlwaysComputesFinalResidual(SNES snes, PetscBool *flg)
1094fc747eaSLawrence Mitchell {
1104fc747eaSLawrence Mitchell   PetscFunctionBegin;
1114fc747eaSLawrence Mitchell   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1124fc747eaSLawrence Mitchell   *flg = snes->alwayscomputesfinalresidual;
1134fc747eaSLawrence Mitchell   PetscFunctionReturn(0);
1144fc747eaSLawrence Mitchell }
1154fc747eaSLawrence Mitchell 
116e725d27bSBarry Smith /*@
117bf388a1fSBarry Smith    SNESSetFunctionDomainError - tells SNES that the input vector to your SNESFunction is not
1184936397dSBarry Smith      in the functions domain. For example, negative pressure.
1194936397dSBarry Smith 
1203f9fe445SBarry Smith    Logically Collective on SNES
1214936397dSBarry Smith 
1224936397dSBarry Smith    Input Parameters:
1236a388c36SPeter Brune .  snes - the SNES context
1244936397dSBarry Smith 
12528529972SSatish Balay    Level: advanced
1264936397dSBarry Smith 
1274936397dSBarry Smith .keywords: SNES, view
1284936397dSBarry Smith 
129bf388a1fSBarry Smith .seealso: SNESCreate(), SNESSetFunction(), SNESFunction
1304936397dSBarry Smith @*/
1317087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionDomainError(SNES snes)
1324936397dSBarry Smith {
1334936397dSBarry Smith   PetscFunctionBegin;
1340700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
135422a814eSBarry Smith   if (snes->errorifnotconverged) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"User code indicates input vector is not in the function domain");
1364936397dSBarry Smith   snes->domainerror = PETSC_TRUE;
1374936397dSBarry Smith   PetscFunctionReturn(0);
1384936397dSBarry Smith }
1394936397dSBarry Smith 
1406a388c36SPeter Brune /*@
141c77b2880SPeter Brune    SNESGetFunctionDomainError - Gets the status of the domain error after a call to SNESComputeFunction;
1426a388c36SPeter Brune 
1436a388c36SPeter Brune    Logically Collective on SNES
1446a388c36SPeter Brune 
1456a388c36SPeter Brune    Input Parameters:
1466a388c36SPeter Brune .  snes - the SNES context
1476a388c36SPeter Brune 
1486a388c36SPeter Brune    Output Parameters:
149bf388a1fSBarry Smith .  domainerror - Set to PETSC_TRUE if there's a domain error; PETSC_FALSE otherwise.
1506a388c36SPeter Brune 
1516a388c36SPeter Brune    Level: advanced
1526a388c36SPeter Brune 
1536a388c36SPeter Brune .keywords: SNES, view
1546a388c36SPeter Brune 
155bf388a1fSBarry Smith .seealso: SNESSetFunctionDomainError(), SNESComputeFunction()
1566a388c36SPeter Brune @*/
1576a388c36SPeter Brune PetscErrorCode  SNESGetFunctionDomainError(SNES snes, PetscBool *domainerror)
1586a388c36SPeter Brune {
1596a388c36SPeter Brune   PetscFunctionBegin;
1606a388c36SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1616a388c36SPeter Brune   PetscValidPointer(domainerror, 2);
1626a388c36SPeter Brune   *domainerror = snes->domainerror;
1636a388c36SPeter Brune   PetscFunctionReturn(0);
1646a388c36SPeter Brune }
1656a388c36SPeter Brune 
16655849f57SBarry Smith /*@C
16755849f57SBarry Smith   SNESLoad - Loads a SNES that has been stored in binary  with SNESView().
16855849f57SBarry Smith 
16955849f57SBarry Smith   Collective on PetscViewer
17055849f57SBarry Smith 
17155849f57SBarry Smith   Input Parameters:
17255849f57SBarry Smith + newdm - the newly loaded SNES, this needs to have been created with SNESCreate() or
17355849f57SBarry Smith            some related function before a call to SNESLoad().
17455849f57SBarry Smith - viewer - binary file viewer, obtained from PetscViewerBinaryOpen()
17555849f57SBarry Smith 
17655849f57SBarry Smith    Level: intermediate
17755849f57SBarry Smith 
17855849f57SBarry Smith   Notes:
17955849f57SBarry Smith    The type is determined by the data in the file, any type set into the SNES before this call is ignored.
18055849f57SBarry Smith 
18155849f57SBarry Smith   Notes for advanced users:
18255849f57SBarry Smith   Most users should not need to know the details of the binary storage
18355849f57SBarry Smith   format, since SNESLoad() and TSView() completely hide these details.
18455849f57SBarry Smith   But for anyone who's interested, the standard binary matrix storage
18555849f57SBarry Smith   format is
18655849f57SBarry Smith .vb
18755849f57SBarry Smith      has not yet been determined
18855849f57SBarry Smith .ve
18955849f57SBarry Smith 
19055849f57SBarry Smith .seealso: PetscViewerBinaryOpen(), SNESView(), MatLoad(), VecLoad()
19155849f57SBarry Smith @*/
1922d53ad75SBarry Smith PetscErrorCode  SNESLoad(SNES snes, PetscViewer viewer)
19355849f57SBarry Smith {
19455849f57SBarry Smith   PetscErrorCode ierr;
19555849f57SBarry Smith   PetscBool      isbinary;
196060da220SMatthew G. Knepley   PetscInt       classid;
19755849f57SBarry Smith   char           type[256];
19855849f57SBarry Smith   KSP            ksp;
1992d53ad75SBarry Smith   DM             dm;
2002d53ad75SBarry Smith   DMSNES         dmsnes;
20155849f57SBarry Smith 
20255849f57SBarry Smith   PetscFunctionBegin;
2032d53ad75SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
20455849f57SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
20555849f57SBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
20655849f57SBarry Smith   if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");
20755849f57SBarry Smith 
208060da220SMatthew G. Knepley   ierr = PetscViewerBinaryRead(viewer,&classid,1,NULL,PETSC_INT);CHKERRQ(ierr);
209ce94432eSBarry Smith   if (classid != SNES_FILE_CLASSID) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_WRONG,"Not SNES next in file");
210060da220SMatthew G. Knepley   ierr = PetscViewerBinaryRead(viewer,type,256,NULL,PETSC_CHAR);CHKERRQ(ierr);
2112d53ad75SBarry Smith   ierr = SNESSetType(snes, type);CHKERRQ(ierr);
2122d53ad75SBarry Smith   if (snes->ops->load) {
2132d53ad75SBarry Smith     ierr = (*snes->ops->load)(snes,viewer);CHKERRQ(ierr);
214f2c2a1b9SBarry Smith   }
2152d53ad75SBarry Smith   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2162d53ad75SBarry Smith   ierr = DMGetDMSNES(dm,&dmsnes);CHKERRQ(ierr);
2172d53ad75SBarry Smith   ierr = DMSNESLoad(dmsnes,viewer);CHKERRQ(ierr);
2182d53ad75SBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
21955849f57SBarry Smith   ierr = KSPLoad(ksp,viewer);CHKERRQ(ierr);
22055849f57SBarry Smith   PetscFunctionReturn(0);
22155849f57SBarry Smith }
2226a388c36SPeter Brune 
2239804daf3SBarry Smith #include <petscdraw.h>
224e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
225e04113cfSBarry Smith #include <petscviewersaws.h>
226bfb97211SBarry Smith #endif
2278404b7f3SBarry Smith 
2287e2c5f70SBarry Smith /*@C
2299b94acceSBarry Smith    SNESView - Prints the SNES data structure.
2309b94acceSBarry Smith 
2314c49b128SBarry Smith    Collective on SNES
232fee21e36SBarry Smith 
233c7afd0dbSLois Curfman McInnes    Input Parameters:
234c7afd0dbSLois Curfman McInnes +  SNES - the SNES context
235c7afd0dbSLois Curfman McInnes -  viewer - visualization context
236c7afd0dbSLois Curfman McInnes 
2379b94acceSBarry Smith    Options Database Key:
238c8a8ba5cSLois Curfman McInnes .  -snes_view - Calls SNESView() at end of SNESSolve()
2399b94acceSBarry Smith 
2409b94acceSBarry Smith    Notes:
2419b94acceSBarry Smith    The available visualization contexts include
242b0a32e0cSBarry Smith +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
243b0a32e0cSBarry Smith -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
244c8a8ba5cSLois Curfman McInnes          output where only the first processor opens
245c8a8ba5cSLois Curfman McInnes          the file.  All other processors send their
246c8a8ba5cSLois Curfman McInnes          data to the first processor to print.
2479b94acceSBarry Smith 
2483e081fefSLois Curfman McInnes    The user can open an alternative visualization context with
249b0a32e0cSBarry Smith    PetscViewerASCIIOpen() - output to a specified file.
2509b94acceSBarry Smith 
25136851e7fSLois Curfman McInnes    Level: beginner
25236851e7fSLois Curfman McInnes 
2539b94acceSBarry Smith .keywords: SNES, view
2549b94acceSBarry Smith 
255b0a32e0cSBarry Smith .seealso: PetscViewerASCIIOpen()
2569b94acceSBarry Smith @*/
2577087cfbeSBarry Smith PetscErrorCode  SNESView(SNES snes,PetscViewer viewer)
2589b94acceSBarry Smith {
259fa9f3622SBarry Smith   SNESKSPEW      *kctx;
260dfbe8321SBarry Smith   PetscErrorCode ierr;
26194b7f48cSBarry Smith   KSP            ksp;
2627f1410a3SPeter Brune   SNESLineSearch linesearch;
26372a02f06SBarry Smith   PetscBool      iascii,isstring,isbinary,isdraw;
2642d53ad75SBarry Smith   DMSNES         dmsnes;
265e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
266536b137fSBarry Smith   PetscBool      issaws;
267bfb97211SBarry Smith #endif
2689b94acceSBarry Smith 
2693a40ed3dSBarry Smith   PetscFunctionBegin;
2700700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2713050cee2SBarry Smith   if (!viewer) {
272ce94432eSBarry Smith     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&viewer);CHKERRQ(ierr);
2733050cee2SBarry Smith   }
2740700a824SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
275c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,viewer,2);
27674679c65SBarry Smith 
277251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
278251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr);
27955849f57SBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
28072a02f06SBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
281e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
282536b137fSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr);
283bfb97211SBarry Smith #endif
28432077d6dSBarry Smith   if (iascii) {
285dc0571f2SMatthew G. Knepley     SNESNormSchedule normschedule;
2868404b7f3SBarry Smith     DM               dm;
2878404b7f3SBarry Smith     PetscErrorCode   (*cJ)(SNES,Vec,Mat,Mat,void*);
2888404b7f3SBarry Smith     void             *ctx;
289dc0571f2SMatthew G. Knepley 
290dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer);CHKERRQ(ierr);
291fce1e034SJed Brown     if (!snes->setupcalled) {
292fce1e034SJed Brown       ierr = PetscViewerASCIIPrintf(viewer,"  SNES has not been set up so information may be incomplete\n");CHKERRQ(ierr);
293fce1e034SJed Brown     }
294e7788613SBarry Smith     if (snes->ops->view) {
295b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
296e7788613SBarry Smith       ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr);
297b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2980ef38995SBarry Smith     }
29977431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);CHKERRQ(ierr);
30057622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  tolerances: relative=%g, absolute=%g, solution=%g\n",(double)snes->rtol,(double)snes->abstol,(double)snes->stol);CHKERRQ(ierr);
301efd4aadfSBarry Smith     if (snes->usesksp) {
30277431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr);
303efd4aadfSBarry Smith     }
30477431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr);
305dc0571f2SMatthew G. Knepley     ierr = SNESGetNormSchedule(snes, &normschedule);CHKERRQ(ierr);
306dc0571f2SMatthew G. Knepley     if (normschedule > 0) {ierr = PetscViewerASCIIPrintf(viewer,"  norm schedule %s\n",SNESNormSchedules[normschedule]);CHKERRQ(ierr);}
30717fe4bdfSPeter Brune     if (snes->gridsequence) {
30817fe4bdfSPeter Brune       ierr = PetscViewerASCIIPrintf(viewer,"  total number of grid sequence refinements=%D\n",snes->gridsequence);CHKERRQ(ierr);
30917fe4bdfSPeter Brune     }
3109b94acceSBarry Smith     if (snes->ksp_ewconv) {
311fa9f3622SBarry Smith       kctx = (SNESKSPEW*)snes->kspconvctx;
3129b94acceSBarry Smith       if (kctx) {
31377431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"  Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr);
31457622a8eSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    rtol_0=%g, rtol_max=%g, threshold=%g\n",(double)kctx->rtol_0,(double)kctx->rtol_max,(double)kctx->threshold);CHKERRQ(ierr);
31557622a8eSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    gamma=%g, alpha=%g, alpha2=%g\n",(double)kctx->gamma,(double)kctx->alpha,(double)kctx->alpha2);CHKERRQ(ierr);
3169b94acceSBarry Smith       }
3179b94acceSBarry Smith     }
318eb1f6c34SBarry Smith     if (snes->lagpreconditioner == -1) {
319eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is never rebuilt\n");CHKERRQ(ierr);
320eb1f6c34SBarry Smith     } else if (snes->lagpreconditioner > 1) {
321eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr);
322eb1f6c34SBarry Smith     }
323eb1f6c34SBarry Smith     if (snes->lagjacobian == -1) {
324eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is never rebuilt\n");CHKERRQ(ierr);
325eb1f6c34SBarry Smith     } else if (snes->lagjacobian > 1) {
32642f4f86dSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian);CHKERRQ(ierr);
327eb1f6c34SBarry Smith     }
3288404b7f3SBarry Smith     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3298404b7f3SBarry Smith     ierr = DMSNESGetJacobian(dm,&cJ,&ctx);CHKERRQ(ierr);
3308404b7f3SBarry Smith     if (cJ == SNESComputeJacobianDefault) {
3318404b7f3SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is built using finite differences one column at a time\n");CHKERRQ(ierr);
3328404b7f3SBarry Smith     } else if (cJ == SNESComputeJacobianDefaultColor) {
3338404b7f3SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is built using finite differences with coloring\n");CHKERRQ(ierr);
3348404b7f3SBarry Smith     }
3350f5bd95cSBarry Smith   } else if (isstring) {
336317d6ea6SBarry Smith     const char *type;
337454a90a3SBarry Smith     ierr = SNESGetType(snes,&type);CHKERRQ(ierr);
338b0a32e0cSBarry Smith     ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr);
33955849f57SBarry Smith   } else if (isbinary) {
34055849f57SBarry Smith     PetscInt    classid = SNES_FILE_CLASSID;
34155849f57SBarry Smith     MPI_Comm    comm;
34255849f57SBarry Smith     PetscMPIInt rank;
34355849f57SBarry Smith     char        type[256];
34455849f57SBarry Smith 
34555849f57SBarry Smith     ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
34655849f57SBarry Smith     ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
34755849f57SBarry Smith     if (!rank) {
34855849f57SBarry Smith       ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
34989d949e2SBarry Smith       ierr = PetscStrncpy(type,((PetscObject)snes)->type_name,sizeof(type));CHKERRQ(ierr);
35089d949e2SBarry Smith       ierr = PetscViewerBinaryWrite(viewer,type,sizeof(type),PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr);
35155849f57SBarry Smith     }
35255849f57SBarry Smith     if (snes->ops->view) {
35355849f57SBarry Smith       ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr);
35455849f57SBarry Smith     }
35572a02f06SBarry Smith   } else if (isdraw) {
35672a02f06SBarry Smith     PetscDraw draw;
35772a02f06SBarry Smith     char      str[36];
35889fd9fafSBarry Smith     PetscReal x,y,bottom,h;
35972a02f06SBarry Smith 
36072a02f06SBarry Smith     ierr   = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
36172a02f06SBarry Smith     ierr   = PetscDrawGetCurrentPoint(draw,&x,&y);CHKERRQ(ierr);
362a126751eSBarry Smith     ierr   = PetscStrncpy(str,"SNES: ",sizeof(str));CHKERRQ(ierr);
363a126751eSBarry Smith     ierr   = PetscStrlcat(str,((PetscObject)snes)->type_name,sizeof(str));CHKERRQ(ierr);
36451fa3d41SBarry Smith     ierr   = PetscDrawStringBoxed(draw,x,y,PETSC_DRAW_BLUE,PETSC_DRAW_BLACK,str,NULL,&h);CHKERRQ(ierr);
36589fd9fafSBarry Smith     bottom = y - h;
36672a02f06SBarry Smith     ierr   = PetscDrawPushCurrentPoint(draw,x,bottom);CHKERRQ(ierr);
367c4646bacSPeter Brune     if (snes->ops->view) {
368c4646bacSPeter Brune       ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr);
369c4646bacSPeter Brune     }
370e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
371536b137fSBarry Smith   } else if (issaws) {
372d45a07a7SBarry Smith     PetscMPIInt rank;
3732657e9d9SBarry Smith     const char *name;
374d45a07a7SBarry Smith 
3752657e9d9SBarry Smith     ierr = PetscObjectGetName((PetscObject)snes,&name);CHKERRQ(ierr);
376d45a07a7SBarry Smith     ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
377d45a07a7SBarry Smith     if (!((PetscObject)snes)->amsmem && !rank) {
378d45a07a7SBarry Smith       char       dir[1024];
379d45a07a7SBarry Smith 
380e04113cfSBarry Smith       ierr = PetscObjectViewSAWs((PetscObject)snes,viewer);CHKERRQ(ierr);
3812657e9d9SBarry Smith       ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/its",name);CHKERRQ(ierr);
3822657e9d9SBarry Smith       PetscStackCallSAWs(SAWs_Register,(dir,&snes->iter,1,SAWs_READ,SAWs_INT));
383bfb97211SBarry Smith       if (!snes->conv_hist) {
384a0931e03SBarry Smith         ierr = SNESSetConvergenceHistory(snes,NULL,NULL,PETSC_DECIDE,PETSC_TRUE);CHKERRQ(ierr);
385bfb97211SBarry Smith       }
3862657e9d9SBarry Smith       ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/conv_hist",name);CHKERRQ(ierr);
3872657e9d9SBarry Smith       PetscStackCallSAWs(SAWs_Register,(dir,snes->conv_hist,10,SAWs_READ,SAWs_DOUBLE));
388f05ece33SBarry Smith     }
389bfb97211SBarry Smith #endif
39072a02f06SBarry Smith   }
39172a02f06SBarry Smith   if (snes->linesearch) {
3927601faf0SJed Brown     ierr = SNESGetLineSearch(snes, &linesearch);CHKERRQ(ierr);
39385928a98SStefano Zampini     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
39472a02f06SBarry Smith     ierr = SNESLineSearchView(linesearch, viewer);CHKERRQ(ierr);
39585928a98SStefano Zampini     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
39619bcc07fSBarry Smith   }
397efd4aadfSBarry Smith   if (snes->npc && snes->usesnpc) {
39885928a98SStefano Zampini     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
399efd4aadfSBarry Smith     ierr = SNESView(snes->npc, viewer);CHKERRQ(ierr);
40085928a98SStefano Zampini     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
4014a0c5b0cSMatthew G Knepley   }
4022d53ad75SBarry Smith   ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
4032d53ad75SBarry Smith   ierr = DMGetDMSNES(snes->dm,&dmsnes);CHKERRQ(ierr);
4042d53ad75SBarry Smith   ierr = DMSNESView(dmsnes, viewer);CHKERRQ(ierr);
4052d53ad75SBarry Smith   ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
4062c155ee1SBarry Smith   if (snes->usesksp) {
4072c155ee1SBarry Smith     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
40885928a98SStefano Zampini     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
40994b7f48cSBarry Smith     ierr = KSPView(ksp,viewer);CHKERRQ(ierr);
41085928a98SStefano Zampini     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
4112c155ee1SBarry Smith   }
41272a02f06SBarry Smith   if (isdraw) {
41372a02f06SBarry Smith     PetscDraw draw;
41472a02f06SBarry Smith     ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
41572a02f06SBarry Smith     ierr = PetscDrawPopCurrentPoint(draw);CHKERRQ(ierr);
4167f1410a3SPeter Brune   }
4173a40ed3dSBarry Smith   PetscFunctionReturn(0);
4189b94acceSBarry Smith }
4199b94acceSBarry Smith 
42076b2cf59SMatthew Knepley /*
42176b2cf59SMatthew Knepley   We retain a list of functions that also take SNES command
42276b2cf59SMatthew Knepley   line options. These are called at the end SNESSetFromOptions()
42376b2cf59SMatthew Knepley */
42476b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5
425a7cc72afSBarry Smith static PetscInt numberofsetfromoptions;
4266849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES);
42776b2cf59SMatthew Knepley 
428ac226902SBarry Smith /*@C
42976b2cf59SMatthew Knepley   SNESAddOptionsChecker - Adds an additional function to check for SNES options.
43076b2cf59SMatthew Knepley 
43176b2cf59SMatthew Knepley   Not Collective
43276b2cf59SMatthew Knepley 
43376b2cf59SMatthew Knepley   Input Parameter:
43476b2cf59SMatthew Knepley . snescheck - function that checks for options
43576b2cf59SMatthew Knepley 
43676b2cf59SMatthew Knepley   Level: developer
43776b2cf59SMatthew Knepley 
43876b2cf59SMatthew Knepley .seealso: SNESSetFromOptions()
43976b2cf59SMatthew Knepley @*/
4407087cfbeSBarry Smith PetscErrorCode  SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES))
44176b2cf59SMatthew Knepley {
44276b2cf59SMatthew Knepley   PetscFunctionBegin;
443f23aa3ddSBarry Smith   if (numberofsetfromoptions >= MAXSETFROMOPTIONS) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS);
44476b2cf59SMatthew Knepley   othersetfromoptions[numberofsetfromoptions++] = snescheck;
44576b2cf59SMatthew Knepley   PetscFunctionReturn(0);
44676b2cf59SMatthew Knepley }
44776b2cf59SMatthew Knepley 
44825acbd8eSLisandro Dalcin PETSC_INTERN PetscErrorCode SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*);
449aa3661deSLisandro Dalcin 
450ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool hasOperator, PetscInt version)
451aa3661deSLisandro Dalcin {
452aa3661deSLisandro Dalcin   Mat            J;
453aa3661deSLisandro Dalcin   KSP            ksp;
454aa3661deSLisandro Dalcin   PC             pc;
455ace3abfcSBarry Smith   PetscBool      match;
456aa3661deSLisandro Dalcin   PetscErrorCode ierr;
457895c21f2SBarry Smith   MatNullSpace   nullsp;
458aa3661deSLisandro Dalcin 
459aa3661deSLisandro Dalcin   PetscFunctionBegin;
4600700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
461aa3661deSLisandro Dalcin 
46298613b67SLisandro Dalcin   if (!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) {
46398613b67SLisandro Dalcin     Mat A = snes->jacobian, B = snes->jacobian_pre;
4642a7a6963SBarry Smith     ierr = MatCreateVecs(A ? A : B, NULL,&snes->vec_func);CHKERRQ(ierr);
46598613b67SLisandro Dalcin   }
46698613b67SLisandro Dalcin 
467aa3661deSLisandro Dalcin   if (version == 1) {
468aa3661deSLisandro Dalcin     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
46998613b67SLisandro Dalcin     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
4709c6ac3b3SBarry Smith     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
471aa3661deSLisandro Dalcin   } else if (version == 2) {
472e32f2f54SBarry Smith     if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first");
473570b7f6dSBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) && !defined(PETSC_USE_REAL___FP16)
474aa3661deSLisandro Dalcin     ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr);
475aa3661deSLisandro Dalcin #else
476e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)");
477aa3661deSLisandro Dalcin #endif
478a8248277SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2");
479aa3661deSLisandro Dalcin 
480895c21f2SBarry Smith   /* attach any user provided null space that was on Amat to the newly created matrix free matrix */
481895c21f2SBarry Smith   if (snes->jacobian) {
482895c21f2SBarry Smith     ierr = MatGetNullSpace(snes->jacobian,&nullsp);CHKERRQ(ierr);
483895c21f2SBarry Smith     if (nullsp) {
484895c21f2SBarry Smith       ierr = MatSetNullSpace(J,nullsp);CHKERRQ(ierr);
485895c21f2SBarry Smith     }
486895c21f2SBarry Smith   }
487895c21f2SBarry Smith 
488aa3661deSLisandro Dalcin   ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr);
489d3462f78SMatthew Knepley   if (hasOperator) {
4903232da50SPeter Brune 
491aa3661deSLisandro Dalcin     /* This version replaces the user provided Jacobian matrix with a
492aa3661deSLisandro Dalcin        matrix-free version but still employs the user-provided preconditioner matrix. */
493aa3661deSLisandro Dalcin     ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr);
494aa3661deSLisandro Dalcin   } else {
495aa3661deSLisandro Dalcin     /* This version replaces both the user-provided Jacobian and the user-
4963232da50SPeter Brune      provided preconditioner Jacobian with the default matrix free version. */
497efd4aadfSBarry Smith     if ((snes->npcside== PC_LEFT) && snes->npc) {
498d728fb7dSPeter Brune       if (!snes->jacobian){ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr);}
499172a4300SPeter Brune     } else {
50028a52e04SBarry Smith       ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,0);CHKERRQ(ierr);
501172a4300SPeter Brune     }
502aa3661deSLisandro Dalcin     /* Force no preconditioner */
503aa3661deSLisandro Dalcin     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
504aa3661deSLisandro Dalcin     ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr);
505251f4c67SDmitry Karpeev     ierr = PetscObjectTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr);
506aa3661deSLisandro Dalcin     if (!match) {
507aa3661deSLisandro Dalcin       ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr);
508aa3661deSLisandro Dalcin       ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr);
509aa3661deSLisandro Dalcin     }
510aa3661deSLisandro Dalcin   }
5116bf464f9SBarry Smith   ierr = MatDestroy(&J);CHKERRQ(ierr);
512aa3661deSLisandro Dalcin   PetscFunctionReturn(0);
513aa3661deSLisandro Dalcin }
514aa3661deSLisandro Dalcin 
515dfe15315SJed Brown static PetscErrorCode DMRestrictHook_SNESVecSol(DM dmfine,Mat Restrict,Vec Rscale,Mat Inject,DM dmcoarse,void *ctx)
516dfe15315SJed Brown {
517dfe15315SJed Brown   SNES           snes = (SNES)ctx;
518dfe15315SJed Brown   PetscErrorCode ierr;
5190298fd71SBarry Smith   Vec            Xfine,Xfine_named = NULL,Xcoarse;
520dfe15315SJed Brown 
521dfe15315SJed Brown   PetscFunctionBegin;
52216ebb321SJed Brown   if (PetscLogPrintInfo) {
52316ebb321SJed Brown     PetscInt finelevel,coarselevel,fineclevel,coarseclevel;
52416ebb321SJed Brown     ierr = DMGetRefineLevel(dmfine,&finelevel);CHKERRQ(ierr);
52516ebb321SJed Brown     ierr = DMGetCoarsenLevel(dmfine,&fineclevel);CHKERRQ(ierr);
52616ebb321SJed Brown     ierr = DMGetRefineLevel(dmcoarse,&coarselevel);CHKERRQ(ierr);
52716ebb321SJed Brown     ierr = DMGetCoarsenLevel(dmcoarse,&coarseclevel);CHKERRQ(ierr);
52816ebb321SJed Brown     ierr = PetscInfo4(dmfine,"Restricting SNES solution vector from level %D-%D to level %D-%D\n",finelevel,fineclevel,coarselevel,coarseclevel);CHKERRQ(ierr);
52916ebb321SJed Brown   }
530dfe15315SJed Brown   if (dmfine == snes->dm) Xfine = snes->vec_sol;
531dfe15315SJed Brown   else {
532dfe15315SJed Brown     ierr  = DMGetNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);
533dfe15315SJed Brown     Xfine = Xfine_named;
534dfe15315SJed Brown   }
535dfe15315SJed Brown   ierr = DMGetNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr);
536907f5c5aSLawrence Mitchell   if (Inject) {
537907f5c5aSLawrence Mitchell     ierr = MatRestrict(Inject,Xfine,Xcoarse);CHKERRQ(ierr);
538907f5c5aSLawrence Mitchell   } else {
539dfe15315SJed Brown     ierr = MatRestrict(Restrict,Xfine,Xcoarse);CHKERRQ(ierr);
540dfe15315SJed Brown     ierr = VecPointwiseMult(Xcoarse,Xcoarse,Rscale);CHKERRQ(ierr);
541907f5c5aSLawrence Mitchell   }
542dfe15315SJed Brown   ierr = DMRestoreNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr);
543dfe15315SJed Brown   if (Xfine_named) {ierr = DMRestoreNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);}
544dfe15315SJed Brown   PetscFunctionReturn(0);
545dfe15315SJed Brown }
546dfe15315SJed Brown 
54716ebb321SJed Brown static PetscErrorCode DMCoarsenHook_SNESVecSol(DM dm,DM dmc,void *ctx)
54816ebb321SJed Brown {
54916ebb321SJed Brown   PetscErrorCode ierr;
55016ebb321SJed Brown 
55116ebb321SJed Brown   PetscFunctionBegin;
55216ebb321SJed Brown   ierr = DMCoarsenHookAdd(dmc,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,ctx);CHKERRQ(ierr);
55316ebb321SJed Brown   PetscFunctionReturn(0);
55416ebb321SJed Brown }
55516ebb321SJed Brown 
556a6950cb2SJed Brown /* This may be called to rediscretize the operator on levels of linear multigrid. The DM shuffle is so the user can
557a6950cb2SJed Brown  * safely call SNESGetDM() in their residual evaluation routine. */
55823ee1639SBarry Smith static PetscErrorCode KSPComputeOperators_SNES(KSP ksp,Mat A,Mat B,void *ctx)
559caa4e7f2SJed Brown {
560caa4e7f2SJed Brown   SNES           snes = (SNES)ctx;
561caa4e7f2SJed Brown   PetscErrorCode ierr;
5620298fd71SBarry Smith   Vec            X,Xnamed = NULL;
563dfe15315SJed Brown   DM             dmsave;
5644e269d77SPeter Brune   void           *ctxsave;
56525ce1634SJed Brown   PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*) = NULL;
566caa4e7f2SJed Brown 
567caa4e7f2SJed Brown   PetscFunctionBegin;
568dfe15315SJed Brown   dmsave = snes->dm;
569dfe15315SJed Brown   ierr   = KSPGetDM(ksp,&snes->dm);CHKERRQ(ierr);
570dfe15315SJed Brown   if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */
571dfe15315SJed Brown   else {                                     /* We are on a coarser level, this vec was initialized using a DM restrict hook */
572dfe15315SJed Brown     ierr = DMGetNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr);
573dfe15315SJed Brown     X    = Xnamed;
5740298fd71SBarry Smith     ierr = SNESGetJacobian(snes,NULL,NULL,&jac,&ctxsave);CHKERRQ(ierr);
5754e269d77SPeter Brune     /* If the DM's don't match up, the MatFDColoring context needed for the jacobian won't match up either -- fixit. */
5768d359177SBarry Smith     if (jac == SNESComputeJacobianDefaultColor) {
5778d359177SBarry Smith       ierr = SNESSetJacobian(snes,NULL,NULL,SNESComputeJacobianDefaultColor,0);CHKERRQ(ierr);
578dfe15315SJed Brown     }
5794e269d77SPeter Brune   }
5804e269d77SPeter Brune 
581*2b93b426SMatthew G. Knepley   /* Compute the operators */
582d1e9a80fSBarry Smith   ierr = SNESComputeJacobian(snes,X,A,B);CHKERRQ(ierr);
583*2b93b426SMatthew G. Knepley   /* Put the previous context back */
5848d359177SBarry Smith   if (snes->dm != dmsave && jac == SNESComputeJacobianDefaultColor) {
5850298fd71SBarry Smith     ierr = SNESSetJacobian(snes,NULL,NULL,jac,ctxsave);CHKERRQ(ierr);
5864e269d77SPeter Brune   }
5874e269d77SPeter Brune 
588*2b93b426SMatthew G. Knepley   if (Xnamed) {ierr = DMRestoreNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr);}
589dfe15315SJed Brown   snes->dm = dmsave;
590caa4e7f2SJed Brown   PetscFunctionReturn(0);
591caa4e7f2SJed Brown }
592caa4e7f2SJed Brown 
5936cab3a1bSJed Brown /*@
5946cab3a1bSJed Brown    SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX()
5956cab3a1bSJed Brown 
5966cab3a1bSJed Brown    Collective
5976cab3a1bSJed Brown 
5986cab3a1bSJed Brown    Input Arguments:
5996cab3a1bSJed Brown .  snes - snes to configure
6006cab3a1bSJed Brown 
6016cab3a1bSJed Brown    Level: developer
6026cab3a1bSJed Brown 
6036cab3a1bSJed Brown .seealso: SNESSetUp()
6046cab3a1bSJed Brown @*/
6056cab3a1bSJed Brown PetscErrorCode SNESSetUpMatrices(SNES snes)
6066cab3a1bSJed Brown {
6076cab3a1bSJed Brown   PetscErrorCode ierr;
6086cab3a1bSJed Brown   DM             dm;
609942e3340SBarry Smith   DMSNES         sdm;
6106cab3a1bSJed Brown 
6116cab3a1bSJed Brown   PetscFunctionBegin;
6126cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
613942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
614ce94432eSBarry Smith   if (!sdm->ops->computejacobian) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_PLIB,"DMSNES not properly configured");
615f5af7f23SKarl Rupp   else if (!snes->jacobian && snes->mf) {
6166cab3a1bSJed Brown     Mat  J;
6176cab3a1bSJed Brown     void *functx;
6186cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
6196cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
6206cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
6210298fd71SBarry Smith     ierr = SNESGetFunction(snes,NULL,NULL,&functx);CHKERRQ(ierr);
6223232da50SPeter Brune     ierr = SNESSetJacobian(snes,J,J,0,0);CHKERRQ(ierr);
6236cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
624caa4e7f2SJed Brown   } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) {
6256cab3a1bSJed Brown     Mat J,B;
6266cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
6276cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
6286cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
629b412c318SBarry Smith     ierr = DMCreateMatrix(snes->dm,&B);CHKERRQ(ierr);
63006f20277SJed Brown     /* sdm->computejacobian was already set to reach here */
6310298fd71SBarry Smith     ierr = SNESSetJacobian(snes,J,B,NULL,NULL);CHKERRQ(ierr);
6326cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
6336cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
634caa4e7f2SJed Brown   } else if (!snes->jacobian_pre) {
6354f3e65b0SMatthew G. Knepley     PetscErrorCode (*nspconstr)(DM, PetscInt, MatNullSpace *);
6361ba9b98eSMatthew G. Knepley     PetscDS          prob;
6376cab3a1bSJed Brown     Mat              J, B;
6384f3e65b0SMatthew G. Knepley     MatNullSpace     nullspace = NULL;
6391ba9b98eSMatthew G. Knepley     PetscBool        hasPrec   = PETSC_FALSE;
6404f3e65b0SMatthew G. Knepley     PetscInt         Nf;
6411ba9b98eSMatthew G. Knepley 
6426cab3a1bSJed Brown     J    = snes->jacobian;
6431ba9b98eSMatthew G. Knepley     ierr = DMGetDS(dm, &prob);CHKERRQ(ierr);
6441ba9b98eSMatthew G. Knepley     if (prob) {ierr = PetscDSHasJacobianPreconditioner(prob, &hasPrec);CHKERRQ(ierr);}
645ec9a985fSMatthew G. Knepley     if (J)            {ierr = PetscObjectReference((PetscObject) J);CHKERRQ(ierr);}
646ec9a985fSMatthew G. Knepley     else if (hasPrec) {ierr = DMCreateMatrix(snes->dm, &J);CHKERRQ(ierr);}
647b412c318SBarry Smith     ierr = DMCreateMatrix(snes->dm, &B);CHKERRQ(ierr);
6484f3e65b0SMatthew G. Knepley     ierr = PetscDSGetNumFields(prob, &Nf);CHKERRQ(ierr);
6494f3e65b0SMatthew G. Knepley     ierr = DMGetNullSpaceConstructor(snes->dm, Nf, &nspconstr);CHKERRQ(ierr);
6504f3e65b0SMatthew G. Knepley     if (nspconstr) (*nspconstr)(snes->dm, -1, &nullspace);
6514f3e65b0SMatthew G. Knepley     ierr = MatSetNullSpace(B, nullspace);CHKERRQ(ierr);
6524f3e65b0SMatthew G. Knepley     ierr = MatNullSpaceDestroy(&nullspace);CHKERRQ(ierr);
6530298fd71SBarry Smith     ierr = SNESSetJacobian(snes, J ? J : B, B, NULL, NULL);CHKERRQ(ierr);
6541ba9b98eSMatthew G. Knepley     ierr = MatDestroy(&J);CHKERRQ(ierr);
6556cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
6566cab3a1bSJed Brown   }
657caa4e7f2SJed Brown   {
658caa4e7f2SJed Brown     KSP ksp;
659caa4e7f2SJed Brown     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
660caa4e7f2SJed Brown     ierr = KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes);CHKERRQ(ierr);
66116ebb321SJed Brown     ierr = DMCoarsenHookAdd(snes->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr);
662caa4e7f2SJed Brown   }
6636cab3a1bSJed Brown   PetscFunctionReturn(0);
6646cab3a1bSJed Brown }
6656cab3a1bSJed Brown 
666fde5950dSBarry Smith /*@C
667fde5950dSBarry Smith    SNESMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user
668fde5950dSBarry Smith 
669fde5950dSBarry Smith    Collective on SNES
670fde5950dSBarry Smith 
671fde5950dSBarry Smith    Input Parameters:
672fde5950dSBarry Smith +  snes - SNES object you wish to monitor
673fde5950dSBarry Smith .  name - the monitor type one is seeking
674fde5950dSBarry Smith .  help - message indicating what monitoring is done
675fde5950dSBarry Smith .  manual - manual page for the monitor
676fde5950dSBarry Smith .  monitor - the monitor function
677fde5950dSBarry Smith -  monitorsetup - a function that is called once ONLY if the user selected this monitor that may set additional features of the SNES or PetscViewer objects
678fde5950dSBarry Smith 
679fde5950dSBarry Smith    Level: developer
680fde5950dSBarry Smith 
681fde5950dSBarry Smith .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
682fde5950dSBarry Smith           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
683fde5950dSBarry Smith           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
684fde5950dSBarry Smith           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
685fde5950dSBarry Smith           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
686fde5950dSBarry Smith           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
687fde5950dSBarry Smith           PetscOptionsFList(), PetscOptionsEList()
688fde5950dSBarry Smith @*/
689d43b4f6eSBarry Smith PetscErrorCode  SNESMonitorSetFromOptions(SNES snes,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(SNES,PetscViewerAndFormat*))
690fde5950dSBarry Smith {
691fde5950dSBarry Smith   PetscErrorCode    ierr;
692fde5950dSBarry Smith   PetscViewer       viewer;
693fde5950dSBarry Smith   PetscViewerFormat format;
694fde5950dSBarry Smith   PetscBool         flg;
695fde5950dSBarry Smith 
696fde5950dSBarry Smith   PetscFunctionBegin;
697fde5950dSBarry Smith   ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,name,&viewer,&format,&flg);CHKERRQ(ierr);
698fde5950dSBarry Smith   if (flg) {
699d43b4f6eSBarry Smith     PetscViewerAndFormat *vf;
700d43b4f6eSBarry Smith     ierr = PetscViewerAndFormatCreate(viewer,format,&vf);CHKERRQ(ierr);
701d43b4f6eSBarry Smith     ierr = PetscObjectDereference((PetscObject)viewer);CHKERRQ(ierr);
702fde5950dSBarry Smith     if (monitorsetup) {
703d43b4f6eSBarry Smith       ierr = (*monitorsetup)(snes,vf);CHKERRQ(ierr);
704fde5950dSBarry Smith     }
705d43b4f6eSBarry Smith     ierr = SNESMonitorSet(snes,(PetscErrorCode (*)(SNES,PetscInt,PetscReal,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy);CHKERRQ(ierr);
706fde5950dSBarry Smith   }
707fde5950dSBarry Smith   PetscFunctionReturn(0);
708fde5950dSBarry Smith }
709fde5950dSBarry Smith 
7109b94acceSBarry Smith /*@
71194b7f48cSBarry Smith    SNESSetFromOptions - Sets various SNES and KSP parameters from user options.
7129b94acceSBarry Smith 
713c7afd0dbSLois Curfman McInnes    Collective on SNES
714c7afd0dbSLois Curfman McInnes 
7159b94acceSBarry Smith    Input Parameter:
7169b94acceSBarry Smith .  snes - the SNES context
7179b94acceSBarry Smith 
71836851e7fSLois Curfman McInnes    Options Database Keys:
719722329fbSBarry Smith +  -snes_type <type> - newtonls, newtontr, ngmres, ncg, nrichardson, qn, vi, fas, SNESType for complete list
72082738288SBarry Smith .  -snes_stol - convergence tolerance in terms of the norm
72182738288SBarry Smith                 of the change in the solution between steps
72270441072SBarry Smith .  -snes_atol <abstol> - absolute tolerance of residual norm
723b39c3a46SLois Curfman McInnes .  -snes_rtol <rtol> - relative decrease in tolerance norm from initial
724e4d06f11SPatrick Farrell .  -snes_divergence_tolerance <divtol> - if the residual goes above divtol*rnorm0, exit with divergence
725be5caee7SBarry Smith .  -snes_force_iteration <force> - force SNESSolve() to take at least one iteration
726b39c3a46SLois Curfman McInnes .  -snes_max_it <max_it> - maximum number of iterations
727b39c3a46SLois Curfman McInnes .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
7284839bfe8SBarry Smith .  -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none
729ddf469c8SBarry Smith .  -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops
730a8054027SBarry Smith .  -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild)
731e35cf81dSBarry Smith .  -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild)
732b39c3a46SLois Curfman McInnes .  -snes_trtol <trtol> - trust region tolerance
7332492ecdbSBarry Smith .  -snes_no_convergence_test - skip convergence test in nonlinear
73482738288SBarry Smith                                solver; hence iterations will continue until max_it
7351fbbfb26SLois Curfman McInnes                                or some other criterion is reached. Saves expense
73682738288SBarry Smith                                of convergence test
737fde5950dSBarry Smith .  -snes_monitor [ascii][:filename][:viewer format] - prints residual norm at each iteration. if no filename given prints to stdout
738fde5950dSBarry Smith .  -snes_monitor_solution [ascii binary draw][:filename][:viewer format] - plots solution at each iteration
739fde5950dSBarry Smith .  -snes_monitor_residual [ascii binary draw][:filename][:viewer format] - plots residual (not its norm) at each iteration
740fde5950dSBarry Smith .  -snes_monitor_solution_update [ascii binary draw][:filename][:viewer format] - plots update to solution at each iteration
7414619e776SBarry Smith .  -snes_monitor_lg_residualnorm - plots residual norm at each iteration
742459f5d12SBarry Smith .  -snes_monitor_lg_range - plots residual norm at each iteration
743e24b481bSBarry Smith .  -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
744e2e60de9SPeter Brune .  -snes_fd_color - use finite differences with coloring to compute Jacobian
7455968eb51SBarry Smith .  -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
746fee2055bSBarry Smith -  -snes_converged_reason - print the reason for convergence/divergence after each solve
74782738288SBarry Smith 
74882738288SBarry Smith     Options Database for Eisenstat-Walker method:
749fa9f3622SBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
7504b27c08aSLois Curfman McInnes .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
75136851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
75236851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
75336851e7fSLois Curfman McInnes .  -snes_ksp_ew_gamma <gamma> - Sets gamma
75436851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha <alpha> - Sets alpha
75536851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
75636851e7fSLois Curfman McInnes -  -snes_ksp_ew_threshold <threshold> - Sets threshold
75782738288SBarry Smith 
75811ca99fdSLois Curfman McInnes    Notes:
75911ca99fdSLois Curfman McInnes    To see all options, run your program with the -help option or consult
760a7f22e61SSatish Balay    Users-Manual: ch_snes
76183e2fdc7SBarry Smith 
76236851e7fSLois Curfman McInnes    Level: beginner
76336851e7fSLois Curfman McInnes 
7649b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database
7659b94acceSBarry Smith 
766b3cd9a81SMatthew G. Knepley .seealso: SNESSetOptionsPrefix(), SNESResetFromOptions()
7679b94acceSBarry Smith @*/
7687087cfbeSBarry Smith PetscErrorCode  SNESSetFromOptions(SNES snes)
7699b94acceSBarry Smith {
7708afaa268SBarry Smith   PetscBool      flg,pcset,persist,set;
771d8f46077SPeter Brune   PetscInt       i,indx,lag,grids;
77204d7464bSBarry Smith   const char     *deft        = SNESNEWTONLS;
77385385478SLisandro Dalcin   const char     *convtests[] = {"default","skip"};
77485385478SLisandro Dalcin   SNESKSPEW      *kctx        = NULL;
775e8105e01SRichard Katz   char           type[256], monfilename[PETSC_MAX_PATH_LEN];
77685385478SLisandro Dalcin   PetscErrorCode ierr;
777c40d0f55SPeter Brune   PCSide         pcside;
778a64e098fSPeter Brune   const char     *optionsprefix;
7799b94acceSBarry Smith 
7803a40ed3dSBarry Smith   PetscFunctionBegin;
7810700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
7820f51fdf8SToby Isaac   ierr = SNESRegisterAll();CHKERRQ(ierr);
7833194b578SJed Brown   ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr);
784639ff905SBarry Smith   if (((PetscObject)snes)->type_name) deft = ((PetscObject)snes)->type_name;
785a264d7a6SBarry Smith   ierr = PetscOptionsFList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr);
786d64ed03dSBarry Smith   if (flg) {
787186905e3SBarry Smith     ierr = SNESSetType(snes,type);CHKERRQ(ierr);
7887adad957SLisandro Dalcin   } else if (!((PetscObject)snes)->type_name) {
789186905e3SBarry Smith     ierr = SNESSetType(snes,deft);CHKERRQ(ierr);
790d64ed03dSBarry Smith   }
79194ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,NULL);CHKERRQ(ierr);
79294ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,NULL);CHKERRQ(ierr);
793186905e3SBarry Smith 
79494ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,NULL);CHKERRQ(ierr);
795e4d06f11SPatrick Farrell   ierr = PetscOptionsReal("-snes_divergence_tolerance","Stop if residual norm increases by this factor","SNESSetDivergenceTolerance",snes->divtol,&snes->divtol,NULL);CHKERRQ(ierr);
7960298fd71SBarry Smith   ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,NULL);CHKERRQ(ierr);
7970298fd71SBarry Smith   ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,NULL);CHKERRQ(ierr);
7980298fd71SBarry Smith   ierr = PetscOptionsInt("-snes_max_fail","Maximum nonlinear step failures","SNESSetMaxNonlinearStepFailures",snes->maxFailures,&snes->maxFailures,NULL);CHKERRQ(ierr);
7990298fd71SBarry Smith   ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,NULL);CHKERRQ(ierr);
8000298fd71SBarry Smith   ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,NULL);CHKERRQ(ierr);
8010d6f27a8SBarry Smith   ierr = PetscOptionsBool("-snes_force_iteration","Force SNESSolve() to take at least one iteration","SNESSetForceIteration",snes->forceiteration,&snes->forceiteration,NULL);CHKERRQ(ierr);
80285385478SLisandro Dalcin 
803a8054027SBarry Smith   ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr);
804a8054027SBarry Smith   if (flg) {
805a8054027SBarry Smith     ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr);
806a8054027SBarry Smith   }
80737ec4e1aSPeter Brune   ierr = PetscOptionsBool("-snes_lag_preconditioner_persists","Preconditioner lagging through multiple solves","SNESSetLagPreconditionerPersists",snes->lagjac_persist,&persist,&flg);CHKERRQ(ierr);
80837ec4e1aSPeter Brune   if (flg) {
80937ec4e1aSPeter Brune     ierr = SNESSetLagPreconditionerPersists(snes,persist);CHKERRQ(ierr);
81037ec4e1aSPeter Brune   }
811e35cf81dSBarry Smith   ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr);
812e35cf81dSBarry Smith   if (flg) {
813e35cf81dSBarry Smith     ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr);
814e35cf81dSBarry Smith   }
81537ec4e1aSPeter Brune   ierr = PetscOptionsBool("-snes_lag_jacobian_persists","Jacobian lagging through multiple solves","SNESSetLagJacobianPersists",snes->lagjac_persist,&persist,&flg);CHKERRQ(ierr);
81637ec4e1aSPeter Brune   if (flg) {
81737ec4e1aSPeter Brune     ierr = SNESSetLagJacobianPersists(snes,persist);CHKERRQ(ierr);
81837ec4e1aSPeter Brune   }
81937ec4e1aSPeter Brune 
820efd51863SBarry Smith   ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr);
821efd51863SBarry Smith   if (flg) {
822efd51863SBarry Smith     ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr);
823efd51863SBarry Smith   }
824a8054027SBarry Smith 
82585385478SLisandro Dalcin   ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr);
82685385478SLisandro Dalcin   if (flg) {
82785385478SLisandro Dalcin     switch (indx) {
8288d359177SBarry Smith     case 0: ierr = SNESSetConvergenceTest(snes,SNESConvergedDefault,NULL,NULL);CHKERRQ(ierr); break;
829e2a6519dSDmitry Karpeev     case 1: ierr = SNESSetConvergenceTest(snes,SNESConvergedSkip,NULL,NULL);CHKERRQ(ierr);    break;
83085385478SLisandro Dalcin     }
83185385478SLisandro Dalcin   }
83285385478SLisandro Dalcin 
833365a6726SPeter Brune   ierr = PetscOptionsEList("-snes_norm_schedule","SNES Norm schedule","SNESSetNormSchedule",SNESNormSchedules,5,"function",&indx,&flg);CHKERRQ(ierr);
834365a6726SPeter Brune   if (flg) { ierr = SNESSetNormSchedule(snes,(SNESNormSchedule)indx);CHKERRQ(ierr); }
835fdacfa88SPeter Brune 
83647073ea2SPeter Brune   ierr = PetscOptionsEList("-snes_function_type","SNES Norm schedule","SNESSetFunctionType",SNESFunctionTypes,2,"unpreconditioned",&indx,&flg);CHKERRQ(ierr);
83747073ea2SPeter Brune   if (flg) { ierr = SNESSetFunctionType(snes,(SNESFunctionType)indx);CHKERRQ(ierr); }
838186905e3SBarry Smith 
83985385478SLisandro Dalcin   kctx = (SNESKSPEW*)snes->kspconvctx;
84085385478SLisandro Dalcin 
8410298fd71SBarry Smith   ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,NULL);CHKERRQ(ierr);
842186905e3SBarry Smith 
84394ae4db5SBarry Smith   ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,NULL);CHKERRQ(ierr);
84494ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,NULL);CHKERRQ(ierr);
84594ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,NULL);CHKERRQ(ierr);
84694ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,NULL);CHKERRQ(ierr);
84794ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,NULL);CHKERRQ(ierr);
84894ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,NULL);CHKERRQ(ierr);
84994ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,NULL);CHKERRQ(ierr);
850186905e3SBarry Smith 
85190d69ab7SBarry Smith   flg  = PETSC_FALSE;
8528afaa268SBarry Smith   ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,&set);CHKERRQ(ierr);
8538afaa268SBarry Smith   if (set && flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);}
854eabae89aSBarry Smith 
855fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor","Monitor norm of function","SNESMonitorDefault",SNESMonitorDefault,NULL);CHKERRQ(ierr);
856fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_short","Monitor norm of function with fewer digits","SNESMonitorDefaultShort",SNESMonitorDefaultShort,NULL);CHKERRQ(ierr);
857fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_range","Monitor range of elements of function","SNESMonitorRange",SNESMonitorRange,NULL);CHKERRQ(ierr);
858eabae89aSBarry Smith 
859fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_ratio","Monitor ratios of the norm of function for consecutive steps","SNESMonitorRatio",SNESMonitorRatio,SNESMonitorRatioSetUp);CHKERRQ(ierr);
860fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_field","Monitor norm of function (split into fields)","SNESMonitorDefaultField",SNESMonitorDefaultField,NULL);CHKERRQ(ierr);
861fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_solution","View solution at each iteration","SNESMonitorSolution",SNESMonitorSolution,NULL);CHKERRQ(ierr);
862fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_solution_update","View correction at each iteration","SNESMonitorSolutionUpdate",SNESMonitorSolutionUpdate,NULL);CHKERRQ(ierr);
863fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_residual","View residual at each iteration","SNESMonitorResidual",SNESMonitorResidual,NULL);CHKERRQ(ierr);
864fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_jacupdate_spectrum","Print the change in the spectrum of the Jacobian","SNESMonitorJacUpdateSpectrum",SNESMonitorJacUpdateSpectrum,NULL);CHKERRQ(ierr);
865fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_fields","Monitor norm of function per field","SNESMonitorSet",SNESMonitorFields,NULL);CHKERRQ(ierr);
8662db13446SMatthew G. Knepley 
8675180491cSLisandro Dalcin   ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
8685180491cSLisandro Dalcin   if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);}
8695180491cSLisandro Dalcin 
870fde5950dSBarry Smith 
87190d69ab7SBarry Smith   flg  = PETSC_FALSE;
8720298fd71SBarry Smith   ierr = PetscOptionsBool("-snes_monitor_lg_residualnorm","Plot function norm at each iteration","SNESMonitorLGResidualNorm",flg,&flg,NULL);CHKERRQ(ierr);
873459f5d12SBarry Smith   if (flg) {
874d96771aaSLisandro Dalcin     PetscDrawLG ctx;
875459f5d12SBarry Smith 
8766ba87a44SLisandro Dalcin     ierr = SNESMonitorLGCreate(PetscObjectComm((PetscObject)snes),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);CHKERRQ(ierr);
877d96771aaSLisandro Dalcin     ierr = SNESMonitorSet(snes,SNESMonitorLGResidualNorm,ctx,(PetscErrorCode (*)(void**))PetscDrawLGDestroy);CHKERRQ(ierr);
878459f5d12SBarry Smith   }
87990d69ab7SBarry Smith   flg  = PETSC_FALSE;
8800298fd71SBarry Smith   ierr = PetscOptionsBool("-snes_monitor_lg_range","Plot function range at each iteration","SNESMonitorLGRange",flg,&flg,NULL);CHKERRQ(ierr);
881459f5d12SBarry Smith   if (flg) {
882459f5d12SBarry Smith     PetscViewer ctx;
883e24b481bSBarry Smith 
8846ba87a44SLisandro Dalcin     ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);CHKERRQ(ierr);
885459f5d12SBarry Smith     ierr = SNESMonitorSet(snes,SNESMonitorLGRange,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
886459f5d12SBarry Smith   }
8872e7541e6SPeter Brune 
8882e7541e6SPeter Brune 
889cc0c4584SMatthew G. Knepley 
89090d69ab7SBarry Smith   flg  = PETSC_FALSE;
8918d359177SBarry Smith   ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESComputeJacobianDefault",flg,&flg,NULL);CHKERRQ(ierr);
8924b27c08aSLois Curfman McInnes   if (flg) {
8936cab3a1bSJed Brown     void    *functx;
894b1f624c7SBarry Smith     DM      dm;
895b1f624c7SBarry Smith     DMSNES  sdm;
896b1f624c7SBarry Smith     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
897b1f624c7SBarry Smith     ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
898b1f624c7SBarry Smith     sdm->jacobianctx = NULL;
8990298fd71SBarry Smith     ierr = SNESGetFunction(snes,NULL,NULL,&functx);CHKERRQ(ierr);
9008d359177SBarry Smith     ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESComputeJacobianDefault,functx);CHKERRQ(ierr);
901ae15b995SBarry Smith     ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr);
9029b94acceSBarry Smith   }
903639f9d9dSBarry Smith 
90444848bc4SPeter Brune   flg  = PETSC_FALSE;
9058d359177SBarry Smith   ierr = PetscOptionsBool("-snes_fd_function","Use finite differences (slow) to compute function from user objective","SNESObjectiveComputeFunctionDefaultFD",flg,&flg,NULL);CHKERRQ(ierr);
90697584545SPeter Brune   if (flg) {
9078d359177SBarry Smith     ierr = SNESSetFunction(snes,NULL,SNESObjectiveComputeFunctionDefaultFD,NULL);CHKERRQ(ierr);
90897584545SPeter Brune   }
90997584545SPeter Brune 
91097584545SPeter Brune   flg  = PETSC_FALSE;
9118d359177SBarry Smith   ierr = PetscOptionsBool("-snes_fd_color","Use finite differences with coloring to compute Jacobian","SNESComputeJacobianDefaultColor",flg,&flg,NULL);CHKERRQ(ierr);
91244848bc4SPeter Brune   if (flg) {
913c52e227fSPeter Brune     DM             dm;
914c52e227fSPeter Brune     DMSNES         sdm;
915c52e227fSPeter Brune     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
916aace71b7SPeter Brune     ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
917aace71b7SPeter Brune     sdm->jacobianctx = NULL;
9188d359177SBarry Smith     ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESComputeJacobianDefaultColor,0);CHKERRQ(ierr);
91944848bc4SPeter Brune     ierr = PetscInfo(snes,"Setting default finite difference coloring Jacobian matrix\n");CHKERRQ(ierr);
92044848bc4SPeter Brune   }
92144848bc4SPeter Brune 
922aa3661deSLisandro Dalcin   flg  = PETSC_FALSE;
923f871313dSBarry Smith   ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","SNESSetUseMatrixFree",PETSC_FALSE,&snes->mf_operator,&flg);CHKERRQ(ierr);
924d8f46077SPeter Brune   if (flg && snes->mf_operator) {
925a8248277SBarry Smith     snes->mf_operator = PETSC_TRUE;
926d8f46077SPeter Brune     snes->mf          = PETSC_TRUE;
927a8248277SBarry Smith   }
928aa3661deSLisandro Dalcin   flg  = PETSC_FALSE;
929f871313dSBarry Smith   ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","SNESSetUseMatrixFree",PETSC_FALSE,&snes->mf,&flg);CHKERRQ(ierr);
930d8f46077SPeter Brune   if (!flg && snes->mf_operator) snes->mf = PETSC_TRUE;
931d8f46077SPeter Brune   ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",snes->mf_version,&snes->mf_version,0);CHKERRQ(ierr);
932d28543b3SPeter Brune 
933c40d0f55SPeter Brune   flg  = PETSC_FALSE;
934be95d8f1SBarry Smith   ierr = SNESGetNPCSide(snes,&pcside);CHKERRQ(ierr);
935be95d8f1SBarry Smith   ierr = PetscOptionsEnum("-snes_npc_side","SNES nonlinear preconditioner side","SNESSetNPCSide",PCSides,(PetscEnum)pcside,(PetscEnum*)&pcside,&flg);CHKERRQ(ierr);
936be95d8f1SBarry Smith   if (flg) {ierr = SNESSetNPCSide(snes,pcside);CHKERRQ(ierr);}
937c40d0f55SPeter Brune 
938e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
9398a70d858SHong Zhang   /*
9408a70d858SHong Zhang     Publish convergence information using SAWs
9418a70d858SHong Zhang   */
9428a70d858SHong Zhang   flg  = PETSC_FALSE;
9438a70d858SHong Zhang   ierr = PetscOptionsBool("-snes_monitor_saws","Publish SNES progress using SAWs","SNESMonitorSet",flg,&flg,NULL);CHKERRQ(ierr);
9448a70d858SHong Zhang   if (flg) {
9458a70d858SHong Zhang     void *ctx;
9468a70d858SHong Zhang     ierr = SNESMonitorSAWsCreate(snes,&ctx);CHKERRQ(ierr);
9478a70d858SHong Zhang     ierr = SNESMonitorSet(snes,SNESMonitorSAWs,ctx,SNESMonitorSAWsDestroy);CHKERRQ(ierr);
9488a70d858SHong Zhang   }
9498a70d858SHong Zhang #endif
9508a70d858SHong Zhang #if defined(PETSC_HAVE_SAWS)
951b90c6cbeSBarry Smith   {
952b90c6cbeSBarry Smith   PetscBool set;
953b90c6cbeSBarry Smith   flg  = PETSC_FALSE;
9548a70d858SHong Zhang   ierr = PetscOptionsBool("-snes_saws_block","Block for SAWs at end of SNESSolve","PetscObjectSAWsBlock",((PetscObject)snes)->amspublishblock,&flg,&set);CHKERRQ(ierr);
955b90c6cbeSBarry Smith   if (set) {
956e04113cfSBarry Smith     ierr = PetscObjectSAWsSetBlock((PetscObject)snes,flg);CHKERRQ(ierr);
957b90c6cbeSBarry Smith   }
958b90c6cbeSBarry Smith   }
959b90c6cbeSBarry Smith #endif
960b90c6cbeSBarry Smith 
96176b2cf59SMatthew Knepley   for (i = 0; i < numberofsetfromoptions; i++) {
96276b2cf59SMatthew Knepley     ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr);
96376b2cf59SMatthew Knepley   }
96476b2cf59SMatthew Knepley 
965e7788613SBarry Smith   if (snes->ops->setfromoptions) {
966e55864a3SBarry Smith     ierr = (*snes->ops->setfromoptions)(PetscOptionsObject,snes);CHKERRQ(ierr);
967639f9d9dSBarry Smith   }
9685d973c19SBarry Smith 
9695d973c19SBarry Smith   /* process any options handlers added with PetscObjectAddOptionsHandler() */
9700633abcbSJed Brown   ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)snes);CHKERRQ(ierr);
971b0a32e0cSBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
9724bbc92c1SBarry Smith 
9739e764e56SPeter Brune   if (!snes->linesearch) {
9747601faf0SJed Brown     ierr = SNESGetLineSearch(snes, &snes->linesearch);CHKERRQ(ierr);
9759e764e56SPeter Brune   }
976f1c6b773SPeter Brune   ierr = SNESLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr);
9779e764e56SPeter Brune 
9786991f827SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
9796991f827SBarry Smith   ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre);CHKERRQ(ierr);
9806991f827SBarry Smith   ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr);
9816991f827SBarry Smith 
982be95d8f1SBarry Smith   /* if someone has set the SNES NPC type, create it. */
98351e86f29SPeter Brune   ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
984c5929fdfSBarry Smith   ierr = PetscOptionsHasName(((PetscObject)snes)->options,optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr);
985efd4aadfSBarry Smith   if (pcset && (!snes->npc)) {
986efd4aadfSBarry Smith     ierr = SNESGetNPC(snes, &snes->npc);CHKERRQ(ierr);
98751e86f29SPeter Brune   }
988b3cd9a81SMatthew G. Knepley   snes->setfromoptionscalled++;
989b3cd9a81SMatthew G. Knepley   PetscFunctionReturn(0);
990b3cd9a81SMatthew G. Knepley }
991b3cd9a81SMatthew G. Knepley 
992b3cd9a81SMatthew G. Knepley /*@
993b3cd9a81SMatthew G. Knepley    SNESResetFromOptions - Sets various SNES and KSP parameters from user options ONLY if the SNES was previously set from options
994b3cd9a81SMatthew G. Knepley 
995b3cd9a81SMatthew G. Knepley    Collective on SNES
996b3cd9a81SMatthew G. Knepley 
997b3cd9a81SMatthew G. Knepley    Input Parameter:
998b3cd9a81SMatthew G. Knepley .  snes - the SNES context
999b3cd9a81SMatthew G. Knepley 
1000b3cd9a81SMatthew G. Knepley    Level: beginner
1001b3cd9a81SMatthew G. Knepley 
1002b3cd9a81SMatthew G. Knepley .keywords: SNES, nonlinear, set, options, database
1003b3cd9a81SMatthew G. Knepley 
1004b3cd9a81SMatthew G. Knepley .seealso: SNESSetFromOptions(), SNESSetOptionsPrefix()
1005b3cd9a81SMatthew G. Knepley @*/
1006b3cd9a81SMatthew G. Knepley PetscErrorCode SNESResetFromOptions(SNES snes)
1007b3cd9a81SMatthew G. Knepley {
1008b3cd9a81SMatthew G. Knepley   PetscErrorCode ierr;
1009b3cd9a81SMatthew G. Knepley 
1010b3cd9a81SMatthew G. Knepley   PetscFunctionBegin;
1011b3cd9a81SMatthew G. Knepley   if (snes->setfromoptionscalled) {ierr = SNESSetFromOptions(snes);CHKERRQ(ierr);}
10123a40ed3dSBarry Smith   PetscFunctionReturn(0);
10139b94acceSBarry Smith }
10149b94acceSBarry Smith 
1015bb9467b5SJed Brown /*@C
1016d25893d9SBarry Smith    SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for
1017d25893d9SBarry Smith    the nonlinear solvers.
1018d25893d9SBarry Smith 
1019d25893d9SBarry Smith    Logically Collective on SNES
1020d25893d9SBarry Smith 
1021d25893d9SBarry Smith    Input Parameters:
1022d25893d9SBarry Smith +  snes - the SNES context
1023d25893d9SBarry Smith .  compute - function to compute the context
1024d25893d9SBarry Smith -  destroy - function to destroy the context
1025d25893d9SBarry Smith 
1026d25893d9SBarry Smith    Level: intermediate
1027d25893d9SBarry Smith 
1028bb9467b5SJed Brown    Notes:
1029bb9467b5SJed Brown    This function is currently not available from Fortran.
1030bb9467b5SJed Brown 
1031d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context
1032d25893d9SBarry Smith 
1033d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext()
1034d25893d9SBarry Smith @*/
1035d25893d9SBarry Smith PetscErrorCode  SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**))
1036d25893d9SBarry Smith {
1037d25893d9SBarry Smith   PetscFunctionBegin;
1038d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1039d25893d9SBarry Smith   snes->ops->usercompute = compute;
1040d25893d9SBarry Smith   snes->ops->userdestroy = destroy;
1041d25893d9SBarry Smith   PetscFunctionReturn(0);
1042d25893d9SBarry Smith }
1043a847f771SSatish Balay 
1044b07ff414SBarry Smith /*@
10459b94acceSBarry Smith    SNESSetApplicationContext - Sets the optional user-defined context for
10469b94acceSBarry Smith    the nonlinear solvers.
10479b94acceSBarry Smith 
10483f9fe445SBarry Smith    Logically Collective on SNES
1049fee21e36SBarry Smith 
1050c7afd0dbSLois Curfman McInnes    Input Parameters:
1051c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1052c7afd0dbSLois Curfman McInnes -  usrP - optional user context
1053c7afd0dbSLois Curfman McInnes 
105436851e7fSLois Curfman McInnes    Level: intermediate
105536851e7fSLois Curfman McInnes 
105695452b02SPatrick Sanan    Fortran Notes:
105795452b02SPatrick Sanan     To use this from Fortran you must write a Fortran interface definition for this
1058daf670e6SBarry Smith     function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument.
1059daf670e6SBarry Smith 
10609b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context
10619b94acceSBarry Smith 
1062ecaffddaSVictor Eijkhout .seealso: SNESGetApplicationContext()
10639b94acceSBarry Smith @*/
10647087cfbeSBarry Smith PetscErrorCode  SNESSetApplicationContext(SNES snes,void *usrP)
10659b94acceSBarry Smith {
10661b2093e4SBarry Smith   PetscErrorCode ierr;
1067b07ff414SBarry Smith   KSP            ksp;
10681b2093e4SBarry Smith 
10693a40ed3dSBarry Smith   PetscFunctionBegin;
10700700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1071b07ff414SBarry Smith   ierr       = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
1072b07ff414SBarry Smith   ierr       = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr);
10739b94acceSBarry Smith   snes->user = usrP;
10743a40ed3dSBarry Smith   PetscFunctionReturn(0);
10759b94acceSBarry Smith }
107674679c65SBarry Smith 
1077b07ff414SBarry Smith /*@
10789b94acceSBarry Smith    SNESGetApplicationContext - Gets the user-defined context for the
10799b94acceSBarry Smith    nonlinear solvers.
10809b94acceSBarry Smith 
1081c7afd0dbSLois Curfman McInnes    Not Collective
1082c7afd0dbSLois Curfman McInnes 
10839b94acceSBarry Smith    Input Parameter:
10849b94acceSBarry Smith .  snes - SNES context
10859b94acceSBarry Smith 
10869b94acceSBarry Smith    Output Parameter:
10879b94acceSBarry Smith .  usrP - user context
10889b94acceSBarry Smith 
108995452b02SPatrick Sanan    Fortran Notes:
109095452b02SPatrick Sanan     To use this from Fortran you must write a Fortran interface definition for this
1091daf670e6SBarry Smith     function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument.
1092daf670e6SBarry Smith 
109336851e7fSLois Curfman McInnes    Level: intermediate
109436851e7fSLois Curfman McInnes 
10959b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context
10969b94acceSBarry Smith 
10979b94acceSBarry Smith .seealso: SNESSetApplicationContext()
10989b94acceSBarry Smith @*/
1099e71120c6SJed Brown PetscErrorCode  SNESGetApplicationContext(SNES snes,void *usrP)
11009b94acceSBarry Smith {
11013a40ed3dSBarry Smith   PetscFunctionBegin;
11020700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1103e71120c6SJed Brown   *(void**)usrP = snes->user;
11043a40ed3dSBarry Smith   PetscFunctionReturn(0);
11059b94acceSBarry Smith }
110674679c65SBarry Smith 
11079b94acceSBarry Smith /*@
11083565c898SBarry Smith    SNESSetUseMatrixFree - indicates that SNES should use matrix free finite difference matrix vector products internally to apply
11093565c898SBarry Smith                           the Jacobian.
11103565c898SBarry Smith 
11113565c898SBarry Smith    Collective on SNES
11123565c898SBarry Smith 
11133565c898SBarry Smith    Input Parameters:
11143565c898SBarry Smith +  snes - SNES context
11153565c898SBarry Smith .  mf - use matrix-free for both the Amat and Pmat used by SNESSetJacobian(), both the Amat and Pmat set in SNESSetJacobian() will be ignored
11163565c898SBarry Smith -  mf_operator - use matrix-free only for the Amat used by SNESSetJacobian(), this means the user provided Pmat will continue to be used
11173565c898SBarry Smith 
11183565c898SBarry Smith    Options Database:
11193565c898SBarry Smith + -snes_mf - use matrix free for both the mat and pmat operator
11203565c898SBarry Smith - -snes_mf_operator - use matrix free only for the mat operator
11213565c898SBarry Smith 
11223565c898SBarry Smith    Level: intermediate
11233565c898SBarry Smith 
11243565c898SBarry Smith .keywords: SNES, nonlinear, get, iteration, number,
11253565c898SBarry Smith 
11263565c898SBarry Smith .seealso:   SNESGetUseMatrixFree(), MatCreateSNESMF()
11273565c898SBarry Smith @*/
11283565c898SBarry Smith PetscErrorCode  SNESSetUseMatrixFree(SNES snes,PetscBool mf_operator,PetscBool mf)
11293565c898SBarry Smith {
11303565c898SBarry Smith   PetscFunctionBegin;
11313565c898SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
113288b4c220SStefano Zampini   PetscValidLogicalCollectiveBool(snes,mf_operator,2);
113388b4c220SStefano Zampini   PetscValidLogicalCollectiveBool(snes,mf,3);
11343565c898SBarry Smith   if (mf && !mf_operator) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_INCOMP,"If using mf must also use mf_operator");
11353565c898SBarry Smith   snes->mf          = mf;
11363565c898SBarry Smith   snes->mf_operator = mf_operator;
11373565c898SBarry Smith   PetscFunctionReturn(0);
11383565c898SBarry Smith }
11393565c898SBarry Smith 
11403565c898SBarry Smith /*@
11413565c898SBarry Smith    SNESGetUseMatrixFree - indicates if the SNES uses matrix free finite difference matrix vector products to apply
11423565c898SBarry Smith                           the Jacobian.
11433565c898SBarry Smith 
11443565c898SBarry Smith    Collective on SNES
11453565c898SBarry Smith 
11463565c898SBarry Smith    Input Parameter:
11473565c898SBarry Smith .  snes - SNES context
11483565c898SBarry Smith 
11493565c898SBarry Smith    Output Parameters:
11503565c898SBarry Smith +  mf - use matrix-free for both the Amat and Pmat used by SNESSetJacobian(), both the Amat and Pmat set in SNESSetJacobian() will be ignored
11513565c898SBarry Smith -  mf_operator - use matrix-free only for the Amat used by SNESSetJacobian(), this means the user provided Pmat will continue to be used
11523565c898SBarry Smith 
11533565c898SBarry Smith    Options Database:
11543565c898SBarry Smith + -snes_mf - use matrix free for both the mat and pmat operator
11553565c898SBarry Smith - -snes_mf_operator - use matrix free only for the mat operator
11563565c898SBarry Smith 
11573565c898SBarry Smith    Level: intermediate
11583565c898SBarry Smith 
11593565c898SBarry Smith .keywords: SNES, nonlinear, get, iteration, number,
11603565c898SBarry Smith 
11613565c898SBarry Smith .seealso:   SNESSetUseMatrixFree(), MatCreateSNESMF()
11623565c898SBarry Smith @*/
11633565c898SBarry Smith PetscErrorCode  SNESGetUseMatrixFree(SNES snes,PetscBool *mf_operator,PetscBool *mf)
11643565c898SBarry Smith {
11653565c898SBarry Smith   PetscFunctionBegin;
11663565c898SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11673565c898SBarry Smith   if (mf)          *mf          = snes->mf;
11683565c898SBarry Smith   if (mf_operator) *mf_operator = snes->mf_operator;
11693565c898SBarry Smith   PetscFunctionReturn(0);
11703565c898SBarry Smith }
11713565c898SBarry Smith 
11723565c898SBarry Smith /*@
1173c8228a4eSBarry Smith    SNESGetIterationNumber - Gets the number of nonlinear iterations completed
1174c8228a4eSBarry Smith    at this time.
11759b94acceSBarry Smith 
1176c7afd0dbSLois Curfman McInnes    Not Collective
1177c7afd0dbSLois Curfman McInnes 
11789b94acceSBarry Smith    Input Parameter:
11799b94acceSBarry Smith .  snes - SNES context
11809b94acceSBarry Smith 
11819b94acceSBarry Smith    Output Parameter:
11829b94acceSBarry Smith .  iter - iteration number
11839b94acceSBarry Smith 
1184c8228a4eSBarry Smith    Notes:
1185c8228a4eSBarry Smith    For example, during the computation of iteration 2 this would return 1.
1186c8228a4eSBarry Smith 
1187c8228a4eSBarry Smith    This is useful for using lagged Jacobians (where one does not recompute the
118808405cd6SLois Curfman McInnes    Jacobian at each SNES iteration). For example, the code
118908405cd6SLois Curfman McInnes .vb
119008405cd6SLois Curfman McInnes       ierr = SNESGetIterationNumber(snes,&it);
119108405cd6SLois Curfman McInnes       if (!(it % 2)) {
119208405cd6SLois Curfman McInnes         [compute Jacobian here]
119308405cd6SLois Curfman McInnes       }
119408405cd6SLois Curfman McInnes .ve
1195c8228a4eSBarry Smith    can be used in your ComputeJacobian() function to cause the Jacobian to be
119608405cd6SLois Curfman McInnes    recomputed every second SNES iteration.
1197c8228a4eSBarry Smith 
1198c04deec6SBarry Smith    After the SNES solve is complete this will return the number of nonlinear iterations used.
1199c04deec6SBarry Smith 
120036851e7fSLois Curfman McInnes    Level: intermediate
120136851e7fSLois Curfman McInnes 
12022b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number,
12032b668275SBarry Smith 
120471dbe336SPeter Brune .seealso:   SNESGetLinearSolveIterations()
12059b94acceSBarry Smith @*/
12067087cfbeSBarry Smith PetscErrorCode  SNESGetIterationNumber(SNES snes,PetscInt *iter)
12079b94acceSBarry Smith {
12083a40ed3dSBarry Smith   PetscFunctionBegin;
12090700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
12104482741eSBarry Smith   PetscValidIntPointer(iter,2);
12119b94acceSBarry Smith   *iter = snes->iter;
12123a40ed3dSBarry Smith   PetscFunctionReturn(0);
12139b94acceSBarry Smith }
121474679c65SBarry Smith 
1215360c497dSPeter Brune /*@
1216360c497dSPeter Brune    SNESSetIterationNumber - Sets the current iteration number.
1217360c497dSPeter Brune 
1218360c497dSPeter Brune    Not Collective
1219360c497dSPeter Brune 
1220360c497dSPeter Brune    Input Parameter:
1221360c497dSPeter Brune .  snes - SNES context
1222360c497dSPeter Brune .  iter - iteration number
1223360c497dSPeter Brune 
1224360c497dSPeter Brune    Level: developer
1225360c497dSPeter Brune 
1226360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number,
1227360c497dSPeter Brune 
122871dbe336SPeter Brune .seealso:   SNESGetLinearSolveIterations()
1229360c497dSPeter Brune @*/
1230360c497dSPeter Brune PetscErrorCode  SNESSetIterationNumber(SNES snes,PetscInt iter)
1231360c497dSPeter Brune {
1232360c497dSPeter Brune   PetscErrorCode ierr;
1233360c497dSPeter Brune 
1234360c497dSPeter Brune   PetscFunctionBegin;
1235360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1236e04113cfSBarry Smith   ierr       = PetscObjectSAWsTakeAccess((PetscObject)snes);CHKERRQ(ierr);
1237360c497dSPeter Brune   snes->iter = iter;
1238e04113cfSBarry Smith   ierr       = PetscObjectSAWsGrantAccess((PetscObject)snes);CHKERRQ(ierr);
1239360c497dSPeter Brune   PetscFunctionReturn(0);
1240360c497dSPeter Brune }
1241360c497dSPeter Brune 
12429b94acceSBarry Smith /*@
1243b850b91aSLisandro Dalcin    SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
12449b94acceSBarry Smith    attempted by the nonlinear solver.
12459b94acceSBarry Smith 
1246c7afd0dbSLois Curfman McInnes    Not Collective
1247c7afd0dbSLois Curfman McInnes 
12489b94acceSBarry Smith    Input Parameter:
12499b94acceSBarry Smith .  snes - SNES context
12509b94acceSBarry Smith 
12519b94acceSBarry Smith    Output Parameter:
12529b94acceSBarry Smith .  nfails - number of unsuccessful steps attempted
12539b94acceSBarry Smith 
1254c96a6f78SLois Curfman McInnes    Notes:
1255c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
1256c96a6f78SLois Curfman McInnes 
125736851e7fSLois Curfman McInnes    Level: intermediate
125836851e7fSLois Curfman McInnes 
12599b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
126058ebbce7SBarry Smith 
1261e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
126258ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures()
12639b94acceSBarry Smith @*/
12647087cfbeSBarry Smith PetscErrorCode  SNESGetNonlinearStepFailures(SNES snes,PetscInt *nfails)
12659b94acceSBarry Smith {
12663a40ed3dSBarry Smith   PetscFunctionBegin;
12670700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
12684482741eSBarry Smith   PetscValidIntPointer(nfails,2);
126950ffb88aSMatthew Knepley   *nfails = snes->numFailures;
127050ffb88aSMatthew Knepley   PetscFunctionReturn(0);
127150ffb88aSMatthew Knepley }
127250ffb88aSMatthew Knepley 
127350ffb88aSMatthew Knepley /*@
1274b850b91aSLisandro Dalcin    SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
127550ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
127650ffb88aSMatthew Knepley 
127750ffb88aSMatthew Knepley    Not Collective
127850ffb88aSMatthew Knepley 
127950ffb88aSMatthew Knepley    Input Parameters:
128050ffb88aSMatthew Knepley +  snes     - SNES context
128150ffb88aSMatthew Knepley -  maxFails - maximum of unsuccessful steps
128250ffb88aSMatthew Knepley 
128350ffb88aSMatthew Knepley    Level: intermediate
128450ffb88aSMatthew Knepley 
128550ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
128658ebbce7SBarry Smith 
1287e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
128858ebbce7SBarry Smith           SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
128950ffb88aSMatthew Knepley @*/
12907087cfbeSBarry Smith PetscErrorCode  SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
129150ffb88aSMatthew Knepley {
129250ffb88aSMatthew Knepley   PetscFunctionBegin;
12930700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
129450ffb88aSMatthew Knepley   snes->maxFailures = maxFails;
129550ffb88aSMatthew Knepley   PetscFunctionReturn(0);
129650ffb88aSMatthew Knepley }
129750ffb88aSMatthew Knepley 
129850ffb88aSMatthew Knepley /*@
1299b850b91aSLisandro Dalcin    SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
130050ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
130150ffb88aSMatthew Knepley 
130250ffb88aSMatthew Knepley    Not Collective
130350ffb88aSMatthew Knepley 
130450ffb88aSMatthew Knepley    Input Parameter:
130550ffb88aSMatthew Knepley .  snes     - SNES context
130650ffb88aSMatthew Knepley 
130750ffb88aSMatthew Knepley    Output Parameter:
130850ffb88aSMatthew Knepley .  maxFails - maximum of unsuccessful steps
130950ffb88aSMatthew Knepley 
131050ffb88aSMatthew Knepley    Level: intermediate
131150ffb88aSMatthew Knepley 
131250ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
131358ebbce7SBarry Smith 
1314e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
131558ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
131658ebbce7SBarry Smith 
131750ffb88aSMatthew Knepley @*/
13187087cfbeSBarry Smith PetscErrorCode  SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
131950ffb88aSMatthew Knepley {
132050ffb88aSMatthew Knepley   PetscFunctionBegin;
13210700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
13224482741eSBarry Smith   PetscValidIntPointer(maxFails,2);
132350ffb88aSMatthew Knepley   *maxFails = snes->maxFailures;
13243a40ed3dSBarry Smith   PetscFunctionReturn(0);
13259b94acceSBarry Smith }
1326a847f771SSatish Balay 
13272541af92SBarry Smith /*@
13282541af92SBarry Smith    SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations
13292541af92SBarry Smith      done by SNES.
13302541af92SBarry Smith 
13312541af92SBarry Smith    Not Collective
13322541af92SBarry Smith 
13332541af92SBarry Smith    Input Parameter:
13342541af92SBarry Smith .  snes     - SNES context
13352541af92SBarry Smith 
13362541af92SBarry Smith    Output Parameter:
13372541af92SBarry Smith .  nfuncs - number of evaluations
13382541af92SBarry Smith 
13392541af92SBarry Smith    Level: intermediate
13402541af92SBarry Smith 
134195452b02SPatrick Sanan    Notes:
134295452b02SPatrick Sanan     Reset every time SNESSolve is called unless SNESSetCountersReset() is used.
1343971e163fSPeter Brune 
13442541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
134558ebbce7SBarry Smith 
1346971e163fSPeter Brune .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), SNESSetCountersReset()
13472541af92SBarry Smith @*/
13487087cfbeSBarry Smith PetscErrorCode  SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs)
13492541af92SBarry Smith {
13502541af92SBarry Smith   PetscFunctionBegin;
13510700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
13522541af92SBarry Smith   PetscValidIntPointer(nfuncs,2);
13532541af92SBarry Smith   *nfuncs = snes->nfuncs;
13542541af92SBarry Smith   PetscFunctionReturn(0);
13552541af92SBarry Smith }
13562541af92SBarry Smith 
13573d4c4710SBarry Smith /*@
13583d4c4710SBarry Smith    SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
13593d4c4710SBarry Smith    linear solvers.
13603d4c4710SBarry Smith 
13613d4c4710SBarry Smith    Not Collective
13623d4c4710SBarry Smith 
13633d4c4710SBarry Smith    Input Parameter:
13643d4c4710SBarry Smith .  snes - SNES context
13653d4c4710SBarry Smith 
13663d4c4710SBarry Smith    Output Parameter:
13673d4c4710SBarry Smith .  nfails - number of failed solves
13683d4c4710SBarry Smith 
13699d85da0cSMatthew G. Knepley    Level: intermediate
13709d85da0cSMatthew G. Knepley 
13719d85da0cSMatthew G. Knepley    Options Database Keys:
13729d85da0cSMatthew G. Knepley . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated
13739d85da0cSMatthew G. Knepley 
13743d4c4710SBarry Smith    Notes:
13753d4c4710SBarry Smith    This counter is reset to zero for each successive call to SNESSolve().
13763d4c4710SBarry Smith 
13773d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
137858ebbce7SBarry Smith 
1379e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures()
13803d4c4710SBarry Smith @*/
13817087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveFailures(SNES snes,PetscInt *nfails)
13823d4c4710SBarry Smith {
13833d4c4710SBarry Smith   PetscFunctionBegin;
13840700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
13853d4c4710SBarry Smith   PetscValidIntPointer(nfails,2);
13863d4c4710SBarry Smith   *nfails = snes->numLinearSolveFailures;
13873d4c4710SBarry Smith   PetscFunctionReturn(0);
13883d4c4710SBarry Smith }
13893d4c4710SBarry Smith 
13903d4c4710SBarry Smith /*@
13913d4c4710SBarry Smith    SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
13923d4c4710SBarry Smith    allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE
13933d4c4710SBarry Smith 
13943f9fe445SBarry Smith    Logically Collective on SNES
13953d4c4710SBarry Smith 
13963d4c4710SBarry Smith    Input Parameters:
13973d4c4710SBarry Smith +  snes     - SNES context
13983d4c4710SBarry Smith -  maxFails - maximum allowed linear solve failures
13993d4c4710SBarry Smith 
14003d4c4710SBarry Smith    Level: intermediate
14013d4c4710SBarry Smith 
14029d85da0cSMatthew G. Knepley    Options Database Keys:
14039d85da0cSMatthew G. Knepley . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated
14049d85da0cSMatthew G. Knepley 
140595452b02SPatrick Sanan    Notes:
140695452b02SPatrick Sanan     By default this is 0; that is SNES returns on the first failed linear solve
14073d4c4710SBarry Smith 
14083d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
14093d4c4710SBarry Smith 
141058ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations()
14113d4c4710SBarry Smith @*/
14127087cfbeSBarry Smith PetscErrorCode  SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
14133d4c4710SBarry Smith {
14143d4c4710SBarry Smith   PetscFunctionBegin;
14150700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1416c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxFails,2);
14173d4c4710SBarry Smith   snes->maxLinearSolveFailures = maxFails;
14183d4c4710SBarry Smith   PetscFunctionReturn(0);
14193d4c4710SBarry Smith }
14203d4c4710SBarry Smith 
14213d4c4710SBarry Smith /*@
14223d4c4710SBarry Smith    SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
14233d4c4710SBarry Smith      are allowed before SNES terminates
14243d4c4710SBarry Smith 
14253d4c4710SBarry Smith    Not Collective
14263d4c4710SBarry Smith 
14273d4c4710SBarry Smith    Input Parameter:
14283d4c4710SBarry Smith .  snes     - SNES context
14293d4c4710SBarry Smith 
14303d4c4710SBarry Smith    Output Parameter:
14313d4c4710SBarry Smith .  maxFails - maximum of unsuccessful solves allowed
14323d4c4710SBarry Smith 
14333d4c4710SBarry Smith    Level: intermediate
14343d4c4710SBarry Smith 
143595452b02SPatrick Sanan    Notes:
143695452b02SPatrick Sanan     By default this is 1; that is SNES returns on the first failed linear solve
14373d4c4710SBarry Smith 
14383d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
14393d4c4710SBarry Smith 
1440e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(),
14413d4c4710SBarry Smith @*/
14427087cfbeSBarry Smith PetscErrorCode  SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
14433d4c4710SBarry Smith {
14443d4c4710SBarry Smith   PetscFunctionBegin;
14450700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
14463d4c4710SBarry Smith   PetscValidIntPointer(maxFails,2);
14473d4c4710SBarry Smith   *maxFails = snes->maxLinearSolveFailures;
14483d4c4710SBarry Smith   PetscFunctionReturn(0);
14493d4c4710SBarry Smith }
14503d4c4710SBarry Smith 
1451c96a6f78SLois Curfman McInnes /*@
1452b850b91aSLisandro Dalcin    SNESGetLinearSolveIterations - Gets the total number of linear iterations
1453c96a6f78SLois Curfman McInnes    used by the nonlinear solver.
1454c96a6f78SLois Curfman McInnes 
1455c7afd0dbSLois Curfman McInnes    Not Collective
1456c7afd0dbSLois Curfman McInnes 
1457c96a6f78SLois Curfman McInnes    Input Parameter:
1458c96a6f78SLois Curfman McInnes .  snes - SNES context
1459c96a6f78SLois Curfman McInnes 
1460c96a6f78SLois Curfman McInnes    Output Parameter:
1461c96a6f78SLois Curfman McInnes .  lits - number of linear iterations
1462c96a6f78SLois Curfman McInnes 
1463c96a6f78SLois Curfman McInnes    Notes:
1464971e163fSPeter Brune    This counter is reset to zero for each successive call to SNESSolve() unless SNESSetCountersReset() is used.
1465c96a6f78SLois Curfman McInnes 
1466010be392SBarry Smith    If the linear solver fails inside the SNESSolve() the iterations for that call to the linear solver are not included. If you wish to count them
1467010be392SBarry Smith    then call KSPGetIterationNumber() after the failed solve.
1468010be392SBarry Smith 
146936851e7fSLois Curfman McInnes    Level: intermediate
147036851e7fSLois Curfman McInnes 
1471c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations
14722b668275SBarry Smith 
147371dbe336SPeter Brune .seealso:  SNESGetIterationNumber(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESSetCountersReset()
1474c96a6f78SLois Curfman McInnes @*/
14757087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveIterations(SNES snes,PetscInt *lits)
1476c96a6f78SLois Curfman McInnes {
14773a40ed3dSBarry Smith   PetscFunctionBegin;
14780700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
14794482741eSBarry Smith   PetscValidIntPointer(lits,2);
1480c96a6f78SLois Curfman McInnes   *lits = snes->linear_its;
14813a40ed3dSBarry Smith   PetscFunctionReturn(0);
1482c96a6f78SLois Curfman McInnes }
1483c96a6f78SLois Curfman McInnes 
1484971e163fSPeter Brune /*@
1485971e163fSPeter Brune    SNESSetCountersReset - Sets whether or not the counters for linear iterations and function evaluations
1486971e163fSPeter Brune    are reset every time SNESSolve() is called.
1487971e163fSPeter Brune 
1488971e163fSPeter Brune    Logically Collective on SNES
1489971e163fSPeter Brune 
1490971e163fSPeter Brune    Input Parameter:
1491971e163fSPeter Brune +  snes - SNES context
1492971e163fSPeter Brune -  reset - whether to reset the counters or not
1493971e163fSPeter Brune 
1494971e163fSPeter Brune    Notes:
1495fa19ca70SBarry Smith    This defaults to PETSC_TRUE
1496971e163fSPeter Brune 
1497971e163fSPeter Brune    Level: developer
1498971e163fSPeter Brune 
1499971e163fSPeter Brune .keywords: SNES, nonlinear, set, reset, number, linear, iterations
1500971e163fSPeter Brune 
1501734794cfSBarry Smith .seealso:  SNESGetNumberFunctionEvals(), SNESGetLinearSolveIterations(), SNESGetNPC()
1502971e163fSPeter Brune @*/
1503971e163fSPeter Brune PetscErrorCode  SNESSetCountersReset(SNES snes,PetscBool reset)
1504971e163fSPeter Brune {
1505971e163fSPeter Brune   PetscFunctionBegin;
1506971e163fSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1507971e163fSPeter Brune   PetscValidLogicalCollectiveBool(snes,reset,2);
1508971e163fSPeter Brune   snes->counters_reset = reset;
1509971e163fSPeter Brune   PetscFunctionReturn(0);
1510971e163fSPeter Brune }
1511971e163fSPeter Brune 
151282bf6240SBarry Smith 
15132999313aSBarry Smith /*@
15142999313aSBarry Smith    SNESSetKSP - Sets a KSP context for the SNES object to use
15152999313aSBarry Smith 
15162999313aSBarry Smith    Not Collective, but the SNES and KSP objects must live on the same MPI_Comm
15172999313aSBarry Smith 
15182999313aSBarry Smith    Input Parameters:
15192999313aSBarry Smith +  snes - the SNES context
15202999313aSBarry Smith -  ksp - the KSP context
15212999313aSBarry Smith 
15222999313aSBarry Smith    Notes:
15232999313aSBarry Smith    The SNES object already has its KSP object, you can obtain with SNESGetKSP()
15242999313aSBarry Smith    so this routine is rarely needed.
15252999313aSBarry Smith 
15262999313aSBarry Smith    The KSP object that is already in the SNES object has its reference count
15272999313aSBarry Smith    decreased by one.
15282999313aSBarry Smith 
15292999313aSBarry Smith    Level: developer
15302999313aSBarry Smith 
15312999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
15322999313aSBarry Smith 
15332999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
15342999313aSBarry Smith @*/
15357087cfbeSBarry Smith PetscErrorCode  SNESSetKSP(SNES snes,KSP ksp)
15362999313aSBarry Smith {
15372999313aSBarry Smith   PetscErrorCode ierr;
15382999313aSBarry Smith 
15392999313aSBarry Smith   PetscFunctionBegin;
15400700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
15410700a824SBarry Smith   PetscValidHeaderSpecific(ksp,KSP_CLASSID,2);
15422999313aSBarry Smith   PetscCheckSameComm(snes,1,ksp,2);
15437dcf0eaaSdalcinl   ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr);
1544906ed7ccSBarry Smith   if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);}
15452999313aSBarry Smith   snes->ksp = ksp;
15462999313aSBarry Smith   PetscFunctionReturn(0);
15472999313aSBarry Smith }
15482999313aSBarry Smith 
15499b94acceSBarry Smith /* -----------------------------------------------------------*/
155052baeb72SSatish Balay /*@
15519b94acceSBarry Smith    SNESCreate - Creates a nonlinear solver context.
15529b94acceSBarry Smith 
1553c7afd0dbSLois Curfman McInnes    Collective on MPI_Comm
1554c7afd0dbSLois Curfman McInnes 
1555c7afd0dbSLois Curfman McInnes    Input Parameters:
1556906ed7ccSBarry Smith .  comm - MPI communicator
15579b94acceSBarry Smith 
15589b94acceSBarry Smith    Output Parameter:
15599b94acceSBarry Smith .  outsnes - the new SNES context
15609b94acceSBarry Smith 
1561c7afd0dbSLois Curfman McInnes    Options Database Keys:
1562c7afd0dbSLois Curfman McInnes +   -snes_mf - Activates default matrix-free Jacobian-vector products,
1563c7afd0dbSLois Curfman McInnes                and no preconditioning matrix
1564c7afd0dbSLois Curfman McInnes .   -snes_mf_operator - Activates default matrix-free Jacobian-vector
1565c7afd0dbSLois Curfman McInnes                products, and a user-provided preconditioning matrix
1566c7afd0dbSLois Curfman McInnes                as set by SNESSetJacobian()
1567c7afd0dbSLois Curfman McInnes -   -snes_fd - Uses (slow!) finite differences to compute Jacobian
1568c1f60f51SBarry Smith 
156936851e7fSLois Curfman McInnes    Level: beginner
157036851e7fSLois Curfman McInnes 
157195452b02SPatrick Sanan    Developer Notes:
157295452b02SPatrick Sanan     SNES always creates a KSP object even though many SNES methods do not use it. This is
1573efd4aadfSBarry Smith                     unfortunate and should be fixed at some point. The flag snes->usesksp indicates if the
1574efd4aadfSBarry Smith                     particular method does use KSP and regulates if the information about the KSP is printed
1575efd4aadfSBarry Smith                     in SNESView(). TSSetFromOptions() does call SNESSetFromOptions() which can lead to users being confused
1576efd4aadfSBarry Smith                     by help messages about meaningless SNES options.
1577efd4aadfSBarry Smith 
1578efd4aadfSBarry Smith                     SNES always creates the snes->kspconvctx even though it is used by only one type. This should
1579efd4aadfSBarry Smith                     be fixed.
1580efd4aadfSBarry Smith 
15819b94acceSBarry Smith .keywords: SNES, nonlinear, create, context
15829b94acceSBarry Smith 
1583a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner()
1584a8054027SBarry Smith 
15859b94acceSBarry Smith @*/
15867087cfbeSBarry Smith PetscErrorCode  SNESCreate(MPI_Comm comm,SNES *outsnes)
15879b94acceSBarry Smith {
1588dfbe8321SBarry Smith   PetscErrorCode ierr;
15899b94acceSBarry Smith   SNES           snes;
1590fa9f3622SBarry Smith   SNESKSPEW      *kctx;
159137fcc0dbSBarry Smith 
15923a40ed3dSBarry Smith   PetscFunctionBegin;
1593ed1caa07SMatthew Knepley   PetscValidPointer(outsnes,2);
15940298fd71SBarry Smith   *outsnes = NULL;
1595607a6623SBarry Smith   ierr = SNESInitializePackage();CHKERRQ(ierr);
15968ba1e511SMatthew Knepley 
159773107ff1SLisandro Dalcin   ierr = PetscHeaderCreate(snes,SNES_CLASSID,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr);
15987adad957SLisandro Dalcin 
15998d359177SBarry Smith   snes->ops->converged    = SNESConvergedDefault;
16002c155ee1SBarry Smith   snes->usesksp           = PETSC_TRUE;
160188976e71SPeter Brune   snes->tolerancesset     = PETSC_FALSE;
16029b94acceSBarry Smith   snes->max_its           = 50;
16039750a799SBarry Smith   snes->max_funcs         = 10000;
16049b94acceSBarry Smith   snes->norm              = 0.0;
1605365a6726SPeter Brune   snes->normschedule      = SNES_NORM_ALWAYS;
16066c67d002SPeter Brune   snes->functype          = SNES_FUNCTION_DEFAULT;
16073a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE)
16083a2046daSBarry Smith   snes->rtol              = 1.e-5;
16093a2046daSBarry Smith #else
1610b4874afaSBarry Smith   snes->rtol              = 1.e-8;
16113a2046daSBarry Smith #endif
1612b4874afaSBarry Smith   snes->ttol              = 0.0;
16133a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE)
16143a2046daSBarry Smith   snes->abstol            = 1.e-25;
16153a2046daSBarry Smith #else
161670441072SBarry Smith   snes->abstol            = 1.e-50;
16173a2046daSBarry Smith #endif
16187cd0ae37SLisandro Dalcin #if defined(PETSC_USE_REAL_SINGLE)
16197cd0ae37SLisandro Dalcin   snes->stol              = 1.e-5;
16207cd0ae37SLisandro Dalcin #else
1621c60f73f4SPeter Brune   snes->stol              = 1.e-8;
16227cd0ae37SLisandro Dalcin #endif
16233a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE)
16243a2046daSBarry Smith   snes->deltatol          = 1.e-6;
16253a2046daSBarry Smith #else
16264b27c08aSLois Curfman McInnes   snes->deltatol          = 1.e-12;
16273a2046daSBarry Smith #endif
1628e37c518bSBarry Smith   snes->divtol            = 1.e4;
1629e37c518bSBarry Smith   snes->rnorm0            = 0;
16309b94acceSBarry Smith   snes->nfuncs            = 0;
163150ffb88aSMatthew Knepley   snes->numFailures       = 0;
163250ffb88aSMatthew Knepley   snes->maxFailures       = 1;
16337a00f4a9SLois Curfman McInnes   snes->linear_its        = 0;
1634e35cf81dSBarry Smith   snes->lagjacobian       = 1;
163537ec4e1aSPeter Brune   snes->jac_iter          = 0;
163637ec4e1aSPeter Brune   snes->lagjac_persist    = PETSC_FALSE;
1637a8054027SBarry Smith   snes->lagpreconditioner = 1;
163837ec4e1aSPeter Brune   snes->pre_iter          = 0;
163937ec4e1aSPeter Brune   snes->lagpre_persist    = PETSC_FALSE;
1640639f9d9dSBarry Smith   snes->numbermonitors    = 0;
16419b94acceSBarry Smith   snes->data              = 0;
16424dc4c822SBarry Smith   snes->setupcalled       = PETSC_FALSE;
1643186905e3SBarry Smith   snes->ksp_ewconv        = PETSC_FALSE;
16446f24a144SLois Curfman McInnes   snes->nwork             = 0;
164558c9b817SLisandro Dalcin   snes->work              = 0;
164658c9b817SLisandro Dalcin   snes->nvwork            = 0;
164758c9b817SLisandro Dalcin   snes->vwork             = 0;
1648758f92a0SBarry Smith   snes->conv_hist_len     = 0;
1649758f92a0SBarry Smith   snes->conv_hist_max     = 0;
16500298fd71SBarry Smith   snes->conv_hist         = NULL;
16510298fd71SBarry Smith   snes->conv_hist_its     = NULL;
1652758f92a0SBarry Smith   snes->conv_hist_reset   = PETSC_TRUE;
1653971e163fSPeter Brune   snes->counters_reset    = PETSC_TRUE;
1654e4ed7901SPeter Brune   snes->vec_func_init_set = PETSC_FALSE;
1655184914b5SBarry Smith   snes->reason            = SNES_CONVERGED_ITERATING;
1656efd4aadfSBarry Smith   snes->npcside           = PC_RIGHT;
1657b3cd9a81SMatthew G. Knepley   snes->setfromoptionscalled = 0;
1658c40d0f55SPeter Brune 
1659d8f46077SPeter Brune   snes->mf          = PETSC_FALSE;
1660d8f46077SPeter Brune   snes->mf_operator = PETSC_FALSE;
1661d8f46077SPeter Brune   snes->mf_version  = 1;
1662d8f46077SPeter Brune 
16633d4c4710SBarry Smith   snes->numLinearSolveFailures = 0;
16643d4c4710SBarry Smith   snes->maxLinearSolveFailures = 1;
16653d4c4710SBarry Smith 
1666349187a7SBarry Smith   snes->vizerotolerance = 1.e-8;
1667349187a7SBarry Smith 
16684fc747eaSLawrence Mitchell   /* Set this to true if the implementation of SNESSolve_XXX does compute the residual at the final solution. */
16694fc747eaSLawrence Mitchell   snes->alwayscomputesfinalresidual = PETSC_FALSE;
16704fc747eaSLawrence Mitchell 
16719b94acceSBarry Smith   /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
1672b00a9115SJed Brown   ierr = PetscNewLog(snes,&kctx);CHKERRQ(ierr);
1673f5af7f23SKarl Rupp 
16749b94acceSBarry Smith   snes->kspconvctx  = (void*)kctx;
16759b94acceSBarry Smith   kctx->version     = 2;
16769b94acceSBarry Smith   kctx->rtol_0      = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
16779b94acceSBarry Smith                              this was too large for some test cases */
167875567043SBarry Smith   kctx->rtol_last   = 0.0;
16799b94acceSBarry Smith   kctx->rtol_max    = .9;
16809b94acceSBarry Smith   kctx->gamma       = 1.0;
168162d1f40fSBarry Smith   kctx->alpha       = .5*(1.0 + PetscSqrtReal(5.0));
168271f87433Sdalcinl   kctx->alpha2      = kctx->alpha;
16839b94acceSBarry Smith   kctx->threshold   = .1;
168475567043SBarry Smith   kctx->lresid_last = 0.0;
168575567043SBarry Smith   kctx->norm_last   = 0.0;
16869b94acceSBarry Smith 
16879b94acceSBarry Smith   *outsnes = snes;
16883a40ed3dSBarry Smith   PetscFunctionReturn(0);
16899b94acceSBarry Smith }
16909b94acceSBarry Smith 
169188f0584fSBarry Smith /*MC
1692411c0326SBarry Smith     SNESFunction - Functional form used to convey the nonlinear function to be solved by SNES
169388f0584fSBarry Smith 
169488f0584fSBarry Smith      Synopsis:
1695411c0326SBarry Smith      #include "petscsnes.h"
1696411c0326SBarry Smith      PetscErrorCode SNESFunction(SNES snes,Vec x,Vec f,void *ctx);
169788f0584fSBarry Smith 
169888f0584fSBarry Smith      Input Parameters:
169988f0584fSBarry Smith +     snes - the SNES context
170088f0584fSBarry Smith .     x    - state at which to evaluate residual
170188f0584fSBarry Smith -     ctx     - optional user-defined function context, passed in with SNESSetFunction()
170288f0584fSBarry Smith 
170388f0584fSBarry Smith      Output Parameter:
170488f0584fSBarry Smith .     f  - vector to put residual (function value)
170588f0584fSBarry Smith 
1706878cb397SSatish Balay    Level: intermediate
1707878cb397SSatish Balay 
170888f0584fSBarry Smith .seealso:   SNESSetFunction(), SNESGetFunction()
170988f0584fSBarry Smith M*/
171088f0584fSBarry Smith 
17119b94acceSBarry Smith /*@C
17129b94acceSBarry Smith    SNESSetFunction - Sets the function evaluation routine and function
17139b94acceSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
17149b94acceSBarry Smith    equations.
17159b94acceSBarry Smith 
17163f9fe445SBarry Smith    Logically Collective on SNES
1717fee21e36SBarry Smith 
1718c7afd0dbSLois Curfman McInnes    Input Parameters:
1719c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1720c7afd0dbSLois Curfman McInnes .  r - vector to store function value
1721f8b49ee9SBarry Smith .  f - function evaluation routine; see SNESFunction for calling sequence details
1722c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
17230298fd71SBarry Smith          function evaluation routine (may be NULL)
17249b94acceSBarry Smith 
17259b94acceSBarry Smith    Notes:
17269b94acceSBarry Smith    The Newton-like methods typically solve linear systems of the form
17279b94acceSBarry Smith $      f'(x) x = -f(x),
1728c7afd0dbSLois Curfman McInnes    where f'(x) denotes the Jacobian matrix and f(x) is the function.
17299b94acceSBarry Smith 
173036851e7fSLois Curfman McInnes    Level: beginner
173136851e7fSLois Curfman McInnes 
17329b94acceSBarry Smith .keywords: SNES, nonlinear, set, function
17339b94acceSBarry Smith 
1734bf388a1fSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard(), SNESFunction
17359b94acceSBarry Smith @*/
1736f8b49ee9SBarry Smith PetscErrorCode  SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx)
17379b94acceSBarry Smith {
173885385478SLisandro Dalcin   PetscErrorCode ierr;
17396cab3a1bSJed Brown   DM             dm;
17406cab3a1bSJed Brown 
17413a40ed3dSBarry Smith   PetscFunctionBegin;
17420700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1743d2a683ecSLisandro Dalcin   if (r) {
1744d2a683ecSLisandro Dalcin     PetscValidHeaderSpecific(r,VEC_CLASSID,2);
1745d2a683ecSLisandro Dalcin     PetscCheckSameComm(snes,1,r,2);
174685385478SLisandro Dalcin     ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr);
17476bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
1748f5af7f23SKarl Rupp 
174985385478SLisandro Dalcin     snes->vec_func = r;
1750d2a683ecSLisandro Dalcin   }
17516cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
1752f8b49ee9SBarry Smith   ierr = DMSNESSetFunction(dm,f,ctx);CHKERRQ(ierr);
17533a40ed3dSBarry Smith   PetscFunctionReturn(0);
17549b94acceSBarry Smith }
17559b94acceSBarry Smith 
1756646217ecSPeter Brune 
1757e4ed7901SPeter Brune /*@C
1758e4ed7901SPeter Brune    SNESSetInitialFunction - Sets the function vector to be used as the
1759e4ed7901SPeter Brune    function norm at the initialization of the method.  In some
1760e4ed7901SPeter Brune    instances, the user has precomputed the function before calling
1761e4ed7901SPeter Brune    SNESSolve.  This function allows one to avoid a redundant call
1762e4ed7901SPeter Brune    to SNESComputeFunction in that case.
1763e4ed7901SPeter Brune 
1764e4ed7901SPeter Brune    Logically Collective on SNES
1765e4ed7901SPeter Brune 
1766e4ed7901SPeter Brune    Input Parameters:
1767e4ed7901SPeter Brune +  snes - the SNES context
1768e4ed7901SPeter Brune -  f - vector to store function value
1769e4ed7901SPeter Brune 
1770e4ed7901SPeter Brune    Notes:
1771e4ed7901SPeter Brune    This should not be modified during the solution procedure.
1772e4ed7901SPeter Brune 
1773e4ed7901SPeter Brune    This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning.
1774e4ed7901SPeter Brune 
1775e4ed7901SPeter Brune    Level: developer
1776e4ed7901SPeter Brune 
1777e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function
1778e4ed7901SPeter Brune 
1779e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunctionNorm()
1780e4ed7901SPeter Brune @*/
1781e4ed7901SPeter Brune PetscErrorCode  SNESSetInitialFunction(SNES snes, Vec f)
1782e4ed7901SPeter Brune {
1783e4ed7901SPeter Brune   PetscErrorCode ierr;
1784e4ed7901SPeter Brune   Vec            vec_func;
1785e4ed7901SPeter Brune 
1786e4ed7901SPeter Brune   PetscFunctionBegin;
1787e4ed7901SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1788e4ed7901SPeter Brune   PetscValidHeaderSpecific(f,VEC_CLASSID,2);
1789e4ed7901SPeter Brune   PetscCheckSameComm(snes,1,f,2);
1790efd4aadfSBarry Smith   if (snes->npcside== PC_LEFT && snes->functype == SNES_FUNCTION_PRECONDITIONED) {
1791902f982fSPeter Brune     snes->vec_func_init_set = PETSC_FALSE;
1792902f982fSPeter Brune     PetscFunctionReturn(0);
1793902f982fSPeter Brune   }
17940298fd71SBarry Smith   ierr = SNESGetFunction(snes,&vec_func,NULL,NULL);CHKERRQ(ierr);
1795e4ed7901SPeter Brune   ierr = VecCopy(f, vec_func);CHKERRQ(ierr);
1796f5af7f23SKarl Rupp 
1797217b9c2eSPeter Brune   snes->vec_func_init_set = PETSC_TRUE;
1798e4ed7901SPeter Brune   PetscFunctionReturn(0);
1799e4ed7901SPeter Brune }
1800e4ed7901SPeter Brune 
1801534ebe21SPeter Brune /*@
1802365a6726SPeter Brune    SNESSetNormSchedule - Sets the SNESNormSchedule used in covergence and monitoring
1803534ebe21SPeter Brune    of the SNES method.
1804534ebe21SPeter Brune 
1805534ebe21SPeter Brune    Logically Collective on SNES
1806534ebe21SPeter Brune 
1807534ebe21SPeter Brune    Input Parameters:
1808534ebe21SPeter Brune +  snes - the SNES context
1809365a6726SPeter Brune -  normschedule - the frequency of norm computation
1810534ebe21SPeter Brune 
1811517f1916SMatthew G. Knepley    Options Database Key:
1812517f1916SMatthew G. Knepley .  -snes_norm_schedule <none, always, initialonly, finalonly, initalfinalonly>
1813517f1916SMatthew G. Knepley 
1814534ebe21SPeter Brune    Notes:
1815365a6726SPeter Brune    Only certain SNES methods support certain SNESNormSchedules.  Most require evaluation
1816534ebe21SPeter Brune    of the nonlinear function and the taking of its norm at every iteration to
1817534ebe21SPeter Brune    even ensure convergence at all.  However, methods such as custom Gauss-Seidel methods
1818be95d8f1SBarry Smith    (SNESNGS) and the like do not require the norm of the function to be computed, and therfore
1819534ebe21SPeter Brune    may either be monitored for convergence or not.  As these are often used as nonlinear
1820534ebe21SPeter Brune    preconditioners, monitoring the norm of their error is not a useful enterprise within
1821534ebe21SPeter Brune    their solution.
1822534ebe21SPeter Brune 
1823534ebe21SPeter Brune    Level: developer
1824534ebe21SPeter Brune 
1825534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type
1826534ebe21SPeter Brune 
1827365a6726SPeter Brune .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
1828534ebe21SPeter Brune @*/
1829365a6726SPeter Brune PetscErrorCode  SNESSetNormSchedule(SNES snes, SNESNormSchedule normschedule)
1830534ebe21SPeter Brune {
1831534ebe21SPeter Brune   PetscFunctionBegin;
1832534ebe21SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1833365a6726SPeter Brune   snes->normschedule = normschedule;
1834534ebe21SPeter Brune   PetscFunctionReturn(0);
1835534ebe21SPeter Brune }
1836534ebe21SPeter Brune 
1837534ebe21SPeter Brune 
1838534ebe21SPeter Brune /*@
1839365a6726SPeter Brune    SNESGetNormSchedule - Gets the SNESNormSchedule used in covergence and monitoring
1840534ebe21SPeter Brune    of the SNES method.
1841534ebe21SPeter Brune 
1842534ebe21SPeter Brune    Logically Collective on SNES
1843534ebe21SPeter Brune 
1844534ebe21SPeter Brune    Input Parameters:
1845534ebe21SPeter Brune +  snes - the SNES context
1846365a6726SPeter Brune -  normschedule - the type of the norm used
1847534ebe21SPeter Brune 
1848534ebe21SPeter Brune    Level: advanced
1849534ebe21SPeter Brune 
1850534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type
1851534ebe21SPeter Brune 
1852365a6726SPeter Brune .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
1853534ebe21SPeter Brune @*/
1854365a6726SPeter Brune PetscErrorCode  SNESGetNormSchedule(SNES snes, SNESNormSchedule *normschedule)
1855534ebe21SPeter Brune {
1856534ebe21SPeter Brune   PetscFunctionBegin;
1857534ebe21SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1858365a6726SPeter Brune   *normschedule = snes->normschedule;
1859534ebe21SPeter Brune   PetscFunctionReturn(0);
1860534ebe21SPeter Brune }
1861534ebe21SPeter Brune 
186247073ea2SPeter Brune 
1863c5ce4427SMatthew G. Knepley /*@
1864c5ce4427SMatthew G. Knepley   SNESSetFunctionNorm - Sets the last computed residual norm.
1865c5ce4427SMatthew G. Knepley 
1866c5ce4427SMatthew G. Knepley   Logically Collective on SNES
1867c5ce4427SMatthew G. Knepley 
1868c5ce4427SMatthew G. Knepley   Input Parameters:
1869c5ce4427SMatthew G. Knepley + snes - the SNES context
1870c5ce4427SMatthew G. Knepley 
1871c5ce4427SMatthew G. Knepley - normschedule - the frequency of norm computation
1872c5ce4427SMatthew G. Knepley 
1873c5ce4427SMatthew G. Knepley   Level: developer
1874c5ce4427SMatthew G. Knepley 
1875c5ce4427SMatthew G. Knepley .keywords: SNES, nonlinear, set, function, norm, type
1876c5ce4427SMatthew G. Knepley .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
1877c5ce4427SMatthew G. Knepley @*/
1878c5ce4427SMatthew G. Knepley PetscErrorCode SNESSetFunctionNorm(SNES snes, PetscReal norm)
1879c5ce4427SMatthew G. Knepley {
1880c5ce4427SMatthew G. Knepley   PetscFunctionBegin;
1881c5ce4427SMatthew G. Knepley   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1882c5ce4427SMatthew G. Knepley   snes->norm = norm;
1883c5ce4427SMatthew G. Knepley   PetscFunctionReturn(0);
1884c5ce4427SMatthew G. Knepley }
1885c5ce4427SMatthew G. Knepley 
1886c5ce4427SMatthew G. Knepley /*@
1887c5ce4427SMatthew G. Knepley   SNESGetFunctionNorm - Gets the last computed norm of the residual
1888c5ce4427SMatthew G. Knepley 
1889c5ce4427SMatthew G. Knepley   Not Collective
1890c5ce4427SMatthew G. Knepley 
1891c5ce4427SMatthew G. Knepley   Input Parameter:
1892c5ce4427SMatthew G. Knepley . snes - the SNES context
1893c5ce4427SMatthew G. Knepley 
1894c5ce4427SMatthew G. Knepley   Output Parameter:
1895c5ce4427SMatthew G. Knepley . norm - the last computed residual norm
1896c5ce4427SMatthew G. Knepley 
1897c5ce4427SMatthew G. Knepley   Level: developer
1898c5ce4427SMatthew G. Knepley 
1899c5ce4427SMatthew G. Knepley .keywords: SNES, nonlinear, set, function, norm, type
1900c5ce4427SMatthew G. Knepley .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
1901c5ce4427SMatthew G. Knepley @*/
1902c5ce4427SMatthew G. Knepley PetscErrorCode SNESGetFunctionNorm(SNES snes, PetscReal *norm)
1903c5ce4427SMatthew G. Knepley {
1904c5ce4427SMatthew G. Knepley   PetscFunctionBegin;
1905c5ce4427SMatthew G. Knepley   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1906c5ce4427SMatthew G. Knepley   PetscValidPointer(norm, 2);
1907c5ce4427SMatthew G. Knepley   *norm = snes->norm;
1908c5ce4427SMatthew G. Knepley   PetscFunctionReturn(0);
1909c5ce4427SMatthew G. Knepley }
1910c5ce4427SMatthew G. Knepley 
191147073ea2SPeter Brune /*@C
191247073ea2SPeter Brune    SNESSetFunctionType - Sets the SNESNormSchedule used in covergence and monitoring
191347073ea2SPeter Brune    of the SNES method.
191447073ea2SPeter Brune 
191547073ea2SPeter Brune    Logically Collective on SNES
191647073ea2SPeter Brune 
191747073ea2SPeter Brune    Input Parameters:
191847073ea2SPeter Brune +  snes - the SNES context
191947073ea2SPeter Brune -  normschedule - the frequency of norm computation
192047073ea2SPeter Brune 
192147073ea2SPeter Brune    Notes:
192247073ea2SPeter Brune    Only certain SNES methods support certain SNESNormSchedules.  Most require evaluation
192347073ea2SPeter Brune    of the nonlinear function and the taking of its norm at every iteration to
192447073ea2SPeter Brune    even ensure convergence at all.  However, methods such as custom Gauss-Seidel methods
1925be95d8f1SBarry Smith    (SNESNGS) and the like do not require the norm of the function to be computed, and therfore
192647073ea2SPeter Brune    may either be monitored for convergence or not.  As these are often used as nonlinear
192747073ea2SPeter Brune    preconditioners, monitoring the norm of their error is not a useful enterprise within
192847073ea2SPeter Brune    their solution.
192947073ea2SPeter Brune 
193047073ea2SPeter Brune    Level: developer
193147073ea2SPeter Brune 
193247073ea2SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type
193347073ea2SPeter Brune 
193447073ea2SPeter Brune .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
193547073ea2SPeter Brune @*/
193647073ea2SPeter Brune PetscErrorCode  SNESSetFunctionType(SNES snes, SNESFunctionType type)
193747073ea2SPeter Brune {
193847073ea2SPeter Brune   PetscFunctionBegin;
193947073ea2SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
194047073ea2SPeter Brune   snes->functype = type;
194147073ea2SPeter Brune   PetscFunctionReturn(0);
194247073ea2SPeter Brune }
194347073ea2SPeter Brune 
194447073ea2SPeter Brune 
194547073ea2SPeter Brune /*@C
194647073ea2SPeter Brune    SNESGetFunctionType - Gets the SNESNormSchedule used in covergence and monitoring
194747073ea2SPeter Brune    of the SNES method.
194847073ea2SPeter Brune 
194947073ea2SPeter Brune    Logically Collective on SNES
195047073ea2SPeter Brune 
195147073ea2SPeter Brune    Input Parameters:
195247073ea2SPeter Brune +  snes - the SNES context
195347073ea2SPeter Brune -  normschedule - the type of the norm used
195447073ea2SPeter Brune 
195547073ea2SPeter Brune    Level: advanced
195647073ea2SPeter Brune 
195747073ea2SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type
195847073ea2SPeter Brune 
195947073ea2SPeter Brune .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
196047073ea2SPeter Brune @*/
196147073ea2SPeter Brune PetscErrorCode  SNESGetFunctionType(SNES snes, SNESFunctionType *type)
196247073ea2SPeter Brune {
196347073ea2SPeter Brune   PetscFunctionBegin;
196447073ea2SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
196547073ea2SPeter Brune   *type = snes->functype;
1966534ebe21SPeter Brune   PetscFunctionReturn(0);
1967534ebe21SPeter Brune }
1968534ebe21SPeter Brune 
1969bf388a1fSBarry Smith /*MC
1970be95d8f1SBarry Smith     SNESNGSFunction - function used to convey a Gauss-Seidel sweep on the nonlinear function
1971bf388a1fSBarry Smith 
1972bf388a1fSBarry Smith      Synopsis:
1973aaa7dc30SBarry Smith      #include <petscsnes.h>
1974be95d8f1SBarry Smith $    SNESNGSFunction(SNES snes,Vec x,Vec b,void *ctx);
1975bf388a1fSBarry Smith 
1976bf388a1fSBarry Smith +  X   - solution vector
1977bf388a1fSBarry Smith .  B   - RHS vector
1978bf388a1fSBarry Smith -  ctx - optional user-defined Gauss-Seidel context
1979bf388a1fSBarry Smith 
1980878cb397SSatish Balay    Level: intermediate
1981878cb397SSatish Balay 
1982be95d8f1SBarry Smith .seealso:   SNESSetNGS(), SNESGetNGS()
1983bf388a1fSBarry Smith M*/
1984bf388a1fSBarry Smith 
1985c79ef259SPeter Brune /*@C
1986be95d8f1SBarry Smith    SNESSetNGS - Sets the user nonlinear Gauss-Seidel routine for
1987c79ef259SPeter Brune    use with composed nonlinear solvers.
1988c79ef259SPeter Brune 
1989c79ef259SPeter Brune    Input Parameters:
1990c79ef259SPeter Brune +  snes   - the SNES context
1991be95d8f1SBarry Smith .  f - function evaluation routine to apply Gauss-Seidel see SNESNGSFunction
1992c79ef259SPeter Brune -  ctx    - [optional] user-defined context for private data for the
19930298fd71SBarry Smith             smoother evaluation routine (may be NULL)
1994c79ef259SPeter Brune 
1995c79ef259SPeter Brune    Notes:
1996be95d8f1SBarry Smith    The NGS routines are used by the composed nonlinear solver to generate
1997c79ef259SPeter Brune     a problem appropriate update to the solution, particularly FAS.
1998c79ef259SPeter Brune 
1999d28543b3SPeter Brune    Level: intermediate
2000c79ef259SPeter Brune 
2001d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel
2002c79ef259SPeter Brune 
2003be95d8f1SBarry Smith .seealso: SNESGetFunction(), SNESComputeNGS()
2004c79ef259SPeter Brune @*/
2005be95d8f1SBarry Smith PetscErrorCode SNESSetNGS(SNES snes,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx)
20066cab3a1bSJed Brown {
20076cab3a1bSJed Brown   PetscErrorCode ierr;
20086cab3a1bSJed Brown   DM             dm;
20096cab3a1bSJed Brown 
2010646217ecSPeter Brune   PetscFunctionBegin;
20116cab3a1bSJed Brown   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
20126cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2013be95d8f1SBarry Smith   ierr = DMSNESSetNGS(dm,f,ctx);CHKERRQ(ierr);
2014646217ecSPeter Brune   PetscFunctionReturn(0);
2015646217ecSPeter Brune }
2016646217ecSPeter Brune 
201725acbd8eSLisandro Dalcin PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx)
20188b0a5094SBarry Smith {
20198b0a5094SBarry Smith   PetscErrorCode ierr;
2020e03ab78fSPeter Brune   DM             dm;
2021942e3340SBarry Smith   DMSNES         sdm;
20226cab3a1bSJed Brown 
20238b0a5094SBarry Smith   PetscFunctionBegin;
2024e03ab78fSPeter Brune   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2025942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
202625acbd8eSLisandro Dalcin   if (!sdm->ops->computepfunction) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard function.");
202725acbd8eSLisandro Dalcin   if (!sdm->ops->computepjacobian) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard Jacobian.");
20288b0a5094SBarry Smith   /*  A(x)*x - b(x) */
202925acbd8eSLisandro Dalcin   PetscStackPush("SNES Picard user function");
203022c6f798SBarry Smith   ierr = (*sdm->ops->computepfunction)(snes,x,f,sdm->pctx);CHKERRQ(ierr);
203125acbd8eSLisandro Dalcin   PetscStackPop;
203225acbd8eSLisandro Dalcin   PetscStackPush("SNES Picard user Jacobian");
2033d1e9a80fSBarry Smith   ierr = (*sdm->ops->computepjacobian)(snes,x,snes->jacobian,snes->jacobian_pre,sdm->pctx);CHKERRQ(ierr);
203425acbd8eSLisandro Dalcin   PetscStackPop;
20358b0a5094SBarry Smith   ierr = VecScale(f,-1.0);CHKERRQ(ierr);
203695eabcedSBarry Smith   ierr = MatMultAdd(snes->jacobian,x,f,f);CHKERRQ(ierr);
20378b0a5094SBarry Smith   PetscFunctionReturn(0);
20388b0a5094SBarry Smith }
20398b0a5094SBarry Smith 
204025acbd8eSLisandro Dalcin PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat J,Mat B,void *ctx)
20418b0a5094SBarry Smith {
20428b0a5094SBarry Smith   PetscFunctionBegin;
2043e03ab78fSPeter Brune   /* the jacobian matrix should be pre-filled in SNESPicardComputeFunction */
20448b0a5094SBarry Smith   PetscFunctionReturn(0);
20458b0a5094SBarry Smith }
20468b0a5094SBarry Smith 
20478b0a5094SBarry Smith /*@C
20480d04baf8SBarry Smith    SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization)
20498b0a5094SBarry Smith 
20508b0a5094SBarry Smith    Logically Collective on SNES
20518b0a5094SBarry Smith 
20528b0a5094SBarry Smith    Input Parameters:
20538b0a5094SBarry Smith +  snes - the SNES context
20548b0a5094SBarry Smith .  r - vector to store function value
2055f8b49ee9SBarry Smith .  b - function evaluation routine
2056e5d3d808SBarry Smith .  Amat - matrix with which A(x) x - b(x) is to be computed
2057e5d3d808SBarry Smith .  Pmat - matrix from which preconditioner is computed (usually the same as Amat)
2058411c0326SBarry Smith .  J  - function to compute matrix value, see SNESJacobianFunction for details on its calling sequence
20598b0a5094SBarry Smith -  ctx - [optional] user-defined context for private data for the
20600298fd71SBarry Smith          function evaluation routine (may be NULL)
20618b0a5094SBarry Smith 
20628b0a5094SBarry Smith    Notes:
2063f450aa47SBarry Smith     We do not recomemend using this routine. It is far better to provide the nonlinear function F() and some approximation to the Jacobian and use
2064f450aa47SBarry Smith     an approximate Newton solver. This interface is provided to allow porting/testing a previous Picard based code in PETSc before converting it to approximate Newton.
2065f450aa47SBarry Smith 
20668b0a5094SBarry Smith     One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both
20678b0a5094SBarry Smith 
20688b0a5094SBarry Smith $     Solves the equation A(x) x = b(x) via the defect correction algorithm A(x^{n}) (x^{n+1} - x^{n}) = b(x^{n}) - A(x^{n})x^{n}
20698b0a5094SBarry Smith $     Note that when an exact solver is used this corresponds to the "classic" Picard A(x^{n}) x^{n+1} = b(x^{n}) iteration.
20708b0a5094SBarry Smith 
20718b0a5094SBarry Smith      Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner.
20728b0a5094SBarry Smith 
20730d04baf8SBarry Smith    We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then
20740d04baf8SBarry Smith    the direct Picard iteration A(x^n) x^{n+1} = b(x^n)
20758b0a5094SBarry Smith 
20768b0a5094SBarry Smith    There is some controversity over the definition of a Picard iteration for nonlinear systems but almost everyone agrees that it involves a linear solve and some
20778b0a5094SBarry Smith    believe it is the iteration  A(x^{n}) x^{n+1} = b(x^{n}) hence we use the name Picard. If anyone has an authoritative  reference that defines the Picard iteration
20788b0a5094SBarry Smith    different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-).
20798b0a5094SBarry Smith 
2080f450aa47SBarry Smith    Level: intermediate
20818b0a5094SBarry Smith 
20828b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function
20838b0a5094SBarry Smith 
2084411c0326SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard(), SNESJacobianFunction
20858b0a5094SBarry Smith @*/
2086d1e9a80fSBarry Smith PetscErrorCode  SNESSetPicard(SNES snes,Vec r,PetscErrorCode (*b)(SNES,Vec,Vec,void*),Mat Amat, Mat Pmat, PetscErrorCode (*J)(SNES,Vec,Mat,Mat,void*),void *ctx)
20878b0a5094SBarry Smith {
20888b0a5094SBarry Smith   PetscErrorCode ierr;
2089e03ab78fSPeter Brune   DM             dm;
2090e03ab78fSPeter Brune 
20918b0a5094SBarry Smith   PetscFunctionBegin;
20928b0a5094SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2093e03ab78fSPeter Brune   ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr);
2094f8b49ee9SBarry Smith   ierr = DMSNESSetPicard(dm,b,J,ctx);CHKERRQ(ierr);
20958b0a5094SBarry Smith   ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr);
2096e5d3d808SBarry Smith   ierr = SNESSetJacobian(snes,Amat,Pmat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr);
20978b0a5094SBarry Smith   PetscFunctionReturn(0);
20988b0a5094SBarry Smith }
20998b0a5094SBarry Smith 
21007971a8bfSPeter Brune /*@C
21017971a8bfSPeter Brune    SNESGetPicard - Returns the context for the Picard iteration
21027971a8bfSPeter Brune 
21037971a8bfSPeter Brune    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
21047971a8bfSPeter Brune 
21057971a8bfSPeter Brune    Input Parameter:
21067971a8bfSPeter Brune .  snes - the SNES context
21077971a8bfSPeter Brune 
21087971a8bfSPeter Brune    Output Parameter:
21090298fd71SBarry Smith +  r - the function (or NULL)
2110f8b49ee9SBarry Smith .  f - the function (or NULL); see SNESFunction for calling sequence details
2111e4357dc4SBarry Smith .  Amat - the matrix used to defined the operation A(x) x - b(x) (or NULL)
2112e4357dc4SBarry Smith .  Pmat  - the matrix from which the preconditioner will be constructed (or NULL)
2113f8b49ee9SBarry Smith .  J - the function for matrix evaluation (or NULL); see SNESJacobianFunction for calling sequence details
21140298fd71SBarry Smith -  ctx - the function context (or NULL)
21157971a8bfSPeter Brune 
21167971a8bfSPeter Brune    Level: advanced
21177971a8bfSPeter Brune 
21187971a8bfSPeter Brune .keywords: SNES, nonlinear, get, function
21197971a8bfSPeter Brune 
2120e4357dc4SBarry Smith .seealso: SNESSetPicard(), SNESGetFunction(), SNESGetJacobian(), SNESGetDM(), SNESFunction, SNESJacobianFunction
21217971a8bfSPeter Brune @*/
2122d1e9a80fSBarry Smith PetscErrorCode  SNESGetPicard(SNES snes,Vec *r,PetscErrorCode (**f)(SNES,Vec,Vec,void*),Mat *Amat, Mat *Pmat, PetscErrorCode (**J)(SNES,Vec,Mat,Mat,void*),void **ctx)
21237971a8bfSPeter Brune {
21247971a8bfSPeter Brune   PetscErrorCode ierr;
21257971a8bfSPeter Brune   DM             dm;
21267971a8bfSPeter Brune 
21277971a8bfSPeter Brune   PetscFunctionBegin;
21287971a8bfSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
21290298fd71SBarry Smith   ierr = SNESGetFunction(snes,r,NULL,NULL);CHKERRQ(ierr);
2130e4357dc4SBarry Smith   ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr);
21317971a8bfSPeter Brune   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2132f8b49ee9SBarry Smith   ierr = DMSNESGetPicard(dm,f,J,ctx);CHKERRQ(ierr);
21337971a8bfSPeter Brune   PetscFunctionReturn(0);
21347971a8bfSPeter Brune }
21357971a8bfSPeter Brune 
2136d25893d9SBarry Smith /*@C
2137d25893d9SBarry Smith    SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem
2138d25893d9SBarry Smith 
2139d25893d9SBarry Smith    Logically Collective on SNES
2140d25893d9SBarry Smith 
2141d25893d9SBarry Smith    Input Parameters:
2142d25893d9SBarry Smith +  snes - the SNES context
2143d25893d9SBarry Smith .  func - function evaluation routine
2144d25893d9SBarry Smith -  ctx - [optional] user-defined context for private data for the
21450298fd71SBarry Smith          function evaluation routine (may be NULL)
2146d25893d9SBarry Smith 
2147d25893d9SBarry Smith    Calling sequence of func:
2148d25893d9SBarry Smith $    func (SNES snes,Vec x,void *ctx);
2149d25893d9SBarry Smith 
2150d25893d9SBarry Smith .  f - function vector
2151d25893d9SBarry Smith -  ctx - optional user-defined function context
2152d25893d9SBarry Smith 
2153d25893d9SBarry Smith    Level: intermediate
2154d25893d9SBarry Smith 
2155d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function
2156d25893d9SBarry Smith 
2157d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
2158d25893d9SBarry Smith @*/
2159d25893d9SBarry Smith PetscErrorCode  SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx)
2160d25893d9SBarry Smith {
2161d25893d9SBarry Smith   PetscFunctionBegin;
2162d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2163d25893d9SBarry Smith   if (func) snes->ops->computeinitialguess = func;
2164d25893d9SBarry Smith   if (ctx)  snes->initialguessP            = ctx;
2165d25893d9SBarry Smith   PetscFunctionReturn(0);
2166d25893d9SBarry Smith }
2167d25893d9SBarry Smith 
21683ab0aad5SBarry Smith /* --------------------------------------------------------------- */
21691096aae1SMatthew Knepley /*@C
21701096aae1SMatthew Knepley    SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
21711096aae1SMatthew Knepley    it assumes a zero right hand side.
21721096aae1SMatthew Knepley 
21733f9fe445SBarry Smith    Logically Collective on SNES
21741096aae1SMatthew Knepley 
21751096aae1SMatthew Knepley    Input Parameter:
21761096aae1SMatthew Knepley .  snes - the SNES context
21771096aae1SMatthew Knepley 
21781096aae1SMatthew Knepley    Output Parameter:
21790298fd71SBarry Smith .  rhs - the right hand side vector or NULL if the right hand side vector is null
21801096aae1SMatthew Knepley 
21811096aae1SMatthew Knepley    Level: intermediate
21821096aae1SMatthew Knepley 
21831096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side
21841096aae1SMatthew Knepley 
218585385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
21861096aae1SMatthew Knepley @*/
21877087cfbeSBarry Smith PetscErrorCode  SNESGetRhs(SNES snes,Vec *rhs)
21881096aae1SMatthew Knepley {
21891096aae1SMatthew Knepley   PetscFunctionBegin;
21900700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
21911096aae1SMatthew Knepley   PetscValidPointer(rhs,2);
219285385478SLisandro Dalcin   *rhs = snes->vec_rhs;
21931096aae1SMatthew Knepley   PetscFunctionReturn(0);
21941096aae1SMatthew Knepley }
21951096aae1SMatthew Knepley 
21969b94acceSBarry Smith /*@
2197bf388a1fSBarry Smith    SNESComputeFunction - Calls the function that has been set with SNESSetFunction().
21989b94acceSBarry Smith 
2199c7afd0dbSLois Curfman McInnes    Collective on SNES
2200c7afd0dbSLois Curfman McInnes 
22019b94acceSBarry Smith    Input Parameters:
2202c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2203c7afd0dbSLois Curfman McInnes -  x - input vector
22049b94acceSBarry Smith 
22059b94acceSBarry Smith    Output Parameter:
22063638b69dSLois Curfman McInnes .  y - function vector, as set by SNESSetFunction()
22079b94acceSBarry Smith 
22081bffabb2SLois Curfman McInnes    Notes:
220936851e7fSLois Curfman McInnes    SNESComputeFunction() is typically used within nonlinear solvers
221036851e7fSLois Curfman McInnes    implementations, so most users would not generally call this routine
221136851e7fSLois Curfman McInnes    themselves.
221236851e7fSLois Curfman McInnes 
221336851e7fSLois Curfman McInnes    Level: developer
221436851e7fSLois Curfman McInnes 
22159b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function
22169b94acceSBarry Smith 
2217a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction()
22189b94acceSBarry Smith @*/
22197087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction(SNES snes,Vec x,Vec y)
22209b94acceSBarry Smith {
2221dfbe8321SBarry Smith   PetscErrorCode ierr;
22226cab3a1bSJed Brown   DM             dm;
2223942e3340SBarry Smith   DMSNES         sdm;
22249b94acceSBarry Smith 
22253a40ed3dSBarry Smith   PetscFunctionBegin;
22260700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
22270700a824SBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
22280700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2229c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,x,2);
2230c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,3);
223162796dfbSBarry Smith   ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);
2232184914b5SBarry Smith 
22336cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2234942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
223532f3f7c2SPeter Brune   if (sdm->ops->computefunction) {
223694db00ebSBarry Smith     if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) {
2237ccf3c845SPeter Brune       ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
223894db00ebSBarry Smith     }
22395edff71fSBarry Smith     ierr = VecLockPush(x);CHKERRQ(ierr);
2240d64ed03dSBarry Smith     PetscStackPush("SNES user function");
224122c6f798SBarry Smith     ierr = (*sdm->ops->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr);
2242d64ed03dSBarry Smith     PetscStackPop;
22435edff71fSBarry Smith     ierr = VecLockPop(x);CHKERRQ(ierr);
224494db00ebSBarry Smith     if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) {
2245ccf3c845SPeter Brune       ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
224694db00ebSBarry Smith     }
2247c90fad12SPeter Brune   } else if (snes->vec_rhs) {
2248c90fad12SPeter Brune     ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr);
2249644e2e5bSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve().");
225085385478SLisandro Dalcin   if (snes->vec_rhs) {
225185385478SLisandro Dalcin     ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr);
22523ab0aad5SBarry Smith   }
2253ae3c334cSLois Curfman McInnes   snes->nfuncs++;
2254422a814eSBarry Smith   /*
2255422a814eSBarry Smith      domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will
2256422a814eSBarry Smith      propagate the value to all processes
2257422a814eSBarry Smith   */
2258422a814eSBarry Smith   if (snes->domainerror) {
2259422a814eSBarry Smith     ierr = VecSetInf(y);CHKERRQ(ierr);
2260422a814eSBarry Smith   }
22613a40ed3dSBarry Smith   PetscFunctionReturn(0);
22629b94acceSBarry Smith }
22639b94acceSBarry Smith 
2264c79ef259SPeter Brune /*@
2265be95d8f1SBarry Smith    SNESComputeNGS - Calls the Gauss-Seidel function that has been set with  SNESSetNGS().
2266c79ef259SPeter Brune 
2267c79ef259SPeter Brune    Collective on SNES
2268c79ef259SPeter Brune 
2269c79ef259SPeter Brune    Input Parameters:
2270c79ef259SPeter Brune +  snes - the SNES context
2271c79ef259SPeter Brune .  x - input vector
2272c79ef259SPeter Brune -  b - rhs vector
2273c79ef259SPeter Brune 
2274c79ef259SPeter Brune    Output Parameter:
2275c79ef259SPeter Brune .  x - new solution vector
2276c79ef259SPeter Brune 
2277c79ef259SPeter Brune    Notes:
2278be95d8f1SBarry Smith    SNESComputeNGS() is typically used within composed nonlinear solver
2279c79ef259SPeter Brune    implementations, so most users would not generally call this routine
2280c79ef259SPeter Brune    themselves.
2281c79ef259SPeter Brune 
2282c79ef259SPeter Brune    Level: developer
2283c79ef259SPeter Brune 
2284c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function
2285c79ef259SPeter Brune 
2286be95d8f1SBarry Smith .seealso: SNESSetNGS(), SNESComputeFunction()
2287c79ef259SPeter Brune @*/
2288be95d8f1SBarry Smith PetscErrorCode  SNESComputeNGS(SNES snes,Vec b,Vec x)
2289646217ecSPeter Brune {
2290646217ecSPeter Brune   PetscErrorCode ierr;
22916cab3a1bSJed Brown   DM             dm;
2292942e3340SBarry Smith   DMSNES         sdm;
2293646217ecSPeter Brune 
2294646217ecSPeter Brune   PetscFunctionBegin;
2295646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2296646217ecSPeter Brune   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2297646217ecSPeter Brune   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3);
2298646217ecSPeter Brune   PetscCheckSameComm(snes,1,x,2);
2299646217ecSPeter Brune   if (b) PetscCheckSameComm(snes,1,b,3);
230062796dfbSBarry Smith   if (b) {ierr = VecValidValues(b,2,PETSC_TRUE);CHKERRQ(ierr);}
2301be95d8f1SBarry Smith   ierr = PetscLogEventBegin(SNES_NGSEval,snes,x,b,0);CHKERRQ(ierr);
23026cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2303942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
230422c6f798SBarry Smith   if (sdm->ops->computegs) {
23055edff71fSBarry Smith     if (b) {ierr = VecLockPush(b);CHKERRQ(ierr);}
2306be95d8f1SBarry Smith     PetscStackPush("SNES user NGS");
230722c6f798SBarry Smith     ierr = (*sdm->ops->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr);
2308646217ecSPeter Brune     PetscStackPop;
23095edff71fSBarry Smith     if (b) {ierr = VecLockPop(b);CHKERRQ(ierr);}
2310be95d8f1SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetNGS() before SNESComputeNGS(), likely called from SNESSolve().");
2311be95d8f1SBarry Smith   ierr = PetscLogEventEnd(SNES_NGSEval,snes,x,b,0);CHKERRQ(ierr);
2312646217ecSPeter Brune   PetscFunctionReturn(0);
2313646217ecSPeter Brune }
2314646217ecSPeter Brune 
2315e885f1abSBarry Smith PetscErrorCode SNESTestJacobian(SNES snes)
2316e885f1abSBarry Smith {
231712837594SBarry Smith   Mat               A,B,C,D,jacobian;
2318e885f1abSBarry Smith   Vec               x = snes->vec_sol,f = snes->vec_func;
2319e885f1abSBarry Smith   PetscErrorCode    ierr;
2320e885f1abSBarry Smith   PetscReal         nrm,gnorm;
232181e7118cSBarry Smith   PetscReal         threshold = 1.e-5;
2322e885f1abSBarry Smith   PetscInt          m,n,M,N;
2323e885f1abSBarry Smith   void              *functx;
232418d89885SKarl Rupp   PetscBool         complete_print = PETSC_FALSE,threshold_print = PETSC_FALSE,test = PETSC_FALSE,flg;
23253325ff46SBarry Smith   PetscViewer       viewer,mviewer;
2326e885f1abSBarry Smith   MPI_Comm          comm;
2327e885f1abSBarry Smith   PetscInt          tabs;
232812837594SBarry Smith   static PetscBool  directionsprinted = PETSC_FALSE;
23293325ff46SBarry Smith   PetscViewerFormat format;
2330e885f1abSBarry Smith 
2331e885f1abSBarry Smith   PetscFunctionBegin;
2332fc35ed60SBarry Smith   ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr);
233312837594SBarry Smith   ierr = PetscOptionsName("-snes_test_jacobian","Compare hand-coded and finite difference Jacobians","None",&test);CHKERRQ(ierr);
233412837594SBarry Smith   ierr = PetscOptionsReal("-snes_test_jacobian", "Threshold for element difference between hand-coded and finite difference being meaningful", "None", threshold, &threshold,NULL);CHKERRQ(ierr);
23353325ff46SBarry Smith   ierr = PetscOptionsViewer("-snes_test_jacobian_view","View difference between hand-coded and finite difference Jacobians element entries","None",&mviewer,&format,&complete_print);CHKERRQ(ierr);
233618d89885SKarl Rupp   if (!complete_print) {
233718d89885SKarl Rupp     ierr = PetscOptionsViewer("-snes_test_jacobian_display","Display difference between hand-coded and finite difference Jacobians","None",&mviewer,&format,&complete_print);CHKERRQ(ierr);
233818d89885SKarl Rupp   }
233918d89885SKarl Rupp   /* for compatibility with PETSc 3.9 and older. */
234018d89885SKarl Rupp   ierr = PetscOptionsReal("-snes_test_jacobian_display_threshold", "Display difference between hand-coded and finite difference Jacobians which exceed input threshold", "None", threshold, &threshold, &threshold_print);CHKERRQ(ierr);
2341e885f1abSBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
2342e885f1abSBarry Smith   if (!test) PetscFunctionReturn(0);
2343e885f1abSBarry Smith 
2344e885f1abSBarry Smith   ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
2345e885f1abSBarry Smith   ierr = PetscViewerASCIIGetStdout(comm,&viewer);CHKERRQ(ierr);
2346e885f1abSBarry Smith   ierr = PetscViewerASCIIGetTab(viewer, &tabs);CHKERRQ(ierr);
2347e885f1abSBarry Smith   ierr = PetscViewerASCIISetTab(viewer, ((PetscObject)snes)->tablevel);CHKERRQ(ierr);
234812837594SBarry Smith   ierr = PetscViewerASCIIPrintf(viewer,"  ---------- Testing Jacobian -------------\n");CHKERRQ(ierr);
234912837594SBarry Smith   if (!complete_print && !directionsprinted) {
235012837594SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  Run with -snes_test_jacobian_view and optionally -snes_test_jacobian <threshold> to show difference\n");CHKERRQ(ierr);
2351fc35ed60SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    of hand-coded and finite difference Jacobian entries greater than <threshold>.\n");CHKERRQ(ierr);
235212837594SBarry Smith   }
235312837594SBarry Smith   if (!directionsprinted) {
235412837594SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  Testing hand-coded Jacobian, if (for double precision runs) ||J - Jfd||_F/||J||_F is\n");CHKERRQ(ierr);
2355e885f1abSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    O(1.e-8), the hand-coded Jacobian is probably correct.\n");CHKERRQ(ierr);
235612837594SBarry Smith     directionsprinted = PETSC_TRUE;
2357e885f1abSBarry Smith   }
23583325ff46SBarry Smith   if (complete_print) {
23593325ff46SBarry Smith     ierr = PetscViewerPushFormat(mviewer,format);CHKERRQ(ierr);
2360e885f1abSBarry Smith   }
2361e885f1abSBarry Smith 
236212837594SBarry Smith   /* evaluate the function at this point because SNESComputeJacobianDefault() assumes that the function has been evaluated and put into snes->vec_func */
2363e885f1abSBarry Smith   ierr = SNESComputeFunction(snes,x,f);CHKERRQ(ierr);
236412837594SBarry Smith 
236512837594SBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)snes->jacobian,MATMFFD,&flg);CHKERRQ(ierr);
236612837594SBarry Smith   if (!flg) jacobian = snes->jacobian;
236712837594SBarry Smith   else jacobian = snes->jacobian_pre;
236812837594SBarry Smith 
236912837594SBarry Smith   while (jacobian) {
237012837594SBarry Smith     ierr = PetscObjectTypeCompareAny((PetscObject)jacobian,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr);
237112837594SBarry Smith     if (flg) {
237212837594SBarry Smith       A    = jacobian;
237312837594SBarry Smith       ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
237412837594SBarry Smith     } else {
237512837594SBarry Smith       ierr = MatComputeExplicitOperator(jacobian,&A);CHKERRQ(ierr);
237612837594SBarry Smith     }
2377e885f1abSBarry Smith 
2378e885f1abSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
2379e885f1abSBarry Smith     ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
2380e885f1abSBarry Smith     ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr);
2381e885f1abSBarry Smith     ierr = MatSetSizes(B,m,n,M,N);CHKERRQ(ierr);
2382e885f1abSBarry Smith     ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr);
2383e885f1abSBarry Smith     ierr = MatSetUp(B);CHKERRQ(ierr);
2384e885f1abSBarry Smith     ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr);
2385e885f1abSBarry Smith 
2386e885f1abSBarry Smith     ierr = SNESGetFunction(snes,NULL,NULL,&functx);CHKERRQ(ierr);
2387e885f1abSBarry Smith     ierr = SNESComputeJacobianDefault(snes,x,B,B,functx);CHKERRQ(ierr);
238812837594SBarry Smith 
238912837594SBarry Smith     ierr = MatDuplicate(B,MAT_COPY_VALUES,&D);CHKERRQ(ierr);
239012837594SBarry Smith     ierr = MatAYPX(D,-1.0,A,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
239112837594SBarry Smith     ierr = MatNorm(D,NORM_FROBENIUS,&nrm);CHKERRQ(ierr);
2392e885f1abSBarry Smith     ierr = MatNorm(A,NORM_FROBENIUS,&gnorm);CHKERRQ(ierr);
239312837594SBarry Smith     ierr = MatDestroy(&D);CHKERRQ(ierr);
239412837594SBarry Smith     if (!gnorm) gnorm = 1; /* just in case */
239512837594SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  ||J - Jfd||_F/||J||_F = %g, ||J - Jfd||_F = %g\n",(double)(nrm/gnorm),(double)nrm);CHKERRQ(ierr);
239612837594SBarry Smith 
2397e885f1abSBarry Smith     if (complete_print) {
239812837594SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Hand-coded Jacobian ----------\n");CHKERRQ(ierr);
23993325ff46SBarry Smith       ierr = MatView(jacobian,mviewer);CHKERRQ(ierr);
240012837594SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Finite difference Jacobian ----------\n");CHKERRQ(ierr);
24013325ff46SBarry Smith       ierr = MatView(B,mviewer);CHKERRQ(ierr);
2402e885f1abSBarry Smith     }
2403e885f1abSBarry Smith 
240418d89885SKarl Rupp     if (threshold_print) {
2405e885f1abSBarry Smith       PetscInt          Istart, Iend, *ccols, bncols, cncols, j, row;
2406e885f1abSBarry Smith       PetscScalar       *cvals;
2407e885f1abSBarry Smith       const PetscInt    *bcols;
2408e885f1abSBarry Smith       const PetscScalar *bvals;
2409e885f1abSBarry Smith 
241012837594SBarry Smith       ierr = MatAYPX(B,-1.0,A,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
2411e885f1abSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
2412e885f1abSBarry Smith       ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr);
2413e885f1abSBarry Smith       ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr);
2414e885f1abSBarry Smith       ierr = MatSetUp(C);CHKERRQ(ierr);
2415e885f1abSBarry Smith       ierr = MatSetOption(C,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr);
2416e885f1abSBarry Smith       ierr = MatGetOwnershipRange(B,&Istart,&Iend);CHKERRQ(ierr);
2417e885f1abSBarry Smith 
2418e885f1abSBarry Smith       for (row = Istart; row < Iend; row++) {
2419e885f1abSBarry Smith         ierr = MatGetRow(B,row,&bncols,&bcols,&bvals);CHKERRQ(ierr);
2420e885f1abSBarry Smith         ierr = PetscMalloc2(bncols,&ccols,bncols,&cvals);CHKERRQ(ierr);
2421e885f1abSBarry Smith         for (j = 0, cncols = 0; j < bncols; j++) {
242223a52b1dSBarry Smith           if (PetscAbsScalar(bvals[j]) > threshold) {
2423e885f1abSBarry Smith             ccols[cncols] = bcols[j];
2424e885f1abSBarry Smith             cvals[cncols] = bvals[j];
2425e885f1abSBarry Smith             cncols += 1;
2426e885f1abSBarry Smith           }
2427e885f1abSBarry Smith         }
2428e885f1abSBarry Smith         if (cncols) {
2429e885f1abSBarry Smith           ierr = MatSetValues(C,1,&row,cncols,ccols,cvals,INSERT_VALUES);CHKERRQ(ierr);
2430e885f1abSBarry Smith         }
2431e885f1abSBarry Smith         ierr = MatRestoreRow(B,row,&bncols,&bcols,&bvals);CHKERRQ(ierr);
2432e885f1abSBarry Smith         ierr = PetscFree2(ccols,cvals);CHKERRQ(ierr);
2433e885f1abSBarry Smith       }
2434e885f1abSBarry Smith       ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2435e885f1abSBarry Smith       ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
243612837594SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Hand-coded minus finite-difference Jacobian with tolerance %g ----------\n",(double)threshold);CHKERRQ(ierr);
243718d89885SKarl Rupp       ierr = MatView(C,complete_print ? mviewer : viewer);CHKERRQ(ierr);
2438e885f1abSBarry Smith       ierr = MatDestroy(&C);CHKERRQ(ierr);
2439e885f1abSBarry Smith     }
244012837594SBarry Smith     ierr = MatDestroy(&A);CHKERRQ(ierr);
2441e885f1abSBarry Smith     ierr = MatDestroy(&B);CHKERRQ(ierr);
244212837594SBarry Smith 
244312837594SBarry Smith     if (jacobian != snes->jacobian_pre) {
244412837594SBarry Smith       jacobian = snes->jacobian_pre;
244512837594SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  ---------- Testing Jacobian for preconditioner -------------\n");CHKERRQ(ierr);
244612837594SBarry Smith     }
244712837594SBarry Smith     else jacobian = NULL;
244812837594SBarry Smith   }
24493325ff46SBarry Smith   if (complete_print) {
24503325ff46SBarry Smith     ierr = PetscViewerPopFormat(mviewer);CHKERRQ(ierr);
24513325ff46SBarry Smith   }
2452e885f1abSBarry Smith   ierr = PetscViewerASCIISetTab(viewer,tabs);CHKERRQ(ierr);
2453e885f1abSBarry Smith   PetscFunctionReturn(0);
2454e885f1abSBarry Smith }
2455e885f1abSBarry Smith 
245662fef451SLois Curfman McInnes /*@
2457bf388a1fSBarry Smith    SNESComputeJacobian - Computes the Jacobian matrix that has been set with SNESSetJacobian().
245862fef451SLois Curfman McInnes 
2459c7afd0dbSLois Curfman McInnes    Collective on SNES and Mat
2460c7afd0dbSLois Curfman McInnes 
246162fef451SLois Curfman McInnes    Input Parameters:
2462c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2463c7afd0dbSLois Curfman McInnes -  x - input vector
246462fef451SLois Curfman McInnes 
246562fef451SLois Curfman McInnes    Output Parameters:
2466c7afd0dbSLois Curfman McInnes +  A - Jacobian matrix
2467d1e9a80fSBarry Smith -  B - optional preconditioning matrix
2468fee21e36SBarry Smith 
2469e35cf81dSBarry Smith   Options Database Keys:
2470e35cf81dSBarry Smith +    -snes_lag_preconditioner <lag>
2471693365a8SJed Brown .    -snes_lag_jacobian <lag>
2472e885f1abSBarry Smith .    -snes_test_jacobian - compare the user provided Jacobian with one compute via finite differences to check for errors
2473e885f1abSBarry Smith .    -snes_test_jacobian_display - display the user provided Jacobian, the finite difference Jacobian and the difference between them to help users detect the location of errors in the user provided Jacobian
2474e885f1abSBarry Smith .    -snes_test_jacobian_display_threshold <numerical value>  - display entries in the difference between the user provided Jacobian and finite difference Jacobian that are greater than a certain value to help users detect errors
2475693365a8SJed Brown .    -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences
2476693365a8SJed Brown .    -snes_compare_explicit_draw  - Compare the computed Jacobian to the finite difference Jacobian and draw the result
2477693365a8SJed Brown .    -snes_compare_explicit_contour  - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result
24784c30e9fbSJed Brown .    -snes_compare_operator  - Make the comparison options above use the operator instead of the preconditioning matrix
247994d6a431SBarry Smith .    -snes_compare_coloring - Compute the finite difference Jacobian using coloring and display norms of difference
2480c01495d3SJed Brown .    -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences
2481c01495d3SJed Brown .    -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold
2482c01495d3SJed Brown .    -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
2483c01495d3SJed Brown .    -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
24844c30e9fbSJed Brown .    -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences
2485c01495d3SJed Brown -    -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences
2486c01495d3SJed Brown 
2487e35cf81dSBarry Smith 
248862fef451SLois Curfman McInnes    Notes:
248962fef451SLois Curfman McInnes    Most users should not need to explicitly call this routine, as it
249062fef451SLois Curfman McInnes    is used internally within the nonlinear solvers.
249162fef451SLois Curfman McInnes 
249295452b02SPatrick Sanan    Developer Notes:
249395452b02SPatrick Sanan     This has duplicative ways of checking the accuracy of the user provided Jacobian (see the options above). This is for historical reasons, the routine SNESTestJacobian() use to used
2494e885f1abSBarry Smith       for with the SNESType of test that has been removed.
2495e885f1abSBarry Smith 
249636851e7fSLois Curfman McInnes    Level: developer
249736851e7fSLois Curfman McInnes 
249862fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix
249962fef451SLois Curfman McInnes 
2500e35cf81dSBarry Smith .seealso:  SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian()
250162fef451SLois Curfman McInnes @*/
2502d1e9a80fSBarry Smith PetscErrorCode  SNESComputeJacobian(SNES snes,Vec X,Mat A,Mat B)
25039b94acceSBarry Smith {
2504dfbe8321SBarry Smith   PetscErrorCode ierr;
2505ace3abfcSBarry Smith   PetscBool      flag;
25066cab3a1bSJed Brown   DM             dm;
2507942e3340SBarry Smith   DMSNES         sdm;
2508e0e3a89bSBarry Smith   KSP            ksp;
25093a40ed3dSBarry Smith 
25103a40ed3dSBarry Smith   PetscFunctionBegin;
25110700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
25120700a824SBarry Smith   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
2513c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,X,2);
251462796dfbSBarry Smith   ierr = VecValidValues(X,2,PETSC_TRUE);CHKERRQ(ierr);
25156cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2516942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
25173232da50SPeter Brune 
2518ce94432eSBarry Smith   if (!sdm->ops->computejacobian) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc");
2519ebd3b9afSBarry Smith 
2520ebd3b9afSBarry Smith   /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */
2521ebd3b9afSBarry Smith 
2522fe3ffe1eSBarry Smith   if (snes->lagjacobian == -2) {
2523fe3ffe1eSBarry Smith     snes->lagjacobian = -1;
2524f5af7f23SKarl Rupp 
2525fe3ffe1eSBarry Smith     ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr);
2526fe3ffe1eSBarry Smith   } else if (snes->lagjacobian == -1) {
2527e35cf81dSBarry Smith     ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr);
252894ab13aaSBarry Smith     ierr = PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag);CHKERRQ(ierr);
2529ebd3b9afSBarry Smith     if (flag) {
253094ab13aaSBarry Smith       ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
253194ab13aaSBarry Smith       ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2532ebd3b9afSBarry Smith     }
2533e35cf81dSBarry Smith     PetscFunctionReturn(0);
253437ec4e1aSPeter Brune   } else if (snes->lagjacobian > 1 && (snes->iter + snes->jac_iter) % snes->lagjacobian) {
2535e35cf81dSBarry Smith     ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr);
253694ab13aaSBarry Smith     ierr = PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag);CHKERRQ(ierr);
2537ebd3b9afSBarry Smith     if (flag) {
253894ab13aaSBarry Smith       ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
253994ab13aaSBarry Smith       ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2540ebd3b9afSBarry Smith     }
2541e35cf81dSBarry Smith     PetscFunctionReturn(0);
2542e35cf81dSBarry Smith   }
2543efd4aadfSBarry Smith   if (snes->npc && snes->npcside== PC_LEFT) {
254494ab13aaSBarry Smith       ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
254594ab13aaSBarry Smith       ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2546d728fb7dSPeter Brune       PetscFunctionReturn(0);
2547d728fb7dSPeter Brune   }
2548e35cf81dSBarry Smith 
254994ab13aaSBarry Smith   ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,A,B);CHKERRQ(ierr);
25505edff71fSBarry Smith   ierr = VecLockPush(X);CHKERRQ(ierr);
2551d64ed03dSBarry Smith   PetscStackPush("SNES user Jacobian function");
2552d1e9a80fSBarry Smith   ierr = (*sdm->ops->computejacobian)(snes,X,A,B,sdm->jacobianctx);CHKERRQ(ierr);
2553d64ed03dSBarry Smith   PetscStackPop;
25545edff71fSBarry Smith   ierr = VecLockPop(X);CHKERRQ(ierr);
255594ab13aaSBarry Smith   ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,A,B);CHKERRQ(ierr);
2556a8054027SBarry Smith 
2557e0e3a89bSBarry Smith   /* the next line ensures that snes->ksp exists */
2558e0e3a89bSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
25593b4f5425SBarry Smith   if (snes->lagpreconditioner == -2) {
25603b4f5425SBarry Smith     ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr);
2561d1e9a80fSBarry Smith     ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE);CHKERRQ(ierr);
25623b4f5425SBarry Smith     snes->lagpreconditioner = -1;
25633b4f5425SBarry Smith   } else if (snes->lagpreconditioner == -1) {
2564a8054027SBarry Smith     ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr);
2565d1e9a80fSBarry Smith     ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE);CHKERRQ(ierr);
256637ec4e1aSPeter Brune   } else if (snes->lagpreconditioner > 1 && (snes->iter + snes->pre_iter) % snes->lagpreconditioner) {
2567a8054027SBarry Smith     ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr);
2568d1e9a80fSBarry Smith     ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE);CHKERRQ(ierr);
2569d1e9a80fSBarry Smith   } else {
2570d1e9a80fSBarry Smith     ierr = PetscInfo(snes,"Rebuilding preconditioner\n");CHKERRQ(ierr);
2571d1e9a80fSBarry Smith     ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE);CHKERRQ(ierr);
2572a8054027SBarry Smith   }
2573a8054027SBarry Smith 
2574e885f1abSBarry Smith   ierr = SNESTestJacobian(snes);CHKERRQ(ierr);
25756d84be18SBarry Smith   /* make sure user returned a correct Jacobian and preconditioner */
257694ab13aaSBarry Smith   /* PetscValidHeaderSpecific(A,MAT_CLASSID,3);
257794ab13aaSBarry Smith     PetscValidHeaderSpecific(B,MAT_CLASSID,4);   */
2578693365a8SJed Brown   {
2579693365a8SJed Brown     PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE;
258027b0f280SBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_explicit",NULL,NULL,&flag);CHKERRQ(ierr);
258127b0f280SBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",NULL,NULL,&flag_draw);CHKERRQ(ierr);
258227b0f280SBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",NULL,NULL,&flag_contour);CHKERRQ(ierr);
258327b0f280SBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_operator",NULL,NULL,&flag_operator);CHKERRQ(ierr);
2584693365a8SJed Brown     if (flag || flag_draw || flag_contour) {
25850298fd71SBarry Smith       Mat          Bexp_mine = NULL,Bexp,FDexp;
2586693365a8SJed Brown       PetscViewer  vdraw,vstdout;
25876b3a5b13SJed Brown       PetscBool    flg;
2588693365a8SJed Brown       if (flag_operator) {
258994ab13aaSBarry Smith         ierr = MatComputeExplicitOperator(A,&Bexp_mine);CHKERRQ(ierr);
2590693365a8SJed Brown         Bexp = Bexp_mine;
2591693365a8SJed Brown       } else {
2592693365a8SJed Brown         /* See if the preconditioning matrix can be viewed and added directly */
259394ab13aaSBarry Smith         ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr);
259494ab13aaSBarry Smith         if (flg) Bexp = B;
2595693365a8SJed Brown         else {
2596693365a8SJed Brown           /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */
259794ab13aaSBarry Smith           ierr = MatComputeExplicitOperator(B,&Bexp_mine);CHKERRQ(ierr);
2598693365a8SJed Brown           Bexp = Bexp_mine;
2599693365a8SJed Brown         }
2600693365a8SJed Brown       }
2601693365a8SJed Brown       ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr);
2602d1e9a80fSBarry Smith       ierr = SNESComputeJacobianDefault(snes,X,FDexp,FDexp,NULL);CHKERRQ(ierr);
2603ce94432eSBarry Smith       ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout);CHKERRQ(ierr);
2604693365a8SJed Brown       if (flag_draw || flag_contour) {
2605ce94432eSBarry Smith         ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
2606693365a8SJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
26070298fd71SBarry Smith       } else vdraw = NULL;
2608693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator ? "Jacobian" : "preconditioning Jacobian");CHKERRQ(ierr);
2609693365a8SJed Brown       if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);}
2610693365a8SJed Brown       if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);}
2611693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr);
2612693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
2613693365a8SJed Brown       if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);}
2614693365a8SJed Brown       ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2615693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr);
2616693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
2617693365a8SJed Brown       if (vdraw) {              /* Always use contour for the difference */
2618693365a8SJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
2619693365a8SJed Brown         ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);
2620693365a8SJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
2621693365a8SJed Brown       }
2622693365a8SJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
2623693365a8SJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
2624693365a8SJed Brown       ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr);
2625693365a8SJed Brown       ierr = MatDestroy(&FDexp);CHKERRQ(ierr);
2626693365a8SJed Brown     }
2627693365a8SJed Brown   }
26284c30e9fbSJed Brown   {
26296719d8e4SJed Brown     PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE;
26306719d8e4SJed Brown     PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON;
263127b0f280SBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring",NULL,NULL,&flag);CHKERRQ(ierr);
263227b0f280SBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring_display",NULL,NULL,&flag_display);CHKERRQ(ierr);
263327b0f280SBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",NULL,NULL,&flag_draw);CHKERRQ(ierr);
263427b0f280SBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",NULL,NULL,&flag_contour);CHKERRQ(ierr);
263527b0f280SBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",NULL,NULL,&flag_threshold);CHKERRQ(ierr);
263627b0f280SBarry Smith     if (flag_threshold) {
2637c5929fdfSBarry Smith       ierr = PetscOptionsGetReal(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,NULL);CHKERRQ(ierr);
2638c5929fdfSBarry Smith       ierr = PetscOptionsGetReal(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,NULL);CHKERRQ(ierr);
263927b0f280SBarry Smith     }
26406719d8e4SJed Brown     if (flag || flag_display || flag_draw || flag_contour || flag_threshold) {
26414c30e9fbSJed Brown       Mat            Bfd;
26424c30e9fbSJed Brown       PetscViewer    vdraw,vstdout;
2643335efc43SPeter Brune       MatColoring    coloring;
26444c30e9fbSJed Brown       ISColoring     iscoloring;
26454c30e9fbSJed Brown       MatFDColoring  matfdcoloring;
26464c30e9fbSJed Brown       PetscErrorCode (*func)(SNES,Vec,Vec,void*);
26474c30e9fbSJed Brown       void           *funcctx;
26486719d8e4SJed Brown       PetscReal      norm1,norm2,normmax;
26494c30e9fbSJed Brown 
265094ab13aaSBarry Smith       ierr = MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr);
2651335efc43SPeter Brune       ierr = MatColoringCreate(Bfd,&coloring);CHKERRQ(ierr);
2652335efc43SPeter Brune       ierr = MatColoringSetType(coloring,MATCOLORINGSL);CHKERRQ(ierr);
2653335efc43SPeter Brune       ierr = MatColoringSetFromOptions(coloring);CHKERRQ(ierr);
2654335efc43SPeter Brune       ierr = MatColoringApply(coloring,&iscoloring);CHKERRQ(ierr);
2655335efc43SPeter Brune       ierr = MatColoringDestroy(&coloring);CHKERRQ(ierr);
26564c30e9fbSJed Brown       ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr);
2657f86b9fbaSHong Zhang       ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr);
2658f86b9fbaSHong Zhang       ierr = MatFDColoringSetUp(Bfd,iscoloring,matfdcoloring);CHKERRQ(ierr);
26594c30e9fbSJed Brown       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
26604c30e9fbSJed Brown 
26614c30e9fbSJed Brown       /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */
26620298fd71SBarry Smith       ierr = SNESGetFunction(snes,NULL,&func,&funcctx);CHKERRQ(ierr);
26634c30e9fbSJed Brown       ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode (*)(void))func,funcctx);CHKERRQ(ierr);
26644c30e9fbSJed Brown       ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr);
26654c30e9fbSJed Brown       ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr);
26664c30e9fbSJed Brown       ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr);
2667d1e9a80fSBarry Smith       ierr = MatFDColoringApply(Bfd,matfdcoloring,X,snes);CHKERRQ(ierr);
26684c30e9fbSJed Brown       ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr);
26694c30e9fbSJed Brown 
2670ce94432eSBarry Smith       ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout);CHKERRQ(ierr);
26714c30e9fbSJed Brown       if (flag_draw || flag_contour) {
2672ce94432eSBarry Smith         ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
26734c30e9fbSJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
26740298fd71SBarry Smith       } else vdraw = NULL;
26754c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr);
267694ab13aaSBarry Smith       if (flag_display) {ierr = MatView(B,vstdout);CHKERRQ(ierr);}
267794ab13aaSBarry Smith       if (vdraw) {ierr = MatView(B,vdraw);CHKERRQ(ierr);}
26784c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr);
26796719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
26804c30e9fbSJed Brown       if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);}
268194ab13aaSBarry Smith       ierr = MatAYPX(Bfd,-1.0,B,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
26824c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr);
26836719d8e4SJed Brown       ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr);
26844c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr);
268557622a8eSBarry Smith       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%g normFrob=%g normmax=%g\n",(double)norm1,(double)norm2,(double)normmax);CHKERRQ(ierr);
26866719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
26874c30e9fbSJed Brown       if (vdraw) {              /* Always use contour for the difference */
26884c30e9fbSJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
26894c30e9fbSJed Brown         ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);
26904c30e9fbSJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
26914c30e9fbSJed Brown       }
26924c30e9fbSJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
26936719d8e4SJed Brown 
26946719d8e4SJed Brown       if (flag_threshold) {
26956719d8e4SJed Brown         PetscInt bs,rstart,rend,i;
269694ab13aaSBarry Smith         ierr = MatGetBlockSize(B,&bs);CHKERRQ(ierr);
269794ab13aaSBarry Smith         ierr = MatGetOwnershipRange(B,&rstart,&rend);CHKERRQ(ierr);
26986719d8e4SJed Brown         for (i=rstart; i<rend; i++) {
26996719d8e4SJed Brown           const PetscScalar *ba,*ca;
27006719d8e4SJed Brown           const PetscInt    *bj,*cj;
27016719d8e4SJed Brown           PetscInt          bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1;
27026719d8e4SJed Brown           PetscReal         maxentry = 0,maxdiff = 0,maxrdiff = 0;
270394ab13aaSBarry Smith           ierr = MatGetRow(B,i,&bn,&bj,&ba);CHKERRQ(ierr);
27046719d8e4SJed Brown           ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
270594ab13aaSBarry Smith           if (bn != cn) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold");
27066719d8e4SJed Brown           for (j=0; j<bn; j++) {
27076719d8e4SJed Brown             PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
27086719d8e4SJed Brown             if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) {
27096719d8e4SJed Brown               maxentrycol = bj[j];
27106719d8e4SJed Brown               maxentry    = PetscRealPart(ba[j]);
27116719d8e4SJed Brown             }
27126719d8e4SJed Brown             if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) {
27136719d8e4SJed Brown               maxdiffcol = bj[j];
27146719d8e4SJed Brown               maxdiff    = PetscRealPart(ca[j]);
27156719d8e4SJed Brown             }
27166719d8e4SJed Brown             if (rdiff > maxrdiff) {
27176719d8e4SJed Brown               maxrdiffcol = bj[j];
27186719d8e4SJed Brown               maxrdiff    = rdiff;
27196719d8e4SJed Brown             }
27206719d8e4SJed Brown           }
27216719d8e4SJed Brown           if (maxrdiff > 1) {
272257622a8eSBarry Smith             ierr = PetscViewerASCIIPrintf(vstdout,"row %D (maxentry=%g at %D, maxdiff=%g at %D, maxrdiff=%g at %D):",i,(double)maxentry,maxentrycol,(double)maxdiff,maxdiffcol,(double)maxrdiff,maxrdiffcol);CHKERRQ(ierr);
27236719d8e4SJed Brown             for (j=0; j<bn; j++) {
27246719d8e4SJed Brown               PetscReal rdiff;
27256719d8e4SJed Brown               rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
27266719d8e4SJed Brown               if (rdiff > 1) {
272757622a8eSBarry Smith                 ierr = PetscViewerASCIIPrintf(vstdout," (%D,%g:%g)",bj[j],(double)PetscRealPart(ba[j]),(double)PetscRealPart(ca[j]));CHKERRQ(ierr);
27286719d8e4SJed Brown               }
27296719d8e4SJed Brown             }
27306719d8e4SJed Brown             ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr);
27316719d8e4SJed Brown           }
273294ab13aaSBarry Smith           ierr = MatRestoreRow(B,i,&bn,&bj,&ba);CHKERRQ(ierr);
27336719d8e4SJed Brown           ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
27346719d8e4SJed Brown         }
27356719d8e4SJed Brown       }
27364c30e9fbSJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
27374c30e9fbSJed Brown       ierr = MatDestroy(&Bfd);CHKERRQ(ierr);
27384c30e9fbSJed Brown     }
27394c30e9fbSJed Brown   }
27403a40ed3dSBarry Smith   PetscFunctionReturn(0);
27419b94acceSBarry Smith }
27429b94acceSBarry Smith 
2743bf388a1fSBarry Smith /*MC
2744411c0326SBarry Smith     SNESJacobianFunction - Function used to convey the nonlinear Jacobian of the function to be solved by SNES
2745bf388a1fSBarry Smith 
2746bf388a1fSBarry Smith      Synopsis:
2747411c0326SBarry Smith      #include "petscsnes.h"
2748411c0326SBarry Smith      PetscErrorCode SNESJacobianFunction(SNES snes,Vec x,Mat Amat,Mat Pmat,void *ctx);
2749bf388a1fSBarry Smith 
2750bf388a1fSBarry Smith +  x - input vector
2751e5d3d808SBarry Smith .  Amat - the matrix that defines the (approximate) Jacobian
2752e5d3d808SBarry Smith .  Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat.
2753bf388a1fSBarry Smith -  ctx - [optional] user-defined Jacobian context
2754bf388a1fSBarry Smith 
2755878cb397SSatish Balay    Level: intermediate
2756878cb397SSatish Balay 
2757bf388a1fSBarry Smith .seealso:   SNESSetFunction(), SNESGetFunction(), SNESSetJacobian(), SNESGetJacobian()
2758bf388a1fSBarry Smith M*/
2759bf388a1fSBarry Smith 
27609b94acceSBarry Smith /*@C
27619b94acceSBarry Smith    SNESSetJacobian - Sets the function to compute Jacobian as well as the
2762044dda88SLois Curfman McInnes    location to store the matrix.
27639b94acceSBarry Smith 
27643f9fe445SBarry Smith    Logically Collective on SNES and Mat
2765c7afd0dbSLois Curfman McInnes 
27669b94acceSBarry Smith    Input Parameters:
2767c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2768e5d3d808SBarry Smith .  Amat - the matrix that defines the (approximate) Jacobian
2769e5d3d808SBarry Smith .  Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat.
2770411c0326SBarry Smith .  J - Jacobian evaluation routine (if NULL then SNES retains any previously set value), see SNESJacobianFunction for details
2771c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
27720298fd71SBarry Smith          Jacobian evaluation routine (may be NULL) (if NULL then SNES retains any previously set value)
27739b94acceSBarry Smith 
27749b94acceSBarry Smith    Notes:
2775e5d3d808SBarry Smith    If the Amat matrix and Pmat matrix are different you must call MatAssemblyBegin/End() on
277616913363SBarry Smith    each matrix.
277716913363SBarry Smith 
2778895c21f2SBarry Smith    If you know the operator Amat has a null space you can use MatSetNullSpace() and MatSetTransposeNullSpace() to supply the null
2779895c21f2SBarry Smith    space to Amat and the KSP solvers will automatically use that null space as needed during the solution process.
2780895c21f2SBarry Smith 
27818d359177SBarry Smith    If using SNESComputeJacobianDefaultColor() to assemble a Jacobian, the ctx argument
2782a8a26c1eSJed Brown    must be a MatFDColoring.
2783a8a26c1eSJed Brown 
2784c3cc8fd1SJed Brown    Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian.  One common
2785c3cc8fd1SJed Brown    example is to use the "Picard linearization" which only differentiates through the highest order parts of each term.
2786c3cc8fd1SJed Brown 
278736851e7fSLois Curfman McInnes    Level: beginner
278836851e7fSLois Curfman McInnes 
27899b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix
27909b94acceSBarry Smith 
2791411c0326SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESComputeJacobianDefaultColor(), MatStructure, J,
2792411c0326SBarry Smith           SNESSetPicard(), SNESJacobianFunction
27939b94acceSBarry Smith @*/
2794d1e9a80fSBarry Smith PetscErrorCode  SNESSetJacobian(SNES snes,Mat Amat,Mat Pmat,PetscErrorCode (*J)(SNES,Vec,Mat,Mat,void*),void *ctx)
27959b94acceSBarry Smith {
2796dfbe8321SBarry Smith   PetscErrorCode ierr;
27976cab3a1bSJed Brown   DM             dm;
27983a7fca6bSBarry Smith 
27993a40ed3dSBarry Smith   PetscFunctionBegin;
28000700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2801e5d3d808SBarry Smith   if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2);
2802e5d3d808SBarry Smith   if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_CLASSID,3);
2803e5d3d808SBarry Smith   if (Amat) PetscCheckSameComm(snes,1,Amat,2);
2804e5d3d808SBarry Smith   if (Pmat) PetscCheckSameComm(snes,1,Pmat,3);
28056cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2806f8b49ee9SBarry Smith   ierr = DMSNESSetJacobian(dm,J,ctx);CHKERRQ(ierr);
2807e5d3d808SBarry Smith   if (Amat) {
2808e5d3d808SBarry Smith     ierr = PetscObjectReference((PetscObject)Amat);CHKERRQ(ierr);
28096bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
2810f5af7f23SKarl Rupp 
2811e5d3d808SBarry Smith     snes->jacobian = Amat;
28123a7fca6bSBarry Smith   }
2813e5d3d808SBarry Smith   if (Pmat) {
2814e5d3d808SBarry Smith     ierr = PetscObjectReference((PetscObject)Pmat);CHKERRQ(ierr);
28156bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
2816f5af7f23SKarl Rupp 
2817e5d3d808SBarry Smith     snes->jacobian_pre = Pmat;
28183a7fca6bSBarry Smith   }
28193a40ed3dSBarry Smith   PetscFunctionReturn(0);
28209b94acceSBarry Smith }
282162fef451SLois Curfman McInnes 
2822c2aafc4cSSatish Balay /*@C
2823b4fd4287SBarry Smith    SNESGetJacobian - Returns the Jacobian matrix and optionally the user
2824b4fd4287SBarry Smith    provided context for evaluating the Jacobian.
2825b4fd4287SBarry Smith 
2826c7afd0dbSLois Curfman McInnes    Not Collective, but Mat object will be parallel if SNES object is
2827c7afd0dbSLois Curfman McInnes 
2828b4fd4287SBarry Smith    Input Parameter:
2829b4fd4287SBarry Smith .  snes - the nonlinear solver context
2830b4fd4287SBarry Smith 
2831b4fd4287SBarry Smith    Output Parameters:
2832e5d3d808SBarry Smith +  Amat - location to stash (approximate) Jacobian matrix (or NULL)
2833e5d3d808SBarry Smith .  Pmat - location to stash matrix used to compute the preconditioner (or NULL)
2834411c0326SBarry Smith .  J - location to put Jacobian function (or NULL), see SNESJacobianFunction for details on its calling sequence
28350298fd71SBarry Smith -  ctx - location to stash Jacobian ctx (or NULL)
2836fee21e36SBarry Smith 
283736851e7fSLois Curfman McInnes    Level: advanced
283836851e7fSLois Curfman McInnes 
2839411c0326SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian(), SNESJacobianFunction, SNESGetFunction()
2840b4fd4287SBarry Smith @*/
2841d1e9a80fSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *Amat,Mat *Pmat,PetscErrorCode (**J)(SNES,Vec,Mat,Mat,void*),void **ctx)
2842b4fd4287SBarry Smith {
28436cab3a1bSJed Brown   PetscErrorCode ierr;
28446cab3a1bSJed Brown   DM             dm;
2845942e3340SBarry Smith   DMSNES         sdm;
28466cab3a1bSJed Brown 
28473a40ed3dSBarry Smith   PetscFunctionBegin;
28480700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2849e5d3d808SBarry Smith   if (Amat) *Amat = snes->jacobian;
2850e5d3d808SBarry Smith   if (Pmat) *Pmat = snes->jacobian_pre;
28516cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2852942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
2853f8b49ee9SBarry Smith   if (J) *J = sdm->ops->computejacobian;
28546cab3a1bSJed Brown   if (ctx) *ctx = sdm->jacobianctx;
28553a40ed3dSBarry Smith   PetscFunctionReturn(0);
2856b4fd4287SBarry Smith }
2857b4fd4287SBarry Smith 
28589b94acceSBarry Smith /*@
28599b94acceSBarry Smith    SNESSetUp - Sets up the internal data structures for the later use
2860272ac6f2SLois Curfman McInnes    of a nonlinear solver.
28619b94acceSBarry Smith 
2862fee21e36SBarry Smith    Collective on SNES
2863fee21e36SBarry Smith 
2864c7afd0dbSLois Curfman McInnes    Input Parameters:
286570e92668SMatthew Knepley .  snes - the SNES context
2866c7afd0dbSLois Curfman McInnes 
2867272ac6f2SLois Curfman McInnes    Notes:
2868272ac6f2SLois Curfman McInnes    For basic use of the SNES solvers the user need not explicitly call
2869272ac6f2SLois Curfman McInnes    SNESSetUp(), since these actions will automatically occur during
2870272ac6f2SLois Curfman McInnes    the call to SNESSolve().  However, if one wishes to control this
2871272ac6f2SLois Curfman McInnes    phase separately, SNESSetUp() should be called after SNESCreate()
2872272ac6f2SLois Curfman McInnes    and optional routines of the form SNESSetXXX(), but before SNESSolve().
2873272ac6f2SLois Curfman McInnes 
287436851e7fSLois Curfman McInnes    Level: advanced
287536851e7fSLois Curfman McInnes 
28769b94acceSBarry Smith .keywords: SNES, nonlinear, setup
28779b94acceSBarry Smith 
28789b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
28799b94acceSBarry Smith @*/
28807087cfbeSBarry Smith PetscErrorCode  SNESSetUp(SNES snes)
28819b94acceSBarry Smith {
2882dfbe8321SBarry Smith   PetscErrorCode ierr;
28836cab3a1bSJed Brown   DM             dm;
2884942e3340SBarry Smith   DMSNES         sdm;
2885c35f09e5SBarry Smith   SNESLineSearch linesearch, pclinesearch;
28866e2a1849SPeter Brune   void           *lsprectx,*lspostctx;
28876b2b7091SBarry Smith   PetscErrorCode (*precheck)(SNESLineSearch,Vec,Vec,PetscBool*,void*);
28886b2b7091SBarry Smith   PetscErrorCode (*postcheck)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*);
28896e2a1849SPeter Brune   PetscErrorCode (*func)(SNES,Vec,Vec,void*);
28906e2a1849SPeter Brune   Vec            f,fpc;
28916e2a1849SPeter Brune   void           *funcctx;
2892d1e9a80fSBarry Smith   PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*);
28931eb13d49SPeter Brune   void           *jacctx,*appctx;
289432b97717SPeter Brune   Mat            j,jpre;
28953a40ed3dSBarry Smith 
28963a40ed3dSBarry Smith   PetscFunctionBegin;
28970700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
28984dc4c822SBarry Smith   if (snes->setupcalled) PetscFunctionReturn(0);
28999b94acceSBarry Smith 
29007adad957SLisandro Dalcin   if (!((PetscObject)snes)->type_name) {
290104d7464bSBarry Smith     ierr = SNESSetType(snes,SNESNEWTONLS);CHKERRQ(ierr);
290285385478SLisandro Dalcin   }
290385385478SLisandro Dalcin 
29040298fd71SBarry Smith   ierr = SNESGetFunction(snes,&snes->vec_func,NULL,NULL);CHKERRQ(ierr);
290558c9b817SLisandro Dalcin 
29066cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2907942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
2908ce94432eSBarry Smith   if (!sdm->ops->computefunction) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Function never provided to SNES object");
290922c6f798SBarry Smith   if (!sdm->ops->computejacobian) {
29108d359177SBarry Smith     ierr = DMSNESSetJacobian(dm,SNESComputeJacobianDefaultColor,NULL);CHKERRQ(ierr);
291119f7a02aSBarry Smith   }
29126cab3a1bSJed Brown   if (!snes->vec_func) {
29136cab3a1bSJed Brown     ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr);
2914214df951SJed Brown   }
2915efd51863SBarry Smith 
291622d28d08SBarry Smith   if (!snes->ksp) {
291722d28d08SBarry Smith     ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);
291822d28d08SBarry Smith   }
2919b710008aSBarry Smith 
292022d28d08SBarry Smith   if (!snes->linesearch) {
29217601faf0SJed Brown     ierr = SNESGetLineSearch(snes, &snes->linesearch);CHKERRQ(ierr);
292222d28d08SBarry Smith   }
2923ed07d7d7SPeter Brune   ierr = SNESLineSearchSetFunction(snes->linesearch,SNESComputeFunction);CHKERRQ(ierr);
29249e764e56SPeter Brune 
2925efd4aadfSBarry Smith   if (snes->npc && (snes->npcside== PC_LEFT)) {
2926172a4300SPeter Brune     snes->mf          = PETSC_TRUE;
2927172a4300SPeter Brune     snes->mf_operator = PETSC_FALSE;
2928172a4300SPeter Brune   }
2929d8f46077SPeter Brune 
2930efd4aadfSBarry Smith   if (snes->npc) {
29316e2a1849SPeter Brune     /* copy the DM over */
29326e2a1849SPeter Brune     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2933efd4aadfSBarry Smith     ierr = SNESSetDM(snes->npc,dm);CHKERRQ(ierr);
29346e2a1849SPeter Brune 
29356e2a1849SPeter Brune     ierr = SNESGetFunction(snes,&f,&func,&funcctx);CHKERRQ(ierr);
29366e2a1849SPeter Brune     ierr = VecDuplicate(f,&fpc);CHKERRQ(ierr);
2937efd4aadfSBarry Smith     ierr = SNESSetFunction(snes->npc,fpc,func,funcctx);CHKERRQ(ierr);
293832b97717SPeter Brune     ierr = SNESGetJacobian(snes,&j,&jpre,&jac,&jacctx);CHKERRQ(ierr);
2939efd4aadfSBarry Smith     ierr = SNESSetJacobian(snes->npc,j,jpre,jac,jacctx);CHKERRQ(ierr);
29401eb13d49SPeter Brune     ierr = SNESGetApplicationContext(snes,&appctx);CHKERRQ(ierr);
2941efd4aadfSBarry Smith     ierr = SNESSetApplicationContext(snes->npc,appctx);CHKERRQ(ierr);
29426e2a1849SPeter Brune     ierr = VecDestroy(&fpc);CHKERRQ(ierr);
29436e2a1849SPeter Brune 
29446e2a1849SPeter Brune     /* copy the function pointers over */
2945efd4aadfSBarry Smith     ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)snes,(PetscObject)snes->npc);CHKERRQ(ierr);
29466e2a1849SPeter Brune 
29476e2a1849SPeter Brune     /* default to 1 iteration */
2948efd4aadfSBarry Smith     ierr = SNESSetTolerances(snes->npc,0.0,0.0,0.0,1,snes->npc->max_funcs);CHKERRQ(ierr);
2949efd4aadfSBarry Smith     if (snes->npcside==PC_RIGHT) {
2950efd4aadfSBarry Smith       ierr = SNESSetNormSchedule(snes->npc,SNES_NORM_FINAL_ONLY);CHKERRQ(ierr);
2951a9936a0cSPeter Brune     } else {
2952efd4aadfSBarry Smith       ierr = SNESSetNormSchedule(snes->npc,SNES_NORM_NONE);CHKERRQ(ierr);
2953a9936a0cSPeter Brune     }
2954efd4aadfSBarry Smith     ierr = SNESSetFromOptions(snes->npc);CHKERRQ(ierr);
29556e2a1849SPeter Brune 
29566e2a1849SPeter Brune     /* copy the line search context over */
29577601faf0SJed Brown     ierr = SNESGetLineSearch(snes,&linesearch);CHKERRQ(ierr);
2958efd4aadfSBarry Smith     ierr = SNESGetLineSearch(snes->npc,&pclinesearch);CHKERRQ(ierr);
29596b2b7091SBarry Smith     ierr = SNESLineSearchGetPreCheck(linesearch,&precheck,&lsprectx);CHKERRQ(ierr);
29606b2b7091SBarry Smith     ierr = SNESLineSearchGetPostCheck(linesearch,&postcheck,&lspostctx);CHKERRQ(ierr);
29616b2b7091SBarry Smith     ierr = SNESLineSearchSetPreCheck(pclinesearch,precheck,lsprectx);CHKERRQ(ierr);
29626b2b7091SBarry Smith     ierr = SNESLineSearchSetPostCheck(pclinesearch,postcheck,lspostctx);CHKERRQ(ierr);
29636e2a1849SPeter Brune     ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch);CHKERRQ(ierr);
29646e2a1849SPeter Brune   }
296532b97717SPeter Brune   if (snes->mf) {
296632b97717SPeter Brune     ierr = SNESSetUpMatrixFree_Private(snes, snes->mf_operator, snes->mf_version);CHKERRQ(ierr);
296732b97717SPeter Brune   }
296832b97717SPeter Brune   if (snes->ops->usercompute && !snes->user) {
296932b97717SPeter Brune     ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr);
297032b97717SPeter Brune   }
29716e2a1849SPeter Brune 
297237ec4e1aSPeter Brune   snes->jac_iter = 0;
297337ec4e1aSPeter Brune   snes->pre_iter = 0;
297437ec4e1aSPeter Brune 
2975410397dcSLisandro Dalcin   if (snes->ops->setup) {
2976410397dcSLisandro Dalcin     ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr);
2977410397dcSLisandro Dalcin   }
297858c9b817SLisandro Dalcin 
2979efd4aadfSBarry Smith   if (snes->npc && (snes->npcside== PC_LEFT)) {
29806c67d002SPeter Brune     if (snes->functype == SNES_FUNCTION_PRECONDITIONED) {
298155d4788fSPeter Brune       ierr = SNESGetLineSearch(snes,&linesearch);CHKERRQ(ierr);
2982be95d8f1SBarry Smith       ierr = SNESLineSearchSetFunction(linesearch,SNESComputeFunctionDefaultNPC);CHKERRQ(ierr);
29836c67d002SPeter Brune     }
29846c67d002SPeter Brune   }
29856c67d002SPeter Brune 
29867aaed0d8SBarry Smith   snes->setupcalled = PETSC_TRUE;
29873a40ed3dSBarry Smith   PetscFunctionReturn(0);
29889b94acceSBarry Smith }
29899b94acceSBarry Smith 
299037596af1SLisandro Dalcin /*@
299137596af1SLisandro Dalcin    SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats
299237596af1SLisandro Dalcin 
299337596af1SLisandro Dalcin    Collective on SNES
299437596af1SLisandro Dalcin 
299537596af1SLisandro Dalcin    Input Parameter:
299637596af1SLisandro Dalcin .  snes - iterative context obtained from SNESCreate()
299737596af1SLisandro Dalcin 
2998d25893d9SBarry Smith    Level: intermediate
2999d25893d9SBarry Smith 
300095452b02SPatrick Sanan    Notes:
300195452b02SPatrick Sanan     Also calls the application context destroy routine set with SNESSetComputeApplicationContext()
300237596af1SLisandro Dalcin 
300337596af1SLisandro Dalcin .keywords: SNES, destroy
300437596af1SLisandro Dalcin 
300537596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve()
300637596af1SLisandro Dalcin @*/
300737596af1SLisandro Dalcin PetscErrorCode  SNESReset(SNES snes)
300837596af1SLisandro Dalcin {
300937596af1SLisandro Dalcin   PetscErrorCode ierr;
301037596af1SLisandro Dalcin 
301137596af1SLisandro Dalcin   PetscFunctionBegin;
301237596af1SLisandro Dalcin   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3013d25893d9SBarry Smith   if (snes->ops->userdestroy && snes->user) {
3014d25893d9SBarry Smith     ierr       = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr);
30150298fd71SBarry Smith     snes->user = NULL;
3016d25893d9SBarry Smith   }
3017efd4aadfSBarry Smith   if (snes->npc) {
3018efd4aadfSBarry Smith     ierr = SNESReset(snes->npc);CHKERRQ(ierr);
30198a23116dSBarry Smith   }
30208a23116dSBarry Smith 
302137596af1SLisandro Dalcin   if (snes->ops->reset) {
302237596af1SLisandro Dalcin     ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr);
302337596af1SLisandro Dalcin   }
30249e764e56SPeter Brune   if (snes->ksp) {
30259e764e56SPeter Brune     ierr = KSPReset(snes->ksp);CHKERRQ(ierr);
30269e764e56SPeter Brune   }
30279e764e56SPeter Brune 
30289e764e56SPeter Brune   if (snes->linesearch) {
3029f1c6b773SPeter Brune     ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr);
30309e764e56SPeter Brune   }
30319e764e56SPeter Brune 
30326bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
30336bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
30346bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr);
30356bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
30366bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
30376bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
3038c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);
3039c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);
3040f5af7f23SKarl Rupp 
304140fdac6aSLawrence Mitchell   snes->alwayscomputesfinalresidual = PETSC_FALSE;
304240fdac6aSLawrence Mitchell 
304337596af1SLisandro Dalcin   snes->nwork       = snes->nvwork = 0;
304437596af1SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
304537596af1SLisandro Dalcin   PetscFunctionReturn(0);
304637596af1SLisandro Dalcin }
304737596af1SLisandro Dalcin 
304852baeb72SSatish Balay /*@
30499b94acceSBarry Smith    SNESDestroy - Destroys the nonlinear solver context that was created
30509b94acceSBarry Smith    with SNESCreate().
30519b94acceSBarry Smith 
3052c7afd0dbSLois Curfman McInnes    Collective on SNES
3053c7afd0dbSLois Curfman McInnes 
30549b94acceSBarry Smith    Input Parameter:
30559b94acceSBarry Smith .  snes - the SNES context
30569b94acceSBarry Smith 
305736851e7fSLois Curfman McInnes    Level: beginner
305836851e7fSLois Curfman McInnes 
30599b94acceSBarry Smith .keywords: SNES, nonlinear, destroy
30609b94acceSBarry Smith 
306163a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve()
30629b94acceSBarry Smith @*/
30636bf464f9SBarry Smith PetscErrorCode  SNESDestroy(SNES *snes)
30649b94acceSBarry Smith {
30656849ba73SBarry Smith   PetscErrorCode ierr;
30663a40ed3dSBarry Smith 
30673a40ed3dSBarry Smith   PetscFunctionBegin;
30686bf464f9SBarry Smith   if (!*snes) PetscFunctionReturn(0);
30696bf464f9SBarry Smith   PetscValidHeaderSpecific((*snes),SNES_CLASSID,1);
30706bf464f9SBarry Smith   if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);}
3071d4bb536fSBarry Smith 
30726bf464f9SBarry Smith   ierr = SNESReset((*snes));CHKERRQ(ierr);
3073efd4aadfSBarry Smith   ierr = SNESDestroy(&(*snes)->npc);CHKERRQ(ierr);
30746b8b9a38SLisandro Dalcin 
3075e04113cfSBarry Smith   /* if memory was published with SAWs then destroy it */
3076e04113cfSBarry Smith   ierr = PetscObjectSAWsViewOff((PetscObject)*snes);CHKERRQ(ierr);
30776bf464f9SBarry Smith   if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);}
30786d4c513bSLisandro Dalcin 
307933124788SMatthew G. Knepley   if ((*snes)->dm) {ierr = DMCoarsenHookRemove((*snes)->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,*snes);CHKERRQ(ierr);}
30806bf464f9SBarry Smith   ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr);
30816bf464f9SBarry Smith   ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr);
3082f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr);
30836b8b9a38SLisandro Dalcin 
30846bf464f9SBarry Smith   ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr);
30856bf464f9SBarry Smith   if ((*snes)->ops->convergeddestroy) {
30866bf464f9SBarry Smith     ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr);
30876b8b9a38SLisandro Dalcin   }
30886bf464f9SBarry Smith   if ((*snes)->conv_malloc) {
30896bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr);
30906bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr);
309158c9b817SLisandro Dalcin   }
30926bf464f9SBarry Smith   ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr);
3093a79aaaedSSatish Balay   ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr);
30943a40ed3dSBarry Smith   PetscFunctionReturn(0);
30959b94acceSBarry Smith }
30969b94acceSBarry Smith 
30979b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */
30989b94acceSBarry Smith 
3099a8054027SBarry Smith /*@
3100a8054027SBarry Smith    SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.
3101a8054027SBarry Smith 
31023f9fe445SBarry Smith    Logically Collective on SNES
3103a8054027SBarry Smith 
3104a8054027SBarry Smith    Input Parameters:
3105a8054027SBarry Smith +  snes - the SNES context
3106a8054027SBarry 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
31073b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
3108a8054027SBarry Smith 
3109a8054027SBarry Smith    Options Database Keys:
3110a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
3111a8054027SBarry Smith 
3112a8054027SBarry Smith    Notes:
3113a8054027SBarry Smith    The default is 1
3114a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
3115a8054027SBarry Smith    If  -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use
3116a8054027SBarry Smith 
3117a8054027SBarry Smith    Level: intermediate
3118a8054027SBarry Smith 
3119a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
3120a8054027SBarry Smith 
3121e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
3122a8054027SBarry Smith 
3123a8054027SBarry Smith @*/
31247087cfbeSBarry Smith PetscErrorCode  SNESSetLagPreconditioner(SNES snes,PetscInt lag)
3125a8054027SBarry Smith {
3126a8054027SBarry Smith   PetscFunctionBegin;
31270700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3128e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
3129e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
3130c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
3131a8054027SBarry Smith   snes->lagpreconditioner = lag;
3132a8054027SBarry Smith   PetscFunctionReturn(0);
3133a8054027SBarry Smith }
3134a8054027SBarry Smith 
3135efd51863SBarry Smith /*@
3136efd51863SBarry Smith    SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does
3137efd51863SBarry Smith 
3138efd51863SBarry Smith    Logically Collective on SNES
3139efd51863SBarry Smith 
3140efd51863SBarry Smith    Input Parameters:
3141efd51863SBarry Smith +  snes - the SNES context
3142efd51863SBarry Smith -  steps - the number of refinements to do, defaults to 0
3143efd51863SBarry Smith 
3144efd51863SBarry Smith    Options Database Keys:
3145efd51863SBarry Smith .    -snes_grid_sequence <steps>
3146efd51863SBarry Smith 
3147efd51863SBarry Smith    Level: intermediate
3148efd51863SBarry Smith 
3149c0df2a02SJed Brown    Notes:
3150c0df2a02SJed Brown    Use SNESGetSolution() to extract the fine grid solution after grid sequencing.
3151c0df2a02SJed Brown 
3152efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
3153efd51863SBarry Smith 
3154fa19ca70SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetGridSequence()
3155efd51863SBarry Smith 
3156efd51863SBarry Smith @*/
3157efd51863SBarry Smith PetscErrorCode  SNESSetGridSequence(SNES snes,PetscInt steps)
3158efd51863SBarry Smith {
3159efd51863SBarry Smith   PetscFunctionBegin;
3160efd51863SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3161efd51863SBarry Smith   PetscValidLogicalCollectiveInt(snes,steps,2);
3162efd51863SBarry Smith   snes->gridsequence = steps;
3163efd51863SBarry Smith   PetscFunctionReturn(0);
3164efd51863SBarry Smith }
3165efd51863SBarry Smith 
3166fa19ca70SBarry Smith /*@
3167fa19ca70SBarry Smith    SNESGetGridSequence - gets the number of steps of grid sequencing that SNES does
3168fa19ca70SBarry Smith 
3169fa19ca70SBarry Smith    Logically Collective on SNES
3170fa19ca70SBarry Smith 
3171fa19ca70SBarry Smith    Input Parameter:
3172fa19ca70SBarry Smith .  snes - the SNES context
3173fa19ca70SBarry Smith 
3174fa19ca70SBarry Smith    Output Parameter:
3175fa19ca70SBarry Smith .  steps - the number of refinements to do, defaults to 0
3176fa19ca70SBarry Smith 
3177fa19ca70SBarry Smith    Options Database Keys:
3178fa19ca70SBarry Smith .    -snes_grid_sequence <steps>
3179fa19ca70SBarry Smith 
3180fa19ca70SBarry Smith    Level: intermediate
3181fa19ca70SBarry Smith 
3182fa19ca70SBarry Smith    Notes:
3183fa19ca70SBarry Smith    Use SNESGetSolution() to extract the fine grid solution after grid sequencing.
3184fa19ca70SBarry Smith 
3185fa19ca70SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
3186fa19ca70SBarry Smith 
3187fa19ca70SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESSetGridSequence()
3188fa19ca70SBarry Smith 
3189fa19ca70SBarry Smith @*/
3190fa19ca70SBarry Smith PetscErrorCode  SNESGetGridSequence(SNES snes,PetscInt *steps)
3191fa19ca70SBarry Smith {
3192fa19ca70SBarry Smith   PetscFunctionBegin;
3193fa19ca70SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3194fa19ca70SBarry Smith   *steps = snes->gridsequence;
3195fa19ca70SBarry Smith   PetscFunctionReturn(0);
3196fa19ca70SBarry Smith }
3197fa19ca70SBarry Smith 
3198a8054027SBarry Smith /*@
3199a8054027SBarry Smith    SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt
3200a8054027SBarry Smith 
32013f9fe445SBarry Smith    Not Collective
3202a8054027SBarry Smith 
3203a8054027SBarry Smith    Input Parameter:
3204a8054027SBarry Smith .  snes - the SNES context
3205a8054027SBarry Smith 
3206a8054027SBarry Smith    Output Parameter:
3207a8054027SBarry 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
32083b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
3209a8054027SBarry Smith 
3210a8054027SBarry Smith    Options Database Keys:
3211a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
3212a8054027SBarry Smith 
3213a8054027SBarry Smith    Notes:
3214a8054027SBarry Smith    The default is 1
3215a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
3216a8054027SBarry Smith 
3217a8054027SBarry Smith    Level: intermediate
3218a8054027SBarry Smith 
3219a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
3220a8054027SBarry Smith 
3221a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner()
3222a8054027SBarry Smith 
3223a8054027SBarry Smith @*/
32247087cfbeSBarry Smith PetscErrorCode  SNESGetLagPreconditioner(SNES snes,PetscInt *lag)
3225a8054027SBarry Smith {
3226a8054027SBarry Smith   PetscFunctionBegin;
32270700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3228a8054027SBarry Smith   *lag = snes->lagpreconditioner;
3229a8054027SBarry Smith   PetscFunctionReturn(0);
3230a8054027SBarry Smith }
3231a8054027SBarry Smith 
3232e35cf81dSBarry Smith /*@
3233e35cf81dSBarry Smith    SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how
3234e35cf81dSBarry Smith      often the preconditioner is rebuilt.
3235e35cf81dSBarry Smith 
32363f9fe445SBarry Smith    Logically Collective on SNES
3237e35cf81dSBarry Smith 
3238e35cf81dSBarry Smith    Input Parameters:
3239e35cf81dSBarry Smith +  snes - the SNES context
3240e35cf81dSBarry 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
3241fe3ffe1eSBarry Smith          the Jacobian is built etc. -2 means rebuild at next chance but then never again
3242e35cf81dSBarry Smith 
3243e35cf81dSBarry Smith    Options Database Keys:
3244e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
3245e35cf81dSBarry Smith 
3246e35cf81dSBarry Smith    Notes:
3247e35cf81dSBarry Smith    The default is 1
3248e35cf81dSBarry Smith    The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
3249fe3ffe1eSBarry 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
3250fe3ffe1eSBarry Smith    at the next Newton step but never again (unless it is reset to another value)
3251e35cf81dSBarry Smith 
3252e35cf81dSBarry Smith    Level: intermediate
3253e35cf81dSBarry Smith 
3254e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
3255e35cf81dSBarry Smith 
3256e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian()
3257e35cf81dSBarry Smith 
3258e35cf81dSBarry Smith @*/
32597087cfbeSBarry Smith PetscErrorCode  SNESSetLagJacobian(SNES snes,PetscInt lag)
3260e35cf81dSBarry Smith {
3261e35cf81dSBarry Smith   PetscFunctionBegin;
32620700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3263e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
3264e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
3265c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
3266e35cf81dSBarry Smith   snes->lagjacobian = lag;
3267e35cf81dSBarry Smith   PetscFunctionReturn(0);
3268e35cf81dSBarry Smith }
3269e35cf81dSBarry Smith 
3270e35cf81dSBarry Smith /*@
3271e35cf81dSBarry Smith    SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt
3272e35cf81dSBarry Smith 
32733f9fe445SBarry Smith    Not Collective
3274e35cf81dSBarry Smith 
3275e35cf81dSBarry Smith    Input Parameter:
3276e35cf81dSBarry Smith .  snes - the SNES context
3277e35cf81dSBarry Smith 
3278e35cf81dSBarry Smith    Output Parameter:
3279e35cf81dSBarry 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
3280e35cf81dSBarry Smith          the Jacobian is built etc.
3281e35cf81dSBarry Smith 
3282e35cf81dSBarry Smith    Options Database Keys:
3283e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
3284e35cf81dSBarry Smith 
3285e35cf81dSBarry Smith    Notes:
3286e35cf81dSBarry Smith    The default is 1
3287e35cf81dSBarry Smith    The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
3288e35cf81dSBarry Smith 
3289e35cf81dSBarry Smith    Level: intermediate
3290e35cf81dSBarry Smith 
3291e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
3292e35cf81dSBarry Smith 
3293e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner()
3294e35cf81dSBarry Smith 
3295e35cf81dSBarry Smith @*/
32967087cfbeSBarry Smith PetscErrorCode  SNESGetLagJacobian(SNES snes,PetscInt *lag)
3297e35cf81dSBarry Smith {
3298e35cf81dSBarry Smith   PetscFunctionBegin;
32990700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3300e35cf81dSBarry Smith   *lag = snes->lagjacobian;
3301e35cf81dSBarry Smith   PetscFunctionReturn(0);
3302e35cf81dSBarry Smith }
3303e35cf81dSBarry Smith 
330437ec4e1aSPeter Brune /*@
330537ec4e1aSPeter Brune    SNESSetLagJacobianPersists - Set whether or not the Jacobian lagging persists through multiple solves
330637ec4e1aSPeter Brune 
330737ec4e1aSPeter Brune    Logically collective on SNES
330837ec4e1aSPeter Brune 
330937ec4e1aSPeter Brune    Input Parameter:
331037ec4e1aSPeter Brune +  snes - the SNES context
33119d7e2deaSPeter Brune -   flg - jacobian lagging persists if true
331237ec4e1aSPeter Brune 
331337ec4e1aSPeter Brune    Options Database Keys:
331437ec4e1aSPeter Brune .    -snes_lag_jacobian_persists <flg>
331537ec4e1aSPeter Brune 
331695452b02SPatrick Sanan    Notes:
331795452b02SPatrick Sanan     This is useful both for nonlinear preconditioning, where it's appropriate to have the Jacobian be stale by
331837ec4e1aSPeter Brune    several solves, and for implicit time-stepping, where Jacobian lagging in the inner nonlinear solve over several
331937ec4e1aSPeter Brune    timesteps may present huge efficiency gains.
332037ec4e1aSPeter Brune 
332137ec4e1aSPeter Brune    Level: developer
332237ec4e1aSPeter Brune 
3323be95d8f1SBarry Smith .keywords: SNES, nonlinear, lag
332437ec4e1aSPeter Brune 
3325be95d8f1SBarry Smith .seealso: SNESSetLagPreconditionerPersists(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetNPC()
332637ec4e1aSPeter Brune 
332737ec4e1aSPeter Brune @*/
332837ec4e1aSPeter Brune PetscErrorCode  SNESSetLagJacobianPersists(SNES snes,PetscBool flg)
332937ec4e1aSPeter Brune {
333037ec4e1aSPeter Brune   PetscFunctionBegin;
333137ec4e1aSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
333237ec4e1aSPeter Brune   PetscValidLogicalCollectiveBool(snes,flg,2);
333337ec4e1aSPeter Brune   snes->lagjac_persist = flg;
333437ec4e1aSPeter Brune   PetscFunctionReturn(0);
333537ec4e1aSPeter Brune }
333637ec4e1aSPeter Brune 
333737ec4e1aSPeter Brune /*@
333837ec4e1aSPeter Brune    SNESSetLagPreconditionerPersists - Set whether or not the preconditioner lagging persists through multiple solves
333937ec4e1aSPeter Brune 
334037ec4e1aSPeter Brune    Logically Collective on SNES
334137ec4e1aSPeter Brune 
334237ec4e1aSPeter Brune    Input Parameter:
334337ec4e1aSPeter Brune +  snes - the SNES context
33449d7e2deaSPeter Brune -   flg - preconditioner lagging persists if true
334537ec4e1aSPeter Brune 
334637ec4e1aSPeter Brune    Options Database Keys:
334737ec4e1aSPeter Brune .    -snes_lag_jacobian_persists <flg>
334837ec4e1aSPeter Brune 
334995452b02SPatrick Sanan    Notes:
335095452b02SPatrick Sanan     This is useful both for nonlinear preconditioning, where it's appropriate to have the preconditioner be stale
335137ec4e1aSPeter Brune    by several solves, and for implicit time-stepping, where preconditioner lagging in the inner nonlinear solve over
335237ec4e1aSPeter Brune    several timesteps may present huge efficiency gains.
335337ec4e1aSPeter Brune 
335437ec4e1aSPeter Brune    Level: developer
335537ec4e1aSPeter Brune 
3356be95d8f1SBarry Smith .keywords: SNES, nonlinear, lag
335737ec4e1aSPeter Brune 
3358be95d8f1SBarry Smith .seealso: SNESSetLagJacobianPersists(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetNPC()
335937ec4e1aSPeter Brune 
336037ec4e1aSPeter Brune @*/
336137ec4e1aSPeter Brune PetscErrorCode  SNESSetLagPreconditionerPersists(SNES snes,PetscBool flg)
336237ec4e1aSPeter Brune {
336337ec4e1aSPeter Brune   PetscFunctionBegin;
336437ec4e1aSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
336537ec4e1aSPeter Brune   PetscValidLogicalCollectiveBool(snes,flg,2);
336637ec4e1aSPeter Brune   snes->lagpre_persist = flg;
336737ec4e1aSPeter Brune   PetscFunctionReturn(0);
336837ec4e1aSPeter Brune }
336937ec4e1aSPeter Brune 
33709b94acceSBarry Smith /*@
3371be5caee7SBarry Smith    SNESSetForceIteration - force SNESSolve() to take at least one iteration regardless of the initial residual norm
3372be5caee7SBarry Smith 
3373be5caee7SBarry Smith    Logically Collective on SNES
3374be5caee7SBarry Smith 
3375be5caee7SBarry Smith    Input Parameters:
3376be5caee7SBarry Smith +  snes - the SNES context
3377be5caee7SBarry Smith -  force - PETSC_TRUE require at least one iteration
3378be5caee7SBarry Smith 
3379be5caee7SBarry Smith    Options Database Keys:
3380be5caee7SBarry Smith .    -snes_force_iteration <force> - Sets forcing an iteration
3381be5caee7SBarry Smith 
3382be5caee7SBarry Smith    Notes:
3383be5caee7SBarry Smith    This is used sometimes with TS to prevent TS from detecting a false steady state solution
3384be5caee7SBarry Smith 
3385be5caee7SBarry Smith    Level: intermediate
3386be5caee7SBarry Smith 
3387be5caee7SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
3388be5caee7SBarry Smith 
3389be5caee7SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetDivergenceTolerance()
3390be5caee7SBarry Smith @*/
3391be5caee7SBarry Smith PetscErrorCode  SNESSetForceIteration(SNES snes,PetscBool force)
3392be5caee7SBarry Smith {
3393be5caee7SBarry Smith   PetscFunctionBegin;
3394be5caee7SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3395be5caee7SBarry Smith   snes->forceiteration = force;
3396be5caee7SBarry Smith   PetscFunctionReturn(0);
3397be5caee7SBarry Smith }
3398be5caee7SBarry Smith 
339985216dc7SFande Kong /*@
340085216dc7SFande Kong    SNESGetForceIteration - Whether or not to force SNESSolve() take at least one iteration regardless of the initial residual norm
340185216dc7SFande Kong 
340285216dc7SFande Kong    Logically Collective on SNES
340385216dc7SFande Kong 
340485216dc7SFande Kong    Input Parameters:
340585216dc7SFande Kong .  snes - the SNES context
340685216dc7SFande Kong 
340785216dc7SFande Kong    Output Parameter:
340885216dc7SFande Kong .  force - PETSC_TRUE requires at least one iteration.
340985216dc7SFande Kong 
341085216dc7SFande Kong .keywords: SNES, nonlinear, set, convergence, tolerances
341185216dc7SFande Kong 
341206dd6b0eSSatish Balay    Level: intermediate
341306dd6b0eSSatish Balay 
341485216dc7SFande Kong .seealso: SNESSetForceIteration(), SNESSetTrustRegionTolerance(), SNESSetDivergenceTolerance()
341585216dc7SFande Kong @*/
341685216dc7SFande Kong PetscErrorCode  SNESGetForceIteration(SNES snes,PetscBool *force)
341785216dc7SFande Kong {
341885216dc7SFande Kong   PetscFunctionBegin;
341985216dc7SFande Kong   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
342085216dc7SFande Kong   *force = snes->forceiteration;
342185216dc7SFande Kong   PetscFunctionReturn(0);
342285216dc7SFande Kong }
3423be5caee7SBarry Smith 
3424be5caee7SBarry Smith /*@
3425d7a720efSLois Curfman McInnes    SNESSetTolerances - Sets various parameters used in convergence tests.
34269b94acceSBarry Smith 
34273f9fe445SBarry Smith    Logically Collective on SNES
3428c7afd0dbSLois Curfman McInnes 
34299b94acceSBarry Smith    Input Parameters:
3430c7afd0dbSLois Curfman McInnes +  snes - the SNES context
343170441072SBarry Smith .  abstol - absolute convergence tolerance
343233174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
34335358d0d4SBarry Smith .  stol -  convergence tolerance in terms of the norm of the change in the solution between steps,  || delta x || < stol*|| x ||
343433174efeSLois Curfman McInnes .  maxit - maximum number of iterations
3435e71169deSBarry Smith -  maxf - maximum number of function evaluations (-1 indicates no limit)
3436fee21e36SBarry Smith 
343733174efeSLois Curfman McInnes    Options Database Keys:
343870441072SBarry Smith +    -snes_atol <abstol> - Sets abstol
3439c7afd0dbSLois Curfman McInnes .    -snes_rtol <rtol> - Sets rtol
3440c7afd0dbSLois Curfman McInnes .    -snes_stol <stol> - Sets stol
3441c7afd0dbSLois Curfman McInnes .    -snes_max_it <maxit> - Sets maxit
3442c7afd0dbSLois Curfman McInnes -    -snes_max_funcs <maxf> - Sets maxf
34439b94acceSBarry Smith 
3444d7a720efSLois Curfman McInnes    Notes:
34459b94acceSBarry Smith    The default maximum number of iterations is 50.
34469b94acceSBarry Smith    The default maximum number of function evaluations is 1000.
34479b94acceSBarry Smith 
344836851e7fSLois Curfman McInnes    Level: intermediate
344936851e7fSLois Curfman McInnes 
345033174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances
34519b94acceSBarry Smith 
3452be5caee7SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetDivergenceTolerance(), SNESSetForceIteration()
34539b94acceSBarry Smith @*/
34547087cfbeSBarry Smith PetscErrorCode  SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
34559b94acceSBarry Smith {
34563a40ed3dSBarry Smith   PetscFunctionBegin;
34570700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3458c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,abstol,2);
3459c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol,3);
3460c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,stol,4);
3461c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxit,5);
3462c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxf,6);
3463c5eb9154SBarry Smith 
3464ab54825eSJed Brown   if (abstol != PETSC_DEFAULT) {
346557622a8eSBarry Smith     if (abstol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %g must be non-negative",(double)abstol);
3466ab54825eSJed Brown     snes->abstol = abstol;
3467ab54825eSJed Brown   }
3468ab54825eSJed Brown   if (rtol != PETSC_DEFAULT) {
346957622a8eSBarry Smith     if (rtol < 0.0 || 1.0 <= rtol) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Relative tolerance %g must be non-negative and less than 1.0",(double)rtol);
3470ab54825eSJed Brown     snes->rtol = rtol;
3471ab54825eSJed Brown   }
3472ab54825eSJed Brown   if (stol != PETSC_DEFAULT) {
347357622a8eSBarry Smith     if (stol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %g must be non-negative",(double)stol);
3474c60f73f4SPeter Brune     snes->stol = stol;
3475ab54825eSJed Brown   }
3476ab54825eSJed Brown   if (maxit != PETSC_DEFAULT) {
3477ce94432eSBarry Smith     if (maxit < 0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit);
3478ab54825eSJed Brown     snes->max_its = maxit;
3479ab54825eSJed Brown   }
3480ab54825eSJed Brown   if (maxf != PETSC_DEFAULT) {
3481e71169deSBarry Smith     if (maxf < -1) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be -1 or nonnegative",maxf);
3482ab54825eSJed Brown     snes->max_funcs = maxf;
3483ab54825eSJed Brown   }
348488976e71SPeter Brune   snes->tolerancesset = PETSC_TRUE;
34853a40ed3dSBarry Smith   PetscFunctionReturn(0);
34869b94acceSBarry Smith }
34879b94acceSBarry Smith 
3488e4d06f11SPatrick Farrell /*@
3489e4d06f11SPatrick Farrell    SNESSetDivergenceTolerance - Sets the divergence tolerance used for the SNES divergence test.
3490e4d06f11SPatrick Farrell 
3491e4d06f11SPatrick Farrell    Logically Collective on SNES
3492e4d06f11SPatrick Farrell 
3493e4d06f11SPatrick Farrell    Input Parameters:
3494e4d06f11SPatrick Farrell +  snes - the SNES context
3495e4d06f11SPatrick Farrell -  divtol - the divergence tolerance. Use -1 to deactivate the test.
3496e4d06f11SPatrick Farrell 
3497e4d06f11SPatrick Farrell    Options Database Keys:
3498e4d06f11SPatrick Farrell +    -snes_divergence_tolerance <divtol> - Sets divtol
3499e4d06f11SPatrick Farrell 
3500e4d06f11SPatrick Farrell    Notes:
3501e4d06f11SPatrick Farrell    The default divergence tolerance is 1e4.
3502e4d06f11SPatrick Farrell 
3503e4d06f11SPatrick Farrell    Level: intermediate
3504e4d06f11SPatrick Farrell 
3505e4d06f11SPatrick Farrell .keywords: SNES, nonlinear, set, divergence, tolerance
3506e4d06f11SPatrick Farrell 
3507e4d06f11SPatrick Farrell .seealso: SNESSetTolerances(), SNESGetDivergenceTolerance
3508e4d06f11SPatrick Farrell @*/
3509e4d06f11SPatrick Farrell PetscErrorCode  SNESSetDivergenceTolerance(SNES snes,PetscReal divtol)
3510e4d06f11SPatrick Farrell {
3511e4d06f11SPatrick Farrell   PetscFunctionBegin;
3512e4d06f11SPatrick Farrell   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3513e4d06f11SPatrick Farrell   PetscValidLogicalCollectiveReal(snes,divtol,2);
3514e4d06f11SPatrick Farrell 
3515e4d06f11SPatrick Farrell   if (divtol != PETSC_DEFAULT) {
3516e4d06f11SPatrick Farrell     snes->divtol = divtol;
3517e4d06f11SPatrick Farrell   }
3518e4d06f11SPatrick Farrell   else {
3519e4d06f11SPatrick Farrell     snes->divtol = 1.0e4;
3520e4d06f11SPatrick Farrell   }
3521e4d06f11SPatrick Farrell   PetscFunctionReturn(0);
3522e4d06f11SPatrick Farrell }
3523e4d06f11SPatrick Farrell 
35249b94acceSBarry Smith /*@
352533174efeSLois Curfman McInnes    SNESGetTolerances - Gets various parameters used in convergence tests.
352633174efeSLois Curfman McInnes 
3527c7afd0dbSLois Curfman McInnes    Not Collective
3528c7afd0dbSLois Curfman McInnes 
352933174efeSLois Curfman McInnes    Input Parameters:
3530c7afd0dbSLois Curfman McInnes +  snes - the SNES context
353185385478SLisandro Dalcin .  atol - absolute convergence tolerance
353233174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
353333174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
353433174efeSLois Curfman McInnes            of the change in the solution between steps
353533174efeSLois Curfman McInnes .  maxit - maximum number of iterations
3536c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
3537fee21e36SBarry Smith 
353833174efeSLois Curfman McInnes    Notes:
35390298fd71SBarry Smith    The user can specify NULL for any parameter that is not needed.
354033174efeSLois Curfman McInnes 
354136851e7fSLois Curfman McInnes    Level: intermediate
354236851e7fSLois Curfman McInnes 
354333174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances
354433174efeSLois Curfman McInnes 
354533174efeSLois Curfman McInnes .seealso: SNESSetTolerances()
354633174efeSLois Curfman McInnes @*/
35477087cfbeSBarry Smith PetscErrorCode  SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
354833174efeSLois Curfman McInnes {
35493a40ed3dSBarry Smith   PetscFunctionBegin;
35500700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
355185385478SLisandro Dalcin   if (atol)  *atol  = snes->abstol;
355233174efeSLois Curfman McInnes   if (rtol)  *rtol  = snes->rtol;
3553c60f73f4SPeter Brune   if (stol)  *stol  = snes->stol;
355433174efeSLois Curfman McInnes   if (maxit) *maxit = snes->max_its;
355533174efeSLois Curfman McInnes   if (maxf)  *maxf  = snes->max_funcs;
35563a40ed3dSBarry Smith   PetscFunctionReturn(0);
355733174efeSLois Curfman McInnes }
355833174efeSLois Curfman McInnes 
3559e4d06f11SPatrick Farrell /*@
3560e4d06f11SPatrick Farrell    SNESGetDivergenceTolerance - Gets divergence tolerance used in divergence test.
3561e4d06f11SPatrick Farrell 
3562e4d06f11SPatrick Farrell    Not Collective
3563e4d06f11SPatrick Farrell 
3564e4d06f11SPatrick Farrell    Input Parameters:
3565e4d06f11SPatrick Farrell +  snes - the SNES context
3566e4d06f11SPatrick Farrell -  divtol - divergence tolerance
3567e4d06f11SPatrick Farrell 
3568e4d06f11SPatrick Farrell    Level: intermediate
3569e4d06f11SPatrick Farrell 
3570e4d06f11SPatrick Farrell .keywords: SNES, nonlinear, get, divergence, tolerance
3571e4d06f11SPatrick Farrell 
3572e4d06f11SPatrick Farrell .seealso: SNESSetDivergenceTolerance()
3573e4d06f11SPatrick Farrell @*/
3574e4d06f11SPatrick Farrell PetscErrorCode  SNESGetDivergenceTolerance(SNES snes,PetscReal *divtol)
3575e4d06f11SPatrick Farrell {
3576e4d06f11SPatrick Farrell   PetscFunctionBegin;
3577e4d06f11SPatrick Farrell   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3578e4d06f11SPatrick Farrell   if (divtol) *divtol = snes->divtol;
3579e4d06f11SPatrick Farrell   PetscFunctionReturn(0);
3580e4d06f11SPatrick Farrell }
3581e4d06f11SPatrick Farrell 
358233174efeSLois Curfman McInnes /*@
35839b94acceSBarry Smith    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
35849b94acceSBarry Smith 
35853f9fe445SBarry Smith    Logically Collective on SNES
3586fee21e36SBarry Smith 
3587c7afd0dbSLois Curfman McInnes    Input Parameters:
3588c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3589c7afd0dbSLois Curfman McInnes -  tol - tolerance
3590c7afd0dbSLois Curfman McInnes 
35919b94acceSBarry Smith    Options Database Key:
3592c7afd0dbSLois Curfman McInnes .  -snes_trtol <tol> - Sets tol
35939b94acceSBarry Smith 
359436851e7fSLois Curfman McInnes    Level: intermediate
359536851e7fSLois Curfman McInnes 
35969b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance
35979b94acceSBarry Smith 
35982492ecdbSBarry Smith .seealso: SNESSetTolerances()
35999b94acceSBarry Smith @*/
36007087cfbeSBarry Smith PetscErrorCode  SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
36019b94acceSBarry Smith {
36023a40ed3dSBarry Smith   PetscFunctionBegin;
36030700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3604c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,tol,2);
36059b94acceSBarry Smith   snes->deltatol = tol;
36063a40ed3dSBarry Smith   PetscFunctionReturn(0);
36079b94acceSBarry Smith }
36089b94acceSBarry Smith 
3609df9fa365SBarry Smith /*
3610df9fa365SBarry Smith    Duplicate the lg monitors for SNES from KSP; for some reason with
3611df9fa365SBarry Smith    dynamic libraries things don't work under Sun4 if we just use
3612df9fa365SBarry Smith    macros instead of functions
3613df9fa365SBarry Smith */
3614d96771aaSLisandro Dalcin PetscErrorCode  SNESMonitorLGResidualNorm(SNES snes,PetscInt it,PetscReal norm,void *ctx)
3615ce1608b8SBarry Smith {
3616dfbe8321SBarry Smith   PetscErrorCode ierr;
3617ce1608b8SBarry Smith 
3618ce1608b8SBarry Smith   PetscFunctionBegin;
36190700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3620d96771aaSLisandro Dalcin   ierr = KSPMonitorLGResidualNorm((KSP)snes,it,norm,ctx);CHKERRQ(ierr);
3621ce1608b8SBarry Smith   PetscFunctionReturn(0);
3622ce1608b8SBarry Smith }
3623ce1608b8SBarry Smith 
3624d96771aaSLisandro Dalcin PetscErrorCode  SNESMonitorLGCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *lgctx)
3625df9fa365SBarry Smith {
3626dfbe8321SBarry Smith   PetscErrorCode ierr;
3627df9fa365SBarry Smith 
3628df9fa365SBarry Smith   PetscFunctionBegin;
3629d96771aaSLisandro Dalcin   ierr = KSPMonitorLGResidualNormCreate(comm,host,label,x,y,m,n,lgctx);CHKERRQ(ierr);
3630df9fa365SBarry Smith   PetscFunctionReturn(0);
3631df9fa365SBarry Smith }
3632df9fa365SBarry Smith 
36336ba87a44SLisandro Dalcin PETSC_INTERN PetscErrorCode  SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
36346ba87a44SLisandro Dalcin 
36357087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx)
3636b271bb04SBarry Smith {
3637b271bb04SBarry Smith   PetscDrawLG      lg;
3638b271bb04SBarry Smith   PetscErrorCode   ierr;
3639b271bb04SBarry Smith   PetscReal        x,y,per;
3640b271bb04SBarry Smith   PetscViewer      v = (PetscViewer)monctx;
3641b271bb04SBarry Smith   static PetscReal prev; /* should be in the context */
3642b271bb04SBarry Smith   PetscDraw        draw;
3643b271bb04SBarry Smith 
3644459f5d12SBarry Smith   PetscFunctionBegin;
36454d4332d5SBarry Smith   PetscValidHeaderSpecific(v,PETSC_VIEWER_CLASSID,4);
3646b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr);
3647b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
3648b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
3649b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr);
3650b271bb04SBarry Smith   x    = (PetscReal)n;
365177b4d14cSPeter Brune   if (rnorm > 0.0) y = PetscLog10Real(rnorm);
365294c9c6d3SKarl Rupp   else y = -15.0;
3653b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
36546934998bSLisandro Dalcin   if (n < 20 || !(n % 5) || snes->reason) {
3655b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
36566934998bSLisandro Dalcin     ierr = PetscDrawLGSave(lg);CHKERRQ(ierr);
3657b271bb04SBarry Smith   }
3658b271bb04SBarry Smith 
3659b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr);
3660b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
3661b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
3662b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr);
3663b271bb04SBarry Smith   ierr =  SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr);
3664b271bb04SBarry Smith   x    = (PetscReal)n;
3665b271bb04SBarry Smith   y    = 100.0*per;
3666b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
36676934998bSLisandro Dalcin   if (n < 20 || !(n % 5) || snes->reason) {
3668b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
36696934998bSLisandro Dalcin     ierr = PetscDrawLGSave(lg);CHKERRQ(ierr);
3670b271bb04SBarry Smith   }
3671b271bb04SBarry Smith 
3672b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr);
3673b271bb04SBarry Smith   if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
3674b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
3675b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr);
3676b271bb04SBarry Smith   x    = (PetscReal)n;
3677b271bb04SBarry Smith   y    = (prev - rnorm)/prev;
3678b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
36796934998bSLisandro Dalcin   if (n < 20 || !(n % 5) || snes->reason) {
3680b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
36816934998bSLisandro Dalcin     ierr = PetscDrawLGSave(lg);CHKERRQ(ierr);
3682b271bb04SBarry Smith   }
3683b271bb04SBarry Smith 
3684b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr);
3685b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
3686b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
3687b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr);
3688b271bb04SBarry Smith   x    = (PetscReal)n;
3689b271bb04SBarry Smith   y    = (prev - rnorm)/(prev*per);
3690b271bb04SBarry Smith   if (n > 2) { /*skip initial crazy value */
3691b271bb04SBarry Smith     ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
3692b271bb04SBarry Smith   }
36936934998bSLisandro Dalcin   if (n < 20 || !(n % 5) || snes->reason) {
3694b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
36956934998bSLisandro Dalcin     ierr = PetscDrawLGSave(lg);CHKERRQ(ierr);
3696b271bb04SBarry Smith   }
3697b271bb04SBarry Smith   prev = rnorm;
3698b271bb04SBarry Smith   PetscFunctionReturn(0);
3699b271bb04SBarry Smith }
3700b271bb04SBarry Smith 
3701228d79bcSJed Brown /*@
3702228d79bcSJed Brown    SNESMonitor - runs the user provided monitor routines, if they exist
3703228d79bcSJed Brown 
3704228d79bcSJed Brown    Collective on SNES
3705228d79bcSJed Brown 
3706228d79bcSJed Brown    Input Parameters:
3707228d79bcSJed Brown +  snes - nonlinear solver context obtained from SNESCreate()
3708228d79bcSJed Brown .  iter - iteration number
3709228d79bcSJed Brown -  rnorm - relative norm of the residual
3710228d79bcSJed Brown 
3711228d79bcSJed Brown    Notes:
3712228d79bcSJed Brown    This routine is called by the SNES implementations.
3713228d79bcSJed Brown    It does not typically need to be called by the user.
3714228d79bcSJed Brown 
3715228d79bcSJed Brown    Level: developer
3716228d79bcSJed Brown 
3717228d79bcSJed Brown .seealso: SNESMonitorSet()
3718228d79bcSJed Brown @*/
37197a03ce2fSLisandro Dalcin PetscErrorCode  SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm)
37207a03ce2fSLisandro Dalcin {
37217a03ce2fSLisandro Dalcin   PetscErrorCode ierr;
37227a03ce2fSLisandro Dalcin   PetscInt       i,n = snes->numbermonitors;
37237a03ce2fSLisandro Dalcin 
37247a03ce2fSLisandro Dalcin   PetscFunctionBegin;
37255edff71fSBarry Smith   ierr = VecLockPush(snes->vec_sol);CHKERRQ(ierr);
37267a03ce2fSLisandro Dalcin   for (i=0; i<n; i++) {
37277a03ce2fSLisandro Dalcin     ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr);
37287a03ce2fSLisandro Dalcin   }
37295edff71fSBarry Smith   ierr = VecLockPop(snes->vec_sol);CHKERRQ(ierr);
37307a03ce2fSLisandro Dalcin   PetscFunctionReturn(0);
37317a03ce2fSLisandro Dalcin }
37327a03ce2fSLisandro Dalcin 
37339b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */
37349b94acceSBarry Smith 
3735bf388a1fSBarry Smith /*MC
3736bf388a1fSBarry Smith     SNESMonitorFunction - functional form passed to SNESMonitorSet() to monitor convergence of nonlinear solver
3737bf388a1fSBarry Smith 
3738bf388a1fSBarry Smith      Synopsis:
3739aaa7dc30SBarry Smith      #include <petscsnes.h>
3740bf388a1fSBarry Smith $    PetscErrorCode SNESMonitorFunction(SNES snes,PetscInt its, PetscReal norm,void *mctx)
3741bf388a1fSBarry Smith 
3742bf388a1fSBarry Smith +    snes - the SNES context
3743bf388a1fSBarry Smith .    its - iteration number
3744bf388a1fSBarry Smith .    norm - 2-norm function value (may be estimated)
3745bf388a1fSBarry Smith -    mctx - [optional] monitoring context
3746bf388a1fSBarry Smith 
3747878cb397SSatish Balay    Level: advanced
3748878cb397SSatish Balay 
3749bf388a1fSBarry Smith .seealso:   SNESMonitorSet(), SNESMonitorGet()
3750bf388a1fSBarry Smith M*/
3751bf388a1fSBarry Smith 
37529b94acceSBarry Smith /*@C
3753a6570f20SBarry Smith    SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
37549b94acceSBarry Smith    iteration of the nonlinear solver to display the iteration's
37559b94acceSBarry Smith    progress.
37569b94acceSBarry Smith 
37573f9fe445SBarry Smith    Logically Collective on SNES
3758fee21e36SBarry Smith 
3759c7afd0dbSLois Curfman McInnes    Input Parameters:
3760c7afd0dbSLois Curfman McInnes +  snes - the SNES context
37616e4dcb14SBarry Smith .  f - the monitor function, see SNESMonitorFunction for the calling sequence
3762b8a78c4aSBarry Smith .  mctx - [optional] user-defined context for private data for the
37630298fd71SBarry Smith           monitor routine (use NULL if no context is desired)
3764b3006f0bSLois Curfman McInnes -  monitordestroy - [optional] routine that frees monitor context
37650298fd71SBarry Smith           (may be NULL)
37669b94acceSBarry Smith 
37679665c990SLois Curfman McInnes    Options Database Keys:
3768a6570f20SBarry Smith +    -snes_monitor        - sets SNESMonitorDefault()
37694619e776SBarry Smith .    -snes_monitor_lg_residualnorm    - sets line graph monitor,
3770a6570f20SBarry Smith                             uses SNESMonitorLGCreate()
3771cca6129bSJed Brown -    -snes_monitor_cancel - cancels all monitors that have
3772c7afd0dbSLois Curfman McInnes                             been hardwired into a code by
3773a6570f20SBarry Smith                             calls to SNESMonitorSet(), but
3774c7afd0dbSLois Curfman McInnes                             does not cancel those set via
3775c7afd0dbSLois Curfman McInnes                             the options database.
37769665c990SLois Curfman McInnes 
3777639f9d9dSBarry Smith    Notes:
37786bc08f3fSLois Curfman McInnes    Several different monitoring routines may be set by calling
3779a6570f20SBarry Smith    SNESMonitorSet() multiple times; all will be called in the
37806bc08f3fSLois Curfman McInnes    order in which they were set.
3781639f9d9dSBarry Smith 
378295452b02SPatrick Sanan    Fortran Notes:
378395452b02SPatrick Sanan     Only a single monitor function can be set for each SNES object
3784025f1a04SBarry Smith 
378536851e7fSLois Curfman McInnes    Level: intermediate
378636851e7fSLois Curfman McInnes 
37879b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor
37889b94acceSBarry Smith 
3789bf388a1fSBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel(), SNESMonitorFunction
37909b94acceSBarry Smith @*/
37916e4dcb14SBarry Smith PetscErrorCode  SNESMonitorSet(SNES snes,PetscErrorCode (*f)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
37929b94acceSBarry Smith {
3793b90d0a6eSBarry Smith   PetscInt       i;
3794649052a6SBarry Smith   PetscErrorCode ierr;
379578064530SBarry Smith   PetscBool      identical;
3796b90d0a6eSBarry Smith 
37973a40ed3dSBarry Smith   PetscFunctionBegin;
37980700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3799b90d0a6eSBarry Smith   for (i=0; i<snes->numbermonitors;i++) {
380078064530SBarry Smith     ierr = PetscMonitorCompare((PetscErrorCode (*)(void))f,mctx,monitordestroy,(PetscErrorCode (*)(void))snes->monitor[i],snes->monitorcontext[i],snes->monitordestroy[i],&identical);CHKERRQ(ierr);
380178064530SBarry Smith     if (identical) PetscFunctionReturn(0);
3802649052a6SBarry Smith   }
380378064530SBarry Smith   if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
38046e4dcb14SBarry Smith   snes->monitor[snes->numbermonitors]          = f;
3805b8a78c4aSBarry Smith   snes->monitordestroy[snes->numbermonitors]   = monitordestroy;
3806639f9d9dSBarry Smith   snes->monitorcontext[snes->numbermonitors++] = (void*)mctx;
38073a40ed3dSBarry Smith   PetscFunctionReturn(0);
38089b94acceSBarry Smith }
38099b94acceSBarry Smith 
3810a278d85bSSatish Balay /*@
3811a6570f20SBarry Smith    SNESMonitorCancel - Clears all the monitor functions for a SNES object.
38125cd90555SBarry Smith 
38133f9fe445SBarry Smith    Logically Collective on SNES
3814c7afd0dbSLois Curfman McInnes 
38155cd90555SBarry Smith    Input Parameters:
38165cd90555SBarry Smith .  snes - the SNES context
38175cd90555SBarry Smith 
38181a480d89SAdministrator    Options Database Key:
3819a6570f20SBarry Smith .  -snes_monitor_cancel - cancels all monitors that have been hardwired
3820a6570f20SBarry Smith     into a code by calls to SNESMonitorSet(), but does not cancel those
3821c7afd0dbSLois Curfman McInnes     set via the options database
38225cd90555SBarry Smith 
38235cd90555SBarry Smith    Notes:
38245cd90555SBarry Smith    There is no way to clear one specific monitor from a SNES object.
38255cd90555SBarry Smith 
382636851e7fSLois Curfman McInnes    Level: intermediate
382736851e7fSLois Curfman McInnes 
38285cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor
38295cd90555SBarry Smith 
3830a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet()
38315cd90555SBarry Smith @*/
38327087cfbeSBarry Smith PetscErrorCode  SNESMonitorCancel(SNES snes)
38335cd90555SBarry Smith {
3834d952e501SBarry Smith   PetscErrorCode ierr;
3835d952e501SBarry Smith   PetscInt       i;
3836d952e501SBarry Smith 
38375cd90555SBarry Smith   PetscFunctionBegin;
38380700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3839d952e501SBarry Smith   for (i=0; i<snes->numbermonitors; i++) {
3840d952e501SBarry Smith     if (snes->monitordestroy[i]) {
38413c4aec1bSBarry Smith       ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr);
3842d952e501SBarry Smith     }
3843d952e501SBarry Smith   }
38445cd90555SBarry Smith   snes->numbermonitors = 0;
38455cd90555SBarry Smith   PetscFunctionReturn(0);
38465cd90555SBarry Smith }
38475cd90555SBarry Smith 
3848bf388a1fSBarry Smith /*MC
3849bf388a1fSBarry Smith     SNESConvergenceTestFunction - functional form used for testing of convergence of nonlinear solver
3850bf388a1fSBarry Smith 
3851bf388a1fSBarry Smith      Synopsis:
3852aaa7dc30SBarry Smith      #include <petscsnes.h>
3853bf388a1fSBarry Smith $     PetscErrorCode SNESConvergenceTest(SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
3854bf388a1fSBarry Smith 
3855bf388a1fSBarry Smith +    snes - the SNES context
3856bf388a1fSBarry Smith .    it - current iteration (0 is the first and is before any Newton step)
3857bf388a1fSBarry Smith .    cctx - [optional] convergence context
3858bf388a1fSBarry Smith .    reason - reason for convergence/divergence
3859bf388a1fSBarry Smith .    xnorm - 2-norm of current iterate
3860bf388a1fSBarry Smith .    gnorm - 2-norm of current step
3861bf388a1fSBarry Smith -    f - 2-norm of function
3862bf388a1fSBarry Smith 
3863878cb397SSatish Balay    Level: intermediate
3864bf388a1fSBarry Smith 
3865bf388a1fSBarry Smith .seealso:   SNESSetConvergenceTest(), SNESGetConvergenceTest()
3866bf388a1fSBarry Smith M*/
3867bf388a1fSBarry Smith 
38689b94acceSBarry Smith /*@C
38699b94acceSBarry Smith    SNESSetConvergenceTest - Sets the function that is to be used
38709b94acceSBarry Smith    to test for convergence of the nonlinear iterative solution.
38719b94acceSBarry Smith 
38723f9fe445SBarry Smith    Logically Collective on SNES
3873fee21e36SBarry Smith 
3874c7afd0dbSLois Curfman McInnes    Input Parameters:
3875c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3876bf388a1fSBarry Smith .  SNESConvergenceTestFunction - routine to test for convergence
38770298fd71SBarry Smith .  cctx - [optional] context for private data for the convergence routine  (may be NULL)
38780298fd71SBarry Smith -  destroy - [optional] destructor for the context (may be NULL; NULL_FUNCTION in Fortran)
38799b94acceSBarry Smith 
388036851e7fSLois Curfman McInnes    Level: advanced
388136851e7fSLois Curfman McInnes 
38829b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test
38839b94acceSBarry Smith 
3884e2a6519dSDmitry Karpeev .seealso: SNESConvergedDefault(), SNESConvergedSkip(), SNESConvergenceTestFunction
38859b94acceSBarry Smith @*/
3886bf388a1fSBarry Smith PetscErrorCode  SNESSetConvergenceTest(SNES snes,PetscErrorCode (*SNESConvergenceTestFunction)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
38879b94acceSBarry Smith {
38887f7931b9SBarry Smith   PetscErrorCode ierr;
38897f7931b9SBarry Smith 
38903a40ed3dSBarry Smith   PetscFunctionBegin;
38910700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3892e2a6519dSDmitry Karpeev   if (!SNESConvergenceTestFunction) SNESConvergenceTestFunction = SNESConvergedSkip;
38937f7931b9SBarry Smith   if (snes->ops->convergeddestroy) {
38947f7931b9SBarry Smith     ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr);
38957f7931b9SBarry Smith   }
3896bf388a1fSBarry Smith   snes->ops->converged        = SNESConvergenceTestFunction;
38977f7931b9SBarry Smith   snes->ops->convergeddestroy = destroy;
389885385478SLisandro Dalcin   snes->cnvP                  = cctx;
38993a40ed3dSBarry Smith   PetscFunctionReturn(0);
39009b94acceSBarry Smith }
39019b94acceSBarry Smith 
390252baeb72SSatish Balay /*@
3903184914b5SBarry Smith    SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
3904184914b5SBarry Smith 
3905184914b5SBarry Smith    Not Collective
3906184914b5SBarry Smith 
3907184914b5SBarry Smith    Input Parameter:
3908184914b5SBarry Smith .  snes - the SNES context
3909184914b5SBarry Smith 
3910184914b5SBarry Smith    Output Parameter:
39114d0a8057SBarry Smith .  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
3912184914b5SBarry Smith             manual pages for the individual convergence tests for complete lists
3913184914b5SBarry Smith 
39146a4d7782SBarry Smith    Options Database:
39156a4d7782SBarry Smith .   -snes_converged_reason - prints the reason to standard out
39166a4d7782SBarry Smith 
3917184914b5SBarry Smith    Level: intermediate
3918184914b5SBarry Smith 
391995452b02SPatrick Sanan    Notes:
392095452b02SPatrick Sanan     Should only be called after the call the SNESSolve() is complete, if it is called earlier it returns the value SNES__CONVERGED_ITERATING.
3921184914b5SBarry Smith 
3922184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test
3923184914b5SBarry Smith 
392433866048SMatthew G. Knepley .seealso: SNESSetConvergenceTest(), SNESSetConvergedReason(), SNESConvergedReason
3925184914b5SBarry Smith @*/
39267087cfbeSBarry Smith PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
3927184914b5SBarry Smith {
3928184914b5SBarry Smith   PetscFunctionBegin;
39290700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
39304482741eSBarry Smith   PetscValidPointer(reason,2);
3931184914b5SBarry Smith   *reason = snes->reason;
3932184914b5SBarry Smith   PetscFunctionReturn(0);
3933184914b5SBarry Smith }
3934184914b5SBarry Smith 
393533866048SMatthew G. Knepley /*@
393633866048SMatthew G. Knepley    SNESSetConvergedReason - Sets the reason the SNES iteration was stopped.
393733866048SMatthew G. Knepley 
393833866048SMatthew G. Knepley    Not Collective
393933866048SMatthew G. Knepley 
394033866048SMatthew G. Knepley    Input Parameters:
394133866048SMatthew G. Knepley +  snes - the SNES context
394233866048SMatthew G. Knepley -  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
394333866048SMatthew G. Knepley             manual pages for the individual convergence tests for complete lists
394433866048SMatthew G. Knepley 
394533866048SMatthew G. Knepley    Level: intermediate
394633866048SMatthew G. Knepley 
394733866048SMatthew G. Knepley .keywords: SNES, nonlinear, set, convergence, test
394833866048SMatthew G. Knepley .seealso: SNESGetConvergedReason(), SNESSetConvergenceTest(), SNESConvergedReason
394933866048SMatthew G. Knepley @*/
395033866048SMatthew G. Knepley PetscErrorCode SNESSetConvergedReason(SNES snes,SNESConvergedReason reason)
395133866048SMatthew G. Knepley {
395233866048SMatthew G. Knepley   PetscFunctionBegin;
395333866048SMatthew G. Knepley   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
395433866048SMatthew G. Knepley   snes->reason = reason;
395533866048SMatthew G. Knepley   PetscFunctionReturn(0);
395633866048SMatthew G. Knepley }
395733866048SMatthew G. Knepley 
3958c9005455SLois Curfman McInnes /*@
3959c9005455SLois Curfman McInnes    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
3960c9005455SLois Curfman McInnes 
39613f9fe445SBarry Smith    Logically Collective on SNES
3962fee21e36SBarry Smith 
3963c7afd0dbSLois Curfman McInnes    Input Parameters:
3964c7afd0dbSLois Curfman McInnes +  snes - iterative context obtained from SNESCreate()
39658c7482ecSBarry Smith .  a   - array to hold history, this array will contain the function norms computed at each step
3966cd5578b5SBarry Smith .  its - integer array holds the number of linear iterations for each solve.
3967758f92a0SBarry Smith .  na  - size of a and its
396864731454SLois Curfman McInnes -  reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
3969758f92a0SBarry Smith            else it continues storing new values for new nonlinear solves after the old ones
3970c7afd0dbSLois Curfman McInnes 
3971308dcc3eSBarry Smith    Notes:
39720298fd71SBarry Smith    If 'a' and 'its' are NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a
3973308dcc3eSBarry Smith    default array of length 10000 is allocated.
3974308dcc3eSBarry Smith 
3975c9005455SLois Curfman McInnes    This routine is useful, e.g., when running a code for purposes
3976c9005455SLois Curfman McInnes    of accurate performance monitoring, when no I/O should be done
3977c9005455SLois Curfman McInnes    during the section of code that is being timed.
3978c9005455SLois Curfman McInnes 
397936851e7fSLois Curfman McInnes    Level: intermediate
398036851e7fSLois Curfman McInnes 
3981c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history
3982758f92a0SBarry Smith 
398308405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory()
3984758f92a0SBarry Smith 
3985c9005455SLois Curfman McInnes @*/
39867087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset)
3987c9005455SLois Curfman McInnes {
3988308dcc3eSBarry Smith   PetscErrorCode ierr;
3989308dcc3eSBarry Smith 
39903a40ed3dSBarry Smith   PetscFunctionBegin;
39910700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
39927a1ec6d4SBarry Smith   if (a) PetscValidScalarPointer(a,2);
3993a562a398SLisandro Dalcin   if (its) PetscValidIntPointer(its,3);
39947a1ec6d4SBarry Smith   if (!a) {
3995308dcc3eSBarry Smith     if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
39967fdeb8b9SBarry Smith     ierr = PetscCalloc1(na,&a);CHKERRQ(ierr);
39977fdeb8b9SBarry Smith     ierr = PetscCalloc1(na,&its);CHKERRQ(ierr);
3998f5af7f23SKarl Rupp 
3999308dcc3eSBarry Smith     snes->conv_malloc = PETSC_TRUE;
4000308dcc3eSBarry Smith   }
4001c9005455SLois Curfman McInnes   snes->conv_hist       = a;
4002758f92a0SBarry Smith   snes->conv_hist_its   = its;
4003758f92a0SBarry Smith   snes->conv_hist_max   = na;
4004a12bc48fSLisandro Dalcin   snes->conv_hist_len   = 0;
4005758f92a0SBarry Smith   snes->conv_hist_reset = reset;
4006758f92a0SBarry Smith   PetscFunctionReturn(0);
4007758f92a0SBarry Smith }
4008758f92a0SBarry Smith 
4009308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
4010c6db04a5SJed Brown #include <engine.h>   /* MATLAB include file */
4011c6db04a5SJed Brown #include <mex.h>      /* MATLAB include file */
401299e0435eSBarry Smith 
40138cc058d9SJed Brown PETSC_EXTERN mxArray *SNESGetConvergenceHistoryMatlab(SNES snes)
4014308dcc3eSBarry Smith {
4015308dcc3eSBarry Smith   mxArray   *mat;
4016308dcc3eSBarry Smith   PetscInt  i;
4017308dcc3eSBarry Smith   PetscReal *ar;
4018308dcc3eSBarry Smith 
4019308dcc3eSBarry Smith   PetscFunctionBegin;
4020308dcc3eSBarry Smith   mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL);
4021308dcc3eSBarry Smith   ar  = (PetscReal*) mxGetData(mat);
4022f5af7f23SKarl Rupp   for (i=0; i<snes->conv_hist_len; i++) ar[i] = snes->conv_hist[i];
4023308dcc3eSBarry Smith   PetscFunctionReturn(mat);
4024308dcc3eSBarry Smith }
4025308dcc3eSBarry Smith #endif
4026308dcc3eSBarry Smith 
40270c4c9dddSBarry Smith /*@C
4028758f92a0SBarry Smith    SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
4029758f92a0SBarry Smith 
40303f9fe445SBarry Smith    Not Collective
4031758f92a0SBarry Smith 
4032758f92a0SBarry Smith    Input Parameter:
4033758f92a0SBarry Smith .  snes - iterative context obtained from SNESCreate()
4034758f92a0SBarry Smith 
4035758f92a0SBarry Smith    Output Parameters:
4036758f92a0SBarry Smith .  a   - array to hold history
4037758f92a0SBarry Smith .  its - integer array holds the number of linear iterations (or
4038758f92a0SBarry Smith          negative if not converged) for each solve.
4039758f92a0SBarry Smith -  na  - size of a and its
4040758f92a0SBarry Smith 
4041758f92a0SBarry Smith    Notes:
4042758f92a0SBarry Smith     The calling sequence for this routine in Fortran is
4043758f92a0SBarry Smith $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
4044758f92a0SBarry Smith 
4045758f92a0SBarry Smith    This routine is useful, e.g., when running a code for purposes
4046758f92a0SBarry Smith    of accurate performance monitoring, when no I/O should be done
4047758f92a0SBarry Smith    during the section of code that is being timed.
4048758f92a0SBarry Smith 
4049758f92a0SBarry Smith    Level: intermediate
4050758f92a0SBarry Smith 
4051758f92a0SBarry Smith .keywords: SNES, get, convergence, history
4052758f92a0SBarry Smith 
4053758f92a0SBarry Smith .seealso: SNESSetConvergencHistory()
4054758f92a0SBarry Smith 
4055758f92a0SBarry Smith @*/
40567087cfbeSBarry Smith PetscErrorCode  SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
4057758f92a0SBarry Smith {
4058758f92a0SBarry Smith   PetscFunctionBegin;
40590700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4060758f92a0SBarry Smith   if (a)   *a   = snes->conv_hist;
4061758f92a0SBarry Smith   if (its) *its = snes->conv_hist_its;
4062758f92a0SBarry Smith   if (na)  *na  = snes->conv_hist_len;
40633a40ed3dSBarry Smith   PetscFunctionReturn(0);
4064c9005455SLois Curfman McInnes }
4065c9005455SLois Curfman McInnes 
4066ac226902SBarry Smith /*@C
406776b2cf59SMatthew Knepley   SNESSetUpdate - Sets the general-purpose update function called
4068eec8f646SJed Brown   at the beginning of every iteration of the nonlinear solve. Specifically
40697e4bb74cSBarry Smith   it is called just before the Jacobian is "evaluated".
407076b2cf59SMatthew Knepley 
40713f9fe445SBarry Smith   Logically Collective on SNES
407276b2cf59SMatthew Knepley 
407376b2cf59SMatthew Knepley   Input Parameters:
407476b2cf59SMatthew Knepley . snes - The nonlinear solver context
407576b2cf59SMatthew Knepley . func - The function
407676b2cf59SMatthew Knepley 
407776b2cf59SMatthew Knepley   Calling sequence of func:
4078b5d30489SBarry Smith . func (SNES snes, PetscInt step);
407976b2cf59SMatthew Knepley 
408076b2cf59SMatthew Knepley . step - The current step of the iteration
408176b2cf59SMatthew Knepley 
4082fe97e370SBarry Smith   Level: advanced
4083fe97e370SBarry Smith 
4084fe97e370SBarry 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()
4085fe97e370SBarry Smith         This is not used by most users.
408676b2cf59SMatthew Knepley 
408776b2cf59SMatthew Knepley .keywords: SNES, update
4088b5d30489SBarry Smith 
40898d359177SBarry Smith .seealso SNESSetJacobian(), SNESSolve()
409076b2cf59SMatthew Knepley @*/
40917087cfbeSBarry Smith PetscErrorCode  SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
409276b2cf59SMatthew Knepley {
409376b2cf59SMatthew Knepley   PetscFunctionBegin;
40940700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID,1);
4095e7788613SBarry Smith   snes->ops->update = func;
409676b2cf59SMatthew Knepley   PetscFunctionReturn(0);
409776b2cf59SMatthew Knepley }
409876b2cf59SMatthew Knepley 
40999b94acceSBarry Smith /*
41009b94acceSBarry Smith    SNESScaleStep_Private - Scales a step so that its length is less than the
41019b94acceSBarry Smith    positive parameter delta.
41029b94acceSBarry Smith 
41039b94acceSBarry Smith     Input Parameters:
4104c7afd0dbSLois Curfman McInnes +   snes - the SNES context
41059b94acceSBarry Smith .   y - approximate solution of linear system
41069b94acceSBarry Smith .   fnorm - 2-norm of current function
4107c7afd0dbSLois Curfman McInnes -   delta - trust region size
41089b94acceSBarry Smith 
41099b94acceSBarry Smith     Output Parameters:
4110c7afd0dbSLois Curfman McInnes +   gpnorm - predicted function norm at the new point, assuming local
41119b94acceSBarry Smith     linearization.  The value is zero if the step lies within the trust
41129b94acceSBarry Smith     region, and exceeds zero otherwise.
4113c7afd0dbSLois Curfman McInnes -   ynorm - 2-norm of the step
41149b94acceSBarry Smith 
41159b94acceSBarry Smith     Note:
411604d7464bSBarry Smith     For non-trust region methods such as SNESNEWTONLS, the parameter delta
41179b94acceSBarry Smith     is set to be the maximum allowable step size.
41189b94acceSBarry Smith 
41199b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step
41209b94acceSBarry Smith */
4121dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
41229b94acceSBarry Smith {
4123064f8208SBarry Smith   PetscReal      nrm;
4124ea709b57SSatish Balay   PetscScalar    cnorm;
4125dfbe8321SBarry Smith   PetscErrorCode ierr;
41263a40ed3dSBarry Smith 
41273a40ed3dSBarry Smith   PetscFunctionBegin;
41280700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
41290700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
4130c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,2);
4131184914b5SBarry Smith 
4132064f8208SBarry Smith   ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr);
4133064f8208SBarry Smith   if (nrm > *delta) {
4134064f8208SBarry Smith     nrm     = *delta/nrm;
4135064f8208SBarry Smith     *gpnorm = (1.0 - nrm)*(*fnorm);
4136064f8208SBarry Smith     cnorm   = nrm;
41372dcb1b2aSMatthew Knepley     ierr    = VecScale(y,cnorm);CHKERRQ(ierr);
41389b94acceSBarry Smith     *ynorm  = *delta;
41399b94acceSBarry Smith   } else {
41409b94acceSBarry Smith     *gpnorm = 0.0;
4141064f8208SBarry Smith     *ynorm  = nrm;
41429b94acceSBarry Smith   }
41433a40ed3dSBarry Smith   PetscFunctionReturn(0);
41449b94acceSBarry Smith }
41459b94acceSBarry Smith 
41462a359c20SBarry Smith /*@
41472a359c20SBarry Smith    SNESReasonView - Displays the reason a SNES solve converged or diverged to a viewer
41482a359c20SBarry Smith 
41492a359c20SBarry Smith    Collective on SNES
41502a359c20SBarry Smith 
41512a359c20SBarry Smith    Parameter:
41522a359c20SBarry Smith +  snes - iterative context obtained from SNESCreate()
41532a359c20SBarry Smith -  viewer - the viewer to display the reason
41542a359c20SBarry Smith 
41552a359c20SBarry Smith 
41562a359c20SBarry Smith    Options Database Keys:
41572a359c20SBarry Smith .  -snes_converged_reason - print reason for converged or diverged, also prints number of iterations
41582a359c20SBarry Smith 
41592a359c20SBarry Smith    Level: beginner
41602a359c20SBarry Smith 
41612a359c20SBarry Smith .keywords: SNES, solve, linear system
41622a359c20SBarry Smith 
41632a359c20SBarry Smith .seealso: SNESCreate(), SNESSetUp(), SNESDestroy(), SNESSetTolerances(), SNESConvergedDefault()
41642a359c20SBarry Smith 
41652a359c20SBarry Smith @*/
41662a359c20SBarry Smith PetscErrorCode  SNESReasonView(SNES snes,PetscViewer viewer)
41672a359c20SBarry Smith {
416875cca76cSMatthew G. Knepley   PetscViewerFormat format;
41692a359c20SBarry Smith   PetscBool         isAscii;
417075cca76cSMatthew G. Knepley   PetscErrorCode    ierr;
41712a359c20SBarry Smith 
41722a359c20SBarry Smith   PetscFunctionBegin;
41732a359c20SBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isAscii);CHKERRQ(ierr);
41742a359c20SBarry Smith   if (isAscii) {
417575cca76cSMatthew G. Knepley     ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr);
41762a359c20SBarry Smith     ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
417775cca76cSMatthew G. Knepley     if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
417875cca76cSMatthew G. Knepley       DM                dm;
417975cca76cSMatthew G. Knepley       Vec               u;
418075cca76cSMatthew G. Knepley       PetscDS           prob;
418175cca76cSMatthew G. Knepley       PetscInt          Nf, f;
418275cca76cSMatthew G. Knepley       PetscErrorCode (**exactFuncs)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar[], void *);
418375cca76cSMatthew G. Knepley       PetscReal         error;
418475cca76cSMatthew G. Knepley 
418575cca76cSMatthew G. Knepley       ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr);
418675cca76cSMatthew G. Knepley       ierr = SNESGetSolution(snes, &u);CHKERRQ(ierr);
418775cca76cSMatthew G. Knepley       ierr = DMGetDS(dm, &prob);CHKERRQ(ierr);
418875cca76cSMatthew G. Knepley       ierr = PetscDSGetNumFields(prob, &Nf);CHKERRQ(ierr);
418975cca76cSMatthew G. Knepley       ierr = PetscMalloc1(Nf, &exactFuncs);CHKERRQ(ierr);
419075cca76cSMatthew G. Knepley       for (f = 0; f < Nf; ++f) {ierr = PetscDSGetExactSolution(prob, f, &exactFuncs[f]);CHKERRQ(ierr);}
419175cca76cSMatthew G. Knepley       ierr = DMComputeL2Diff(dm, 0.0, exactFuncs, NULL, u, &error);CHKERRQ(ierr);
419275cca76cSMatthew G. Knepley       ierr = PetscFree(exactFuncs);CHKERRQ(ierr);
419375cca76cSMatthew G. Knepley       if (error < 1.0e-11) {ierr = PetscViewerASCIIPrintf(viewer, "L_2 Error: < 1.0e-11\n");CHKERRQ(ierr);}
419475cca76cSMatthew G. Knepley       else                 {ierr = PetscViewerASCIIPrintf(viewer, "L_2 Error: %g\n", error);CHKERRQ(ierr);}
419575cca76cSMatthew G. Knepley     }
41962a359c20SBarry Smith     if (snes->reason > 0) {
41972a359c20SBarry Smith       if (((PetscObject) snes)->prefix) {
41982a359c20SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear %s solve converged due to %s iterations %D\n",((PetscObject) snes)->prefix,SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr);
41992a359c20SBarry Smith       } else {
42002a359c20SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear solve converged due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr);
42012a359c20SBarry Smith       }
42022a359c20SBarry Smith     } else {
42032a359c20SBarry Smith       if (((PetscObject) snes)->prefix) {
42042a359c20SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear %s solve did not converge due to %s iterations %D\n",((PetscObject) snes)->prefix,SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr);
42052a359c20SBarry Smith       } else {
42062a359c20SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear solve did not converge due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr);
42072a359c20SBarry Smith       }
42082a359c20SBarry Smith     }
42092a359c20SBarry Smith     ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
42102a359c20SBarry Smith   }
42112a359c20SBarry Smith   PetscFunctionReturn(0);
42122a359c20SBarry Smith }
42132a359c20SBarry Smith 
42142a359c20SBarry Smith /*@C
42152a359c20SBarry Smith   SNESReasonViewFromOptions - Processes command line options to determine if/how a SNESReason is to be viewed.
42162a359c20SBarry Smith 
42172a359c20SBarry Smith   Collective on SNES
42182a359c20SBarry Smith 
42192a359c20SBarry Smith   Input Parameters:
42202a359c20SBarry Smith . snes   - the SNES object
42212a359c20SBarry Smith 
42222a359c20SBarry Smith   Level: intermediate
42232a359c20SBarry Smith 
42242a359c20SBarry Smith @*/
42252a359c20SBarry Smith PetscErrorCode SNESReasonViewFromOptions(SNES snes)
42262a359c20SBarry Smith {
42272a359c20SBarry Smith   PetscErrorCode    ierr;
42282a359c20SBarry Smith   PetscViewer       viewer;
42292a359c20SBarry Smith   PetscBool         flg;
42302a359c20SBarry Smith   static PetscBool  incall = PETSC_FALSE;
42312a359c20SBarry Smith   PetscViewerFormat format;
42322a359c20SBarry Smith 
42332a359c20SBarry Smith   PetscFunctionBegin;
42342a359c20SBarry Smith   if (incall) PetscFunctionReturn(0);
42352a359c20SBarry Smith   incall = PETSC_TRUE;
42362a359c20SBarry Smith   ierr   = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_converged_reason",&viewer,&format,&flg);CHKERRQ(ierr);
42372a359c20SBarry Smith   if (flg) {
42382a359c20SBarry Smith     ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr);
42392a359c20SBarry Smith     ierr = SNESReasonView(snes,viewer);CHKERRQ(ierr);
42402a359c20SBarry Smith     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
42412a359c20SBarry Smith     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
42422a359c20SBarry Smith   }
42432a359c20SBarry Smith   incall = PETSC_FALSE;
42442a359c20SBarry Smith   PetscFunctionReturn(0);
42452a359c20SBarry Smith }
42462a359c20SBarry Smith 
4247487a658cSBarry Smith /*@
4248f69a0ea3SMatthew Knepley    SNESSolve - Solves a nonlinear system F(x) = b.
4249f69a0ea3SMatthew Knepley    Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
42509b94acceSBarry Smith 
4251c7afd0dbSLois Curfman McInnes    Collective on SNES
4252c7afd0dbSLois Curfman McInnes 
4253b2002411SLois Curfman McInnes    Input Parameters:
4254c7afd0dbSLois Curfman McInnes +  snes - the SNES context
42550298fd71SBarry Smith .  b - the constant part of the equation F(x) = b, or NULL to use zero.
425685385478SLisandro Dalcin -  x - the solution vector.
42579b94acceSBarry Smith 
4258b2002411SLois Curfman McInnes    Notes:
42598ddd3da0SLois Curfman McInnes    The user should initialize the vector,x, with the initial guess
42608ddd3da0SLois Curfman McInnes    for the nonlinear solve prior to calling SNESSolve.  In particular,
42618ddd3da0SLois Curfman McInnes    to employ an initial guess of zero, the user should explicitly set
42628ddd3da0SLois Curfman McInnes    this vector to zero by calling VecSet().
42638ddd3da0SLois Curfman McInnes 
426436851e7fSLois Curfman McInnes    Level: beginner
426536851e7fSLois Curfman McInnes 
42669b94acceSBarry Smith .keywords: SNES, nonlinear, solve
42679b94acceSBarry Smith 
4268c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution()
42699b94acceSBarry Smith @*/
42707087cfbeSBarry Smith PetscErrorCode  SNESSolve(SNES snes,Vec b,Vec x)
42719b94acceSBarry Smith {
4272dfbe8321SBarry Smith   PetscErrorCode    ierr;
4273ace3abfcSBarry Smith   PetscBool         flg;
4274efd51863SBarry Smith   PetscInt          grid;
42750298fd71SBarry Smith   Vec               xcreated = NULL;
4276caa4e7f2SJed Brown   DM                dm;
4277052efed2SBarry Smith 
42783a40ed3dSBarry Smith   PetscFunctionBegin;
42790700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4280a69afd8bSBarry Smith   if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3);
4281a69afd8bSBarry Smith   if (x) PetscCheckSameComm(snes,1,x,3);
42820700a824SBarry Smith   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2);
428385385478SLisandro Dalcin   if (b) PetscCheckSameComm(snes,1,b,2);
428485385478SLisandro Dalcin 
428534b4d3a8SMatthew G. Knepley   /* High level operations using the nonlinear solver */
428606fc46c8SMatthew G. Knepley   {
428706fc46c8SMatthew G. Knepley     PetscViewer       viewer;
428806fc46c8SMatthew G. Knepley     PetscViewerFormat format;
42897c88af5aSMatthew G. Knepley     PetscInt          num;
429006fc46c8SMatthew G. Knepley     PetscBool         flg;
429106fc46c8SMatthew G. Knepley     static PetscBool  incall = PETSC_FALSE;
429206fc46c8SMatthew G. Knepley 
429306fc46c8SMatthew G. Knepley     if (!incall) {
429434b4d3a8SMatthew G. Knepley       /* Estimate the convergence rate of the discretization */
429506fc46c8SMatthew G. Knepley       ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject) snes), ((PetscObject) snes)->prefix, "-snes_convergence_estimate", &viewer, &format, &flg);CHKERRQ(ierr);
429606fc46c8SMatthew G. Knepley       if (flg) {
429706fc46c8SMatthew G. Knepley         PetscConvEst conv;
429846079b62SMatthew G. Knepley         DM           dm;
429946079b62SMatthew G. Knepley         PetscReal   *alpha; /* Convergence rate of the solution error for each field in the L_2 norm */
430046079b62SMatthew G. Knepley         PetscInt     Nf;
430106fc46c8SMatthew G. Knepley 
430206fc46c8SMatthew G. Knepley         incall = PETSC_TRUE;
430346079b62SMatthew G. Knepley         ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr);
430446079b62SMatthew G. Knepley         ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr);
430546079b62SMatthew G. Knepley         ierr = PetscMalloc1(Nf, &alpha);CHKERRQ(ierr);
430606fc46c8SMatthew G. Knepley         ierr = PetscConvEstCreate(PetscObjectComm((PetscObject) snes), &conv);CHKERRQ(ierr);
430706fc46c8SMatthew G. Knepley         ierr = PetscConvEstSetSolver(conv, snes);CHKERRQ(ierr);
430806fc46c8SMatthew G. Knepley         ierr = PetscConvEstSetFromOptions(conv);CHKERRQ(ierr);
43090955ed61SMatthew G. Knepley         ierr = PetscConvEstSetUp(conv);CHKERRQ(ierr);
431046079b62SMatthew G. Knepley         ierr = PetscConvEstGetConvRate(conv, alpha);CHKERRQ(ierr);
431106fc46c8SMatthew G. Knepley         ierr = PetscViewerPushFormat(viewer, format);CHKERRQ(ierr);
431206fc46c8SMatthew G. Knepley         ierr = PetscConvEstRateView(conv, alpha, viewer);CHKERRQ(ierr);
431306fc46c8SMatthew G. Knepley         ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
431406fc46c8SMatthew G. Knepley         ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
431506fc46c8SMatthew G. Knepley         ierr = PetscConvEstDestroy(&conv);CHKERRQ(ierr);
431646079b62SMatthew G. Knepley         ierr = PetscFree(alpha);CHKERRQ(ierr);
431706fc46c8SMatthew G. Knepley         incall = PETSC_FALSE;
431806fc46c8SMatthew G. Knepley       }
431934b4d3a8SMatthew G. Knepley       /* Adaptively refine the initial grid */
4320b2588ea6SMatthew G. Knepley       num  = 1;
4321b2588ea6SMatthew G. Knepley       ierr = PetscOptionsGetInt(NULL, ((PetscObject) snes)->prefix, "-snes_adapt_initial", &num, &flg);CHKERRQ(ierr);
432234b4d3a8SMatthew G. Knepley       if (flg) {
432334b4d3a8SMatthew G. Knepley         DMAdaptor adaptor;
432434b4d3a8SMatthew G. Knepley 
432534b4d3a8SMatthew G. Knepley         incall = PETSC_TRUE;
432634b4d3a8SMatthew G. Knepley         ierr = DMAdaptorCreate(PETSC_COMM_WORLD, &adaptor);CHKERRQ(ierr);
432734b4d3a8SMatthew G. Knepley         ierr = DMAdaptorSetSolver(adaptor, snes);CHKERRQ(ierr);
4328b2588ea6SMatthew G. Knepley         ierr = DMAdaptorSetSequenceLength(adaptor, num);CHKERRQ(ierr);
432934b4d3a8SMatthew G. Knepley         ierr = DMAdaptorSetFromOptions(adaptor);CHKERRQ(ierr);
433034b4d3a8SMatthew G. Knepley         ierr = DMAdaptorSetUp(adaptor);CHKERRQ(ierr);
433134b4d3a8SMatthew G. Knepley         ierr = DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_INITIAL, &dm, &x);CHKERRQ(ierr);
433234b4d3a8SMatthew G. Knepley         ierr = DMAdaptorDestroy(&adaptor);CHKERRQ(ierr);
433334b4d3a8SMatthew G. Knepley         incall = PETSC_FALSE;
433434b4d3a8SMatthew G. Knepley       }
43357c88af5aSMatthew G. Knepley       /* Use grid sequencing to adapt */
43367c88af5aSMatthew G. Knepley       num  = 0;
43377c88af5aSMatthew G. Knepley       ierr = PetscOptionsGetInt(NULL, ((PetscObject) snes)->prefix, "-snes_adapt_sequence", &num, NULL);CHKERRQ(ierr);
43387c88af5aSMatthew G. Knepley       if (num) {
43397c88af5aSMatthew G. Knepley         DMAdaptor adaptor;
43407c88af5aSMatthew G. Knepley 
43417c88af5aSMatthew G. Knepley         incall = PETSC_TRUE;
43427c88af5aSMatthew G. Knepley         ierr = DMAdaptorCreate(PETSC_COMM_WORLD, &adaptor);CHKERRQ(ierr);
43437c88af5aSMatthew G. Knepley         ierr = DMAdaptorSetSolver(adaptor, snes);CHKERRQ(ierr);
43447c88af5aSMatthew G. Knepley         ierr = DMAdaptorSetSequenceLength(adaptor, num);CHKERRQ(ierr);
43457c88af5aSMatthew G. Knepley         ierr = DMAdaptorSetFromOptions(adaptor);CHKERRQ(ierr);
43467c88af5aSMatthew G. Knepley         ierr = DMAdaptorSetUp(adaptor);CHKERRQ(ierr);
43477c88af5aSMatthew G. Knepley         ierr = DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_SEQUENTIAL, &dm, &x);CHKERRQ(ierr);
43487c88af5aSMatthew G. Knepley         ierr = DMAdaptorDestroy(&adaptor);CHKERRQ(ierr);
43497c88af5aSMatthew G. Knepley         incall = PETSC_FALSE;
43507c88af5aSMatthew G. Knepley       }
435106fc46c8SMatthew G. Knepley     }
435206fc46c8SMatthew G. Knepley   }
4353caa4e7f2SJed Brown   if (!x) {
4354caa4e7f2SJed Brown     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
4355caa4e7f2SJed Brown     ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr);
4356a69afd8bSBarry Smith     x    = xcreated;
4357a69afd8bSBarry Smith   }
4358ce1779c8SBarry Smith   ierr = SNESViewFromOptions(snes,NULL,"-snes_view_pre");CHKERRQ(ierr);
4359f05ece33SBarry Smith 
4360ce94432eSBarry Smith   for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)));CHKERRQ(ierr);}
4361efd51863SBarry Smith   for (grid=0; grid<snes->gridsequence+1; grid++) {
4362efd51863SBarry Smith 
436385385478SLisandro Dalcin     /* set solution vector */
4364efd51863SBarry Smith     if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);}
43656bf464f9SBarry Smith     ierr          = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
436685385478SLisandro Dalcin     snes->vec_sol = x;
4367caa4e7f2SJed Brown     ierr          = SNESGetDM(snes,&dm);CHKERRQ(ierr);
4368caa4e7f2SJed Brown 
4369caa4e7f2SJed Brown     /* set affine vector if provided */
437085385478SLisandro Dalcin     if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); }
43716bf464f9SBarry Smith     ierr          = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
437285385478SLisandro Dalcin     snes->vec_rhs = b;
437385385478SLisandro Dalcin 
4374154060b5SMatthew G. Knepley     if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
4375154060b5SMatthew G. Knepley     if (snes->vec_rhs  == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector");
4376154060b5SMatthew G. Knepley     if (!snes->vec_sol_update /* && snes->vec_sol */) {
4377154060b5SMatthew G. Knepley       ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr);
4378154060b5SMatthew G. Knepley       ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->vec_sol_update);CHKERRQ(ierr);
4379154060b5SMatthew G. Knepley     }
4380154060b5SMatthew G. Knepley     ierr = DMShellSetGlobalVector(dm,snes->vec_sol);CHKERRQ(ierr);
438170e92668SMatthew Knepley     ierr = SNESSetUp(snes);CHKERRQ(ierr);
43823f149594SLisandro Dalcin 
43837eee914bSBarry Smith     if (!grid) {
43847eee914bSBarry Smith       if (snes->ops->computeinitialguess) {
4385d25893d9SBarry Smith         ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr);
4386d25893d9SBarry Smith       }
4387dd568438SSatish Balay     }
4388d25893d9SBarry Smith 
4389abc0a331SBarry Smith     if (snes->conv_hist_reset) snes->conv_hist_len = 0;
4390971e163fSPeter Brune     if (snes->counters_reset) {snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;}
4391d5e45103SBarry Smith 
43923f149594SLisandro Dalcin     ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
43934936397dSBarry Smith     ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr);
439485385478SLisandro Dalcin     ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
439517186662SBarry Smith     if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
4396422a814eSBarry Smith     snes->domainerror = PETSC_FALSE; /* clear the flag if it has been set */
43973f149594SLisandro Dalcin 
439837ec4e1aSPeter Brune     if (snes->lagjac_persist) snes->jac_iter += snes->iter;
439937ec4e1aSPeter Brune     if (snes->lagpre_persist) snes->pre_iter += snes->iter;
440037ec4e1aSPeter Brune 
440127b0f280SBarry Smith     ierr   = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_test_local_min",NULL,NULL,&flg);CHKERRQ(ierr);
4402da9b6338SBarry Smith     if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); }
44032a359c20SBarry Smith     ierr = SNESReasonViewFromOptions(snes);CHKERRQ(ierr);
44045968eb51SBarry Smith 
4405ce94432eSBarry Smith     if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged");
44069c8e83a9SBarry Smith     if (snes->reason < 0) break;
4407efd51863SBarry Smith     if (grid <  snes->gridsequence) {
4408efd51863SBarry Smith       DM  fine;
4409efd51863SBarry Smith       Vec xnew;
4410efd51863SBarry Smith       Mat interp;
4411efd51863SBarry Smith 
4412ce94432eSBarry Smith       ierr = DMRefine(snes->dm,PetscObjectComm((PetscObject)snes),&fine);CHKERRQ(ierr);
4413ce94432eSBarry Smith       if (!fine) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing");
44140298fd71SBarry Smith       ierr = DMCreateInterpolation(snes->dm,fine,&interp,NULL);CHKERRQ(ierr);
4415efd51863SBarry Smith       ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr);
4416efd51863SBarry Smith       ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr);
4417c833c3b5SJed Brown       ierr = DMInterpolate(snes->dm,interp,fine);CHKERRQ(ierr);
4418efd51863SBarry Smith       ierr = MatDestroy(&interp);CHKERRQ(ierr);
4419efd51863SBarry Smith       x    = xnew;
4420efd51863SBarry Smith 
4421efd51863SBarry Smith       ierr = SNESReset(snes);CHKERRQ(ierr);
4422efd51863SBarry Smith       ierr = SNESSetDM(snes,fine);CHKERRQ(ierr);
4423352f405dSMatthew G. Knepley       ierr = SNESResetFromOptions(snes);CHKERRQ(ierr);
4424efd51863SBarry Smith       ierr = DMDestroy(&fine);CHKERRQ(ierr);
4425ce94432eSBarry Smith       ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)));CHKERRQ(ierr);
4426efd51863SBarry Smith     }
4427efd51863SBarry Smith   }
4428ce1779c8SBarry Smith   ierr = SNESViewFromOptions(snes,NULL,"-snes_view");CHKERRQ(ierr);
4429685405a1SBarry Smith   ierr = VecViewFromOptions(snes->vec_sol,(PetscObject)snes,"-snes_view_solution");CHKERRQ(ierr);
44303f7e2da0SPeter Brune 
4431a69afd8bSBarry Smith   ierr = VecDestroy(&xcreated);CHKERRQ(ierr);
4432e04113cfSBarry Smith   ierr = PetscObjectSAWsBlock((PetscObject)snes);CHKERRQ(ierr);
44333a40ed3dSBarry Smith   PetscFunctionReturn(0);
44349b94acceSBarry Smith }
44359b94acceSBarry Smith 
44369b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */
44379b94acceSBarry Smith 
443882bf6240SBarry Smith /*@C
44394b0e389bSBarry Smith    SNESSetType - Sets the method for the nonlinear solver.
44409b94acceSBarry Smith 
4441fee21e36SBarry Smith    Collective on SNES
4442fee21e36SBarry Smith 
4443c7afd0dbSLois Curfman McInnes    Input Parameters:
4444c7afd0dbSLois Curfman McInnes +  snes - the SNES context
4445454a90a3SBarry Smith -  type - a known method
4446c7afd0dbSLois Curfman McInnes 
4447c7afd0dbSLois Curfman McInnes    Options Database Key:
4448454a90a3SBarry Smith .  -snes_type <type> - Sets the method; use -help for a list
444904d7464bSBarry Smith    of available methods (for instance, newtonls or newtontr)
4450ae12b187SLois Curfman McInnes 
44519b94acceSBarry Smith    Notes:
4452e090d566SSatish Balay    See "petsc/include/petscsnes.h" for available methods (for instance)
445304d7464bSBarry Smith +    SNESNEWTONLS - Newton's method with line search
4454c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
445504d7464bSBarry Smith .    SNESNEWTONTR - Newton's method with trust region
4456c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
44579b94acceSBarry Smith 
4458ae12b187SLois Curfman McInnes   Normally, it is best to use the SNESSetFromOptions() command and then
4459ae12b187SLois Curfman McInnes   set the SNES solver type from the options database rather than by using
4460ae12b187SLois Curfman McInnes   this routine.  Using the options database provides the user with
4461ae12b187SLois Curfman McInnes   maximum flexibility in evaluating the many nonlinear solvers.
4462ae12b187SLois Curfman McInnes   The SNESSetType() routine is provided for those situations where it
4463ae12b187SLois Curfman McInnes   is necessary to set the nonlinear solver independently of the command
4464ae12b187SLois Curfman McInnes   line or options database.  This might be the case, for example, when
4465ae12b187SLois Curfman McInnes   the choice of solver changes during the execution of the program,
4466ae12b187SLois Curfman McInnes   and the user's application is taking responsibility for choosing the
4467b0a32e0cSBarry Smith   appropriate method.
446836851e7fSLois Curfman McInnes 
446995452b02SPatrick Sanan     Developer Notes:
447095452b02SPatrick Sanan     SNESRegister() adds a constructor for a new SNESType to SNESList, SNESSetType() locates
44718f6c3df8SBarry Smith     the constructor in that list and calls it to create the spexific object.
44728f6c3df8SBarry Smith 
447336851e7fSLois Curfman McInnes   Level: intermediate
4474a703fe33SLois Curfman McInnes 
4475454a90a3SBarry Smith .keywords: SNES, set, type
4476435da068SBarry Smith 
44778f6c3df8SBarry Smith .seealso: SNESType, SNESCreate(), SNESDestroy(), SNESGetType(), SNESSetFromOptions()
4478435da068SBarry Smith 
44799b94acceSBarry Smith @*/
448019fd82e9SBarry Smith PetscErrorCode  SNESSetType(SNES snes,SNESType type)
44819b94acceSBarry Smith {
4482dfbe8321SBarry Smith   PetscErrorCode ierr,(*r)(SNES);
4483ace3abfcSBarry Smith   PetscBool      match;
44843a40ed3dSBarry Smith 
44853a40ed3dSBarry Smith   PetscFunctionBegin;
44860700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
44874482741eSBarry Smith   PetscValidCharPointer(type,2);
448882bf6240SBarry Smith 
4489251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr);
44900f5bd95cSBarry Smith   if (match) PetscFunctionReturn(0);
449192ff6ae8SBarry Smith 
44921c9cd337SJed Brown   ierr =  PetscFunctionListFind(SNESList,type,&r);CHKERRQ(ierr);
4493e32f2f54SBarry Smith   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
449475396ef9SLisandro Dalcin   /* Destroy the previous private SNES context */
4495b5c23020SJed Brown   if (snes->ops->destroy) {
4496b5c23020SJed Brown     ierr               = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr);
44970298fd71SBarry Smith     snes->ops->destroy = NULL;
4498b5c23020SJed Brown   }
449975396ef9SLisandro Dalcin   /* Reinitialize function pointers in SNESOps structure */
450075396ef9SLisandro Dalcin   snes->ops->setup          = 0;
450175396ef9SLisandro Dalcin   snes->ops->solve          = 0;
450275396ef9SLisandro Dalcin   snes->ops->view           = 0;
450375396ef9SLisandro Dalcin   snes->ops->setfromoptions = 0;
450475396ef9SLisandro Dalcin   snes->ops->destroy        = 0;
450575396ef9SLisandro Dalcin   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
450675396ef9SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
4507f5af7f23SKarl Rupp 
4508454a90a3SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr);
450903bfa161SLisandro Dalcin   ierr = (*r)(snes);CHKERRQ(ierr);
45103a40ed3dSBarry Smith   PetscFunctionReturn(0);
45119b94acceSBarry Smith }
45129b94acceSBarry Smith 
45139b94acceSBarry Smith /*@C
45149a28b0a6SLois Curfman McInnes    SNESGetType - Gets the SNES method type and name (as a string).
45159b94acceSBarry Smith 
4516c7afd0dbSLois Curfman McInnes    Not Collective
4517c7afd0dbSLois Curfman McInnes 
45189b94acceSBarry Smith    Input Parameter:
45194b0e389bSBarry Smith .  snes - nonlinear solver context
45209b94acceSBarry Smith 
45219b94acceSBarry Smith    Output Parameter:
45223a7fca6bSBarry Smith .  type - SNES method (a character string)
45239b94acceSBarry Smith 
452436851e7fSLois Curfman McInnes    Level: intermediate
452536851e7fSLois Curfman McInnes 
4526454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name
45279b94acceSBarry Smith @*/
452819fd82e9SBarry Smith PetscErrorCode  SNESGetType(SNES snes,SNESType *type)
45299b94acceSBarry Smith {
45303a40ed3dSBarry Smith   PetscFunctionBegin;
45310700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
45324482741eSBarry Smith   PetscValidPointer(type,2);
45337adad957SLisandro Dalcin   *type = ((PetscObject)snes)->type_name;
45343a40ed3dSBarry Smith   PetscFunctionReturn(0);
45359b94acceSBarry Smith }
45369b94acceSBarry Smith 
45373cd8a7caSMatthew G. Knepley /*@
45383cd8a7caSMatthew G. Knepley   SNESSetSolution - Sets the solution vector for use by the SNES routines.
45393cd8a7caSMatthew G. Knepley 
45403cd8a7caSMatthew G. Knepley   Logically Collective on SNES and Vec
45413cd8a7caSMatthew G. Knepley 
45423cd8a7caSMatthew G. Knepley   Input Parameters:
45433cd8a7caSMatthew G. Knepley + snes - the SNES context obtained from SNESCreate()
45443cd8a7caSMatthew G. Knepley - u    - the solution vector
45453cd8a7caSMatthew G. Knepley 
45463cd8a7caSMatthew G. Knepley   Level: beginner
45473cd8a7caSMatthew G. Knepley 
45483cd8a7caSMatthew G. Knepley .keywords: SNES, set, solution
45493cd8a7caSMatthew G. Knepley @*/
45503cd8a7caSMatthew G. Knepley PetscErrorCode SNESSetSolution(SNES snes, Vec u)
45513cd8a7caSMatthew G. Knepley {
45523cd8a7caSMatthew G. Knepley   DM             dm;
45533cd8a7caSMatthew G. Knepley   PetscErrorCode ierr;
45543cd8a7caSMatthew G. Knepley 
45553cd8a7caSMatthew G. Knepley   PetscFunctionBegin;
45563cd8a7caSMatthew G. Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
45573cd8a7caSMatthew G. Knepley   PetscValidHeaderSpecific(u, VEC_CLASSID, 2);
45583cd8a7caSMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) u);CHKERRQ(ierr);
45593cd8a7caSMatthew G. Knepley   ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
45603cd8a7caSMatthew G. Knepley 
45613cd8a7caSMatthew G. Knepley   snes->vec_sol = u;
45623cd8a7caSMatthew G. Knepley 
45633cd8a7caSMatthew G. Knepley   ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr);
45643cd8a7caSMatthew G. Knepley   ierr = DMShellSetGlobalVector(dm, u);CHKERRQ(ierr);
45653cd8a7caSMatthew G. Knepley   PetscFunctionReturn(0);
45663cd8a7caSMatthew G. Knepley }
45673cd8a7caSMatthew G. Knepley 
456852baeb72SSatish Balay /*@
45699b94acceSBarry Smith    SNESGetSolution - Returns the vector where the approximate solution is
4570c0df2a02SJed Brown    stored. This is the fine grid solution when using SNESSetGridSequence().
45719b94acceSBarry Smith 
4572c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
4573c7afd0dbSLois Curfman McInnes 
45749b94acceSBarry Smith    Input Parameter:
45759b94acceSBarry Smith .  snes - the SNES context
45769b94acceSBarry Smith 
45779b94acceSBarry Smith    Output Parameter:
45789b94acceSBarry Smith .  x - the solution
45799b94acceSBarry Smith 
458070e92668SMatthew Knepley    Level: intermediate
458136851e7fSLois Curfman McInnes 
45829b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution
45839b94acceSBarry Smith 
458485385478SLisandro Dalcin .seealso:  SNESGetSolutionUpdate(), SNESGetFunction()
45859b94acceSBarry Smith @*/
45867087cfbeSBarry Smith PetscErrorCode  SNESGetSolution(SNES snes,Vec *x)
45879b94acceSBarry Smith {
45883a40ed3dSBarry Smith   PetscFunctionBegin;
45890700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
45904482741eSBarry Smith   PetscValidPointer(x,2);
459185385478SLisandro Dalcin   *x = snes->vec_sol;
459270e92668SMatthew Knepley   PetscFunctionReturn(0);
459370e92668SMatthew Knepley }
459470e92668SMatthew Knepley 
459552baeb72SSatish Balay /*@
45969b94acceSBarry Smith    SNESGetSolutionUpdate - Returns the vector where the solution update is
45979b94acceSBarry Smith    stored.
45989b94acceSBarry Smith 
4599c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
4600c7afd0dbSLois Curfman McInnes 
46019b94acceSBarry Smith    Input Parameter:
46029b94acceSBarry Smith .  snes - the SNES context
46039b94acceSBarry Smith 
46049b94acceSBarry Smith    Output Parameter:
46059b94acceSBarry Smith .  x - the solution update
46069b94acceSBarry Smith 
460736851e7fSLois Curfman McInnes    Level: advanced
460836851e7fSLois Curfman McInnes 
46099b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update
46109b94acceSBarry Smith 
461185385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction()
46129b94acceSBarry Smith @*/
46137087cfbeSBarry Smith PetscErrorCode  SNESGetSolutionUpdate(SNES snes,Vec *x)
46149b94acceSBarry Smith {
46153a40ed3dSBarry Smith   PetscFunctionBegin;
46160700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
46174482741eSBarry Smith   PetscValidPointer(x,2);
461885385478SLisandro Dalcin   *x = snes->vec_sol_update;
46193a40ed3dSBarry Smith   PetscFunctionReturn(0);
46209b94acceSBarry Smith }
46219b94acceSBarry Smith 
46229b94acceSBarry Smith /*@C
46233638b69dSLois Curfman McInnes    SNESGetFunction - Returns the vector where the function is stored.
46249b94acceSBarry Smith 
4625a63bb30eSJed Brown    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
4626c7afd0dbSLois Curfman McInnes 
46279b94acceSBarry Smith    Input Parameter:
46289b94acceSBarry Smith .  snes - the SNES context
46299b94acceSBarry Smith 
46309b94acceSBarry Smith    Output Parameter:
46310298fd71SBarry Smith +  r - the vector that is used to store residuals (or NULL if you don't want it)
4632f8b49ee9SBarry Smith .  f - the function (or NULL if you don't want it); see SNESFunction for calling sequence details
46330298fd71SBarry Smith -  ctx - the function context (or NULL if you don't want it)
46349b94acceSBarry Smith 
463536851e7fSLois Curfman McInnes    Level: advanced
463636851e7fSLois Curfman McInnes 
463704edfde5SBarry Smith     Notes: The vector r DOES NOT, in general contain the current value of the SNES nonlinear function
463804edfde5SBarry Smith 
4639a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function
46409b94acceSBarry Smith 
4641bf388a1fSBarry Smith .seealso: SNESSetFunction(), SNESGetSolution(), SNESFunction
46429b94acceSBarry Smith @*/
4643f8b49ee9SBarry Smith PetscErrorCode  SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**f)(SNES,Vec,Vec,void*),void **ctx)
46449b94acceSBarry Smith {
4645a63bb30eSJed Brown   PetscErrorCode ierr;
46466cab3a1bSJed Brown   DM             dm;
4647a63bb30eSJed Brown 
46483a40ed3dSBarry Smith   PetscFunctionBegin;
46490700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4650a63bb30eSJed Brown   if (r) {
4651a63bb30eSJed Brown     if (!snes->vec_func) {
4652a63bb30eSJed Brown       if (snes->vec_rhs) {
4653a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr);
4654a63bb30eSJed Brown       } else if (snes->vec_sol) {
4655a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr);
4656a63bb30eSJed Brown       } else if (snes->dm) {
4657a63bb30eSJed Brown         ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr);
4658a63bb30eSJed Brown       }
4659a63bb30eSJed Brown     }
4660a63bb30eSJed Brown     *r = snes->vec_func;
4661a63bb30eSJed Brown   }
46626cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
4663f8b49ee9SBarry Smith   ierr = DMSNESGetFunction(dm,f,ctx);CHKERRQ(ierr);
46643a40ed3dSBarry Smith   PetscFunctionReturn(0);
46659b94acceSBarry Smith }
46669b94acceSBarry Smith 
4667c79ef259SPeter Brune /*@C
4668be95d8f1SBarry Smith    SNESGetNGS - Returns the NGS function and context.
4669c79ef259SPeter Brune 
4670c79ef259SPeter Brune    Input Parameter:
4671c79ef259SPeter Brune .  snes - the SNES context
4672c79ef259SPeter Brune 
4673c79ef259SPeter Brune    Output Parameter:
4674be95d8f1SBarry Smith +  f - the function (or NULL) see SNESNGSFunction for details
46750298fd71SBarry Smith -  ctx    - the function context (or NULL)
4676c79ef259SPeter Brune 
4677c79ef259SPeter Brune    Level: advanced
4678c79ef259SPeter Brune 
4679c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function
4680c79ef259SPeter Brune 
4681be95d8f1SBarry Smith .seealso: SNESSetNGS(), SNESGetFunction()
4682c79ef259SPeter Brune @*/
4683c79ef259SPeter Brune 
4684be95d8f1SBarry Smith PetscErrorCode SNESGetNGS (SNES snes, PetscErrorCode (**f)(SNES, Vec, Vec, void*), void ** ctx)
4685646217ecSPeter Brune {
46866cab3a1bSJed Brown   PetscErrorCode ierr;
46876cab3a1bSJed Brown   DM             dm;
46886cab3a1bSJed Brown 
4689646217ecSPeter Brune   PetscFunctionBegin;
4690646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
46916cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
4692be95d8f1SBarry Smith   ierr = DMSNESGetNGS(dm,f,ctx);CHKERRQ(ierr);
4693646217ecSPeter Brune   PetscFunctionReturn(0);
4694646217ecSPeter Brune }
4695646217ecSPeter Brune 
46963c7409f5SSatish Balay /*@C
46973c7409f5SSatish Balay    SNESSetOptionsPrefix - Sets the prefix used for searching for all
4698d850072dSLois Curfman McInnes    SNES options in the database.
46993c7409f5SSatish Balay 
47003f9fe445SBarry Smith    Logically Collective on SNES
4701fee21e36SBarry Smith 
4702c7afd0dbSLois Curfman McInnes    Input Parameter:
4703c7afd0dbSLois Curfman McInnes +  snes - the SNES context
4704c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
4705c7afd0dbSLois Curfman McInnes 
4706d850072dSLois Curfman McInnes    Notes:
4707a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
4708c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
4709d850072dSLois Curfman McInnes 
471036851e7fSLois Curfman McInnes    Level: advanced
471136851e7fSLois Curfman McInnes 
47123c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database
4713a86d99e1SLois Curfman McInnes 
4714a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions()
47153c7409f5SSatish Balay @*/
47167087cfbeSBarry Smith PetscErrorCode  SNESSetOptionsPrefix(SNES snes,const char prefix[])
47173c7409f5SSatish Balay {
4718dfbe8321SBarry Smith   PetscErrorCode ierr;
47193c7409f5SSatish Balay 
47203a40ed3dSBarry Smith   PetscFunctionBegin;
47210700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4722639f9d9dSBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
47231cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
472435f5d045SPeter Brune   if (snes->linesearch) {
47257601faf0SJed Brown     ierr = SNESGetLineSearch(snes,&snes->linesearch);CHKERRQ(ierr);
472608b6c495SPeter Brune     ierr = PetscObjectSetOptionsPrefix((PetscObject)snes->linesearch,prefix);CHKERRQ(ierr);
472735f5d045SPeter Brune   }
472835f5d045SPeter Brune   ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
47293a40ed3dSBarry Smith   PetscFunctionReturn(0);
47303c7409f5SSatish Balay }
47313c7409f5SSatish Balay 
47323c7409f5SSatish Balay /*@C
4733f525115eSLois Curfman McInnes    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
4734d850072dSLois Curfman McInnes    SNES options in the database.
47353c7409f5SSatish Balay 
47363f9fe445SBarry Smith    Logically Collective on SNES
4737fee21e36SBarry Smith 
4738c7afd0dbSLois Curfman McInnes    Input Parameters:
4739c7afd0dbSLois Curfman McInnes +  snes - the SNES context
4740c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
4741c7afd0dbSLois Curfman McInnes 
4742d850072dSLois Curfman McInnes    Notes:
4743a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
4744c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
4745d850072dSLois Curfman McInnes 
474636851e7fSLois Curfman McInnes    Level: advanced
474736851e7fSLois Curfman McInnes 
47483c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database
4749a86d99e1SLois Curfman McInnes 
4750a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix()
47513c7409f5SSatish Balay @*/
47527087cfbeSBarry Smith PetscErrorCode  SNESAppendOptionsPrefix(SNES snes,const char prefix[])
47533c7409f5SSatish Balay {
4754dfbe8321SBarry Smith   PetscErrorCode ierr;
47553c7409f5SSatish Balay 
47563a40ed3dSBarry Smith   PetscFunctionBegin;
47570700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4758639f9d9dSBarry Smith   ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
47591cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
476035f5d045SPeter Brune   if (snes->linesearch) {
47617601faf0SJed Brown     ierr = SNESGetLineSearch(snes,&snes->linesearch);CHKERRQ(ierr);
476208b6c495SPeter Brune     ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes->linesearch,prefix);CHKERRQ(ierr);
476335f5d045SPeter Brune   }
476435f5d045SPeter Brune   ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
47653a40ed3dSBarry Smith   PetscFunctionReturn(0);
47663c7409f5SSatish Balay }
47673c7409f5SSatish Balay 
47689ab63eb5SSatish Balay /*@C
47693c7409f5SSatish Balay    SNESGetOptionsPrefix - Sets the prefix used for searching for all
47703c7409f5SSatish Balay    SNES options in the database.
47713c7409f5SSatish Balay 
4772c7afd0dbSLois Curfman McInnes    Not Collective
4773c7afd0dbSLois Curfman McInnes 
47743c7409f5SSatish Balay    Input Parameter:
47753c7409f5SSatish Balay .  snes - the SNES context
47763c7409f5SSatish Balay 
47773c7409f5SSatish Balay    Output Parameter:
47783c7409f5SSatish Balay .  prefix - pointer to the prefix string used
47793c7409f5SSatish Balay 
478095452b02SPatrick Sanan    Notes:
478195452b02SPatrick Sanan     On the fortran side, the user should pass in a string 'prefix' of
47829ab63eb5SSatish Balay    sufficient length to hold the prefix.
47839ab63eb5SSatish Balay 
478436851e7fSLois Curfman McInnes    Level: advanced
478536851e7fSLois Curfman McInnes 
47863c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database
4787a86d99e1SLois Curfman McInnes 
4788a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix()
47893c7409f5SSatish Balay @*/
47907087cfbeSBarry Smith PetscErrorCode  SNESGetOptionsPrefix(SNES snes,const char *prefix[])
47913c7409f5SSatish Balay {
4792dfbe8321SBarry Smith   PetscErrorCode ierr;
47933c7409f5SSatish Balay 
47943a40ed3dSBarry Smith   PetscFunctionBegin;
47950700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4796639f9d9dSBarry Smith   ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
47973a40ed3dSBarry Smith   PetscFunctionReturn(0);
47983c7409f5SSatish Balay }
47993c7409f5SSatish Balay 
4800b2002411SLois Curfman McInnes 
48013cea93caSBarry Smith /*@C
48021c84c290SBarry Smith   SNESRegister - Adds a method to the nonlinear solver package.
48031c84c290SBarry Smith 
48041c84c290SBarry Smith    Not collective
48051c84c290SBarry Smith 
48061c84c290SBarry Smith    Input Parameters:
48071c84c290SBarry Smith +  name_solver - name of a new user-defined solver
48081c84c290SBarry Smith -  routine_create - routine to create method context
48091c84c290SBarry Smith 
48101c84c290SBarry Smith    Notes:
48111c84c290SBarry Smith    SNESRegister() may be called multiple times to add several user-defined solvers.
48121c84c290SBarry Smith 
48131c84c290SBarry Smith    Sample usage:
48141c84c290SBarry Smith .vb
4815bdf89e91SBarry Smith    SNESRegister("my_solver",MySolverCreate);
48161c84c290SBarry Smith .ve
48171c84c290SBarry Smith 
48181c84c290SBarry Smith    Then, your solver can be chosen with the procedural interface via
48191c84c290SBarry Smith $     SNESSetType(snes,"my_solver")
48201c84c290SBarry Smith    or at runtime via the option
48211c84c290SBarry Smith $     -snes_type my_solver
48221c84c290SBarry Smith 
48231c84c290SBarry Smith    Level: advanced
48241c84c290SBarry Smith 
48251c84c290SBarry Smith     Note: If your function is not being put into a shared library then use SNESRegister() instead
48261c84c290SBarry Smith 
48271c84c290SBarry Smith .keywords: SNES, nonlinear, register
48281c84c290SBarry Smith 
48291c84c290SBarry Smith .seealso: SNESRegisterAll(), SNESRegisterDestroy()
48303cea93caSBarry Smith 
48317f6c08e0SMatthew Knepley   Level: advanced
48323cea93caSBarry Smith @*/
4833bdf89e91SBarry Smith PetscErrorCode  SNESRegister(const char sname[],PetscErrorCode (*function)(SNES))
4834b2002411SLois Curfman McInnes {
4835dfbe8321SBarry Smith   PetscErrorCode ierr;
4836b2002411SLois Curfman McInnes 
4837b2002411SLois Curfman McInnes   PetscFunctionBegin;
48381d36bdfdSBarry Smith   ierr = SNESInitializePackage();CHKERRQ(ierr);
4839a240a19fSJed Brown   ierr = PetscFunctionListAdd(&SNESList,sname,function);CHKERRQ(ierr);
4840b2002411SLois Curfman McInnes   PetscFunctionReturn(0);
4841b2002411SLois Curfman McInnes }
4842da9b6338SBarry Smith 
48437087cfbeSBarry Smith PetscErrorCode  SNESTestLocalMin(SNES snes)
4844da9b6338SBarry Smith {
4845dfbe8321SBarry Smith   PetscErrorCode ierr;
484677431f27SBarry Smith   PetscInt       N,i,j;
4847da9b6338SBarry Smith   Vec            u,uh,fh;
4848da9b6338SBarry Smith   PetscScalar    value;
4849da9b6338SBarry Smith   PetscReal      norm;
4850da9b6338SBarry Smith 
4851da9b6338SBarry Smith   PetscFunctionBegin;
4852da9b6338SBarry Smith   ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr);
4853da9b6338SBarry Smith   ierr = VecDuplicate(u,&uh);CHKERRQ(ierr);
4854da9b6338SBarry Smith   ierr = VecDuplicate(u,&fh);CHKERRQ(ierr);
4855da9b6338SBarry Smith 
4856da9b6338SBarry Smith   /* currently only works for sequential */
485722d28d08SBarry Smith   ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");CHKERRQ(ierr);
4858da9b6338SBarry Smith   ierr = VecGetSize(u,&N);CHKERRQ(ierr);
4859da9b6338SBarry Smith   for (i=0; i<N; i++) {
4860da9b6338SBarry Smith     ierr = VecCopy(u,uh);CHKERRQ(ierr);
486177431f27SBarry Smith     ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr);
4862da9b6338SBarry Smith     for (j=-10; j<11; j++) {
48638b49ba18SBarry Smith       value = PetscSign(j)*PetscExpReal(PetscAbs(j)-10.0);
4864da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
48653ab0aad5SBarry Smith       ierr  = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr);
4866da9b6338SBarry Smith       ierr  = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr);
486777431f27SBarry Smith       ierr  = PetscPrintf(PETSC_COMM_WORLD,"       j norm %D %18.16e\n",j,norm);CHKERRQ(ierr);
4868da9b6338SBarry Smith       value = -value;
4869da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
4870da9b6338SBarry Smith     }
4871da9b6338SBarry Smith   }
48726bf464f9SBarry Smith   ierr = VecDestroy(&uh);CHKERRQ(ierr);
48736bf464f9SBarry Smith   ierr = VecDestroy(&fh);CHKERRQ(ierr);
4874da9b6338SBarry Smith   PetscFunctionReturn(0);
4875da9b6338SBarry Smith }
487671f87433Sdalcinl 
487771f87433Sdalcinl /*@
4878fa9f3622SBarry Smith    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
487971f87433Sdalcinl    computing relative tolerance for linear solvers within an inexact
488071f87433Sdalcinl    Newton method.
488171f87433Sdalcinl 
48823f9fe445SBarry Smith    Logically Collective on SNES
488371f87433Sdalcinl 
488471f87433Sdalcinl    Input Parameters:
488571f87433Sdalcinl +  snes - SNES context
488671f87433Sdalcinl -  flag - PETSC_TRUE or PETSC_FALSE
488771f87433Sdalcinl 
488864ba62caSBarry Smith     Options Database:
488964ba62caSBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
489064ba62caSBarry Smith .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
489164ba62caSBarry Smith .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
489264ba62caSBarry Smith .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
489364ba62caSBarry Smith .  -snes_ksp_ew_gamma <gamma> - Sets gamma
489464ba62caSBarry Smith .  -snes_ksp_ew_alpha <alpha> - Sets alpha
489564ba62caSBarry Smith .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
489664ba62caSBarry Smith -  -snes_ksp_ew_threshold <threshold> - Sets threshold
489764ba62caSBarry Smith 
489871f87433Sdalcinl    Notes:
489971f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
490071f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
490171f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
490271f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
490371f87433Sdalcinl    solver.
490471f87433Sdalcinl 
490571f87433Sdalcinl    Level: advanced
490671f87433Sdalcinl 
490771f87433Sdalcinl    Reference:
490871f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
490971f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
491071f87433Sdalcinl 
491171f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
491271f87433Sdalcinl 
4913fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
491471f87433Sdalcinl @*/
49157087cfbeSBarry Smith PetscErrorCode  SNESKSPSetUseEW(SNES snes,PetscBool flag)
491671f87433Sdalcinl {
491771f87433Sdalcinl   PetscFunctionBegin;
49180700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4919acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flag,2);
492071f87433Sdalcinl   snes->ksp_ewconv = flag;
492171f87433Sdalcinl   PetscFunctionReturn(0);
492271f87433Sdalcinl }
492371f87433Sdalcinl 
492471f87433Sdalcinl /*@
4925fa9f3622SBarry Smith    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
492671f87433Sdalcinl    for computing relative tolerance for linear solvers within an
492771f87433Sdalcinl    inexact Newton method.
492871f87433Sdalcinl 
492971f87433Sdalcinl    Not Collective
493071f87433Sdalcinl 
493171f87433Sdalcinl    Input Parameter:
493271f87433Sdalcinl .  snes - SNES context
493371f87433Sdalcinl 
493471f87433Sdalcinl    Output Parameter:
493571f87433Sdalcinl .  flag - PETSC_TRUE or PETSC_FALSE
493671f87433Sdalcinl 
493771f87433Sdalcinl    Notes:
493871f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
493971f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
494071f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
494171f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
494271f87433Sdalcinl    solver.
494371f87433Sdalcinl 
494471f87433Sdalcinl    Level: advanced
494571f87433Sdalcinl 
494671f87433Sdalcinl    Reference:
494771f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
494871f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
494971f87433Sdalcinl 
495071f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
495171f87433Sdalcinl 
4952fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
495371f87433Sdalcinl @*/
49547087cfbeSBarry Smith PetscErrorCode  SNESKSPGetUseEW(SNES snes, PetscBool  *flag)
495571f87433Sdalcinl {
495671f87433Sdalcinl   PetscFunctionBegin;
49570700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
495871f87433Sdalcinl   PetscValidPointer(flag,2);
495971f87433Sdalcinl   *flag = snes->ksp_ewconv;
496071f87433Sdalcinl   PetscFunctionReturn(0);
496171f87433Sdalcinl }
496271f87433Sdalcinl 
496371f87433Sdalcinl /*@
4964fa9f3622SBarry Smith    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
496571f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
496671f87433Sdalcinl    Newton method.
496771f87433Sdalcinl 
49683f9fe445SBarry Smith    Logically Collective on SNES
496971f87433Sdalcinl 
497071f87433Sdalcinl    Input Parameters:
497171f87433Sdalcinl +    snes - SNES context
497271f87433Sdalcinl .    version - version 1, 2 (default is 2) or 3
497371f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
497471f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
497571f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
497671f87433Sdalcinl              (0 <= gamma2 <= 1)
497771f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
497871f87433Sdalcinl .    alpha2 - power for safeguard
497971f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
498071f87433Sdalcinl 
498171f87433Sdalcinl    Note:
498271f87433Sdalcinl    Version 3 was contributed by Luis Chacon, June 2006.
498371f87433Sdalcinl 
498471f87433Sdalcinl    Use PETSC_DEFAULT to retain the default for any of the parameters.
498571f87433Sdalcinl 
498671f87433Sdalcinl    Level: advanced
498771f87433Sdalcinl 
498871f87433Sdalcinl    Reference:
498971f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
499071f87433Sdalcinl    inexact Newton method", Utah State University Math. Stat. Dept. Res.
499171f87433Sdalcinl    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
499271f87433Sdalcinl 
499371f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
499471f87433Sdalcinl 
4995fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
499671f87433Sdalcinl @*/
4997f5af7f23SKarl Rupp PetscErrorCode  SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
499871f87433Sdalcinl {
4999fa9f3622SBarry Smith   SNESKSPEW *kctx;
50005fd66863SKarl Rupp 
500171f87433Sdalcinl   PetscFunctionBegin;
50020700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5003fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
5004e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
5005c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,version,2);
5006c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_0,3);
5007c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_max,4);
5008c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,gamma,5);
5009c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha,6);
5010c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha2,7);
5011c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,threshold,8);
501271f87433Sdalcinl 
501371f87433Sdalcinl   if (version != PETSC_DEFAULT)   kctx->version   = version;
501471f87433Sdalcinl   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
501571f87433Sdalcinl   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
501671f87433Sdalcinl   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
501771f87433Sdalcinl   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
501871f87433Sdalcinl   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
501971f87433Sdalcinl   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
502071f87433Sdalcinl 
5021f23aa3ddSBarry Smith   if (kctx->version < 1 || kctx->version > 3) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version);
502257622a8eSBarry Smith   if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %g",(double)kctx->rtol_0);
502357622a8eSBarry Smith   if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%g) < 1.0\n",(double)kctx->rtol_max);
502457622a8eSBarry Smith   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%g) <= 1.0\n",(double)kctx->gamma);
502557622a8eSBarry Smith   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%g) <= 2.0\n",(double)kctx->alpha);
502657622a8eSBarry Smith   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%g) < 1.0\n",(double)kctx->threshold);
502771f87433Sdalcinl   PetscFunctionReturn(0);
502871f87433Sdalcinl }
502971f87433Sdalcinl 
503071f87433Sdalcinl /*@
5031fa9f3622SBarry Smith    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
503271f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
503371f87433Sdalcinl    Newton method.
503471f87433Sdalcinl 
503571f87433Sdalcinl    Not Collective
503671f87433Sdalcinl 
503771f87433Sdalcinl    Input Parameters:
503871f87433Sdalcinl      snes - SNES context
503971f87433Sdalcinl 
504071f87433Sdalcinl    Output Parameters:
504171f87433Sdalcinl +    version - version 1, 2 (default is 2) or 3
504271f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
504371f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
5044bf388a1fSBarry Smith .    gamma - multiplicative factor for version 2 rtol computation (0 <= gamma2 <= 1)
504571f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
504671f87433Sdalcinl .    alpha2 - power for safeguard
504771f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
504871f87433Sdalcinl 
504971f87433Sdalcinl    Level: advanced
505071f87433Sdalcinl 
505171f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters
505271f87433Sdalcinl 
5053fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
505471f87433Sdalcinl @*/
5055bf388a1fSBarry Smith PetscErrorCode  SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
505671f87433Sdalcinl {
5057fa9f3622SBarry Smith   SNESKSPEW *kctx;
50585fd66863SKarl Rupp 
505971f87433Sdalcinl   PetscFunctionBegin;
50600700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5061fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
5062e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
506371f87433Sdalcinl   if (version)   *version   = kctx->version;
506471f87433Sdalcinl   if (rtol_0)    *rtol_0    = kctx->rtol_0;
506571f87433Sdalcinl   if (rtol_max)  *rtol_max  = kctx->rtol_max;
506671f87433Sdalcinl   if (gamma)     *gamma     = kctx->gamma;
506771f87433Sdalcinl   if (alpha)     *alpha     = kctx->alpha;
506871f87433Sdalcinl   if (alpha2)    *alpha2    = kctx->alpha2;
506971f87433Sdalcinl   if (threshold) *threshold = kctx->threshold;
507071f87433Sdalcinl   PetscFunctionReturn(0);
507171f87433Sdalcinl }
507271f87433Sdalcinl 
5073d5378b5fSDmitry Karpeev  PetscErrorCode KSPPreSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes)
507471f87433Sdalcinl {
507571f87433Sdalcinl   PetscErrorCode ierr;
5076fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
507771f87433Sdalcinl   PetscReal      rtol  = PETSC_DEFAULT,stol;
507871f87433Sdalcinl 
507971f87433Sdalcinl   PetscFunctionBegin;
5080d4211eb9SBarry Smith   if (!snes->ksp_ewconv) PetscFunctionReturn(0);
508130058271SDmitry Karpeev   if (!snes->iter) {
508230058271SDmitry Karpeev     rtol = kctx->rtol_0; /* first time in, so use the original user rtol */
508330058271SDmitry Karpeev     ierr = VecNorm(snes->vec_func,NORM_2,&kctx->norm_first);CHKERRQ(ierr);
508430058271SDmitry Karpeev   }
5085f5af7f23SKarl Rupp   else {
508671f87433Sdalcinl     if (kctx->version == 1) {
508771f87433Sdalcinl       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
508871f87433Sdalcinl       if (rtol < 0.0) rtol = -rtol;
508985ec1a3cSBarry Smith       stol = PetscPowReal(kctx->rtol_last,kctx->alpha2);
509071f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
509171f87433Sdalcinl     } else if (kctx->version == 2) {
509285ec1a3cSBarry Smith       rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha);
509385ec1a3cSBarry Smith       stol = kctx->gamma * PetscPowReal(kctx->rtol_last,kctx->alpha);
509471f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
509571f87433Sdalcinl     } else if (kctx->version == 3) { /* contributed by Luis Chacon, June 2006. */
509685ec1a3cSBarry Smith       rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha);
509771f87433Sdalcinl       /* safeguard: avoid sharp decrease of rtol */
509885ec1a3cSBarry Smith       stol = kctx->gamma*PetscPowReal(kctx->rtol_last,kctx->alpha);
509971f87433Sdalcinl       stol = PetscMax(rtol,stol);
510071f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
510171f87433Sdalcinl       /* safeguard: avoid oversolving */
510230058271SDmitry Karpeev       stol = kctx->gamma*(kctx->norm_first*snes->rtol)/snes->norm;
510371f87433Sdalcinl       stol = PetscMax(rtol,stol);
510471f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
5105e32f2f54SBarry Smith     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
510671f87433Sdalcinl   }
510771f87433Sdalcinl   /* safeguard: avoid rtol greater than one */
510871f87433Sdalcinl   rtol = PetscMin(rtol,kctx->rtol_max);
510971f87433Sdalcinl   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
511057622a8eSBarry Smith   ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%g\n",snes->iter,kctx->version,(double)rtol);CHKERRQ(ierr);
511171f87433Sdalcinl   PetscFunctionReturn(0);
511271f87433Sdalcinl }
511371f87433Sdalcinl 
5114d5378b5fSDmitry Karpeev PetscErrorCode KSPPostSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes)
511571f87433Sdalcinl {
511671f87433Sdalcinl   PetscErrorCode ierr;
5117fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
511871f87433Sdalcinl   PCSide         pcside;
511971f87433Sdalcinl   Vec            lres;
512071f87433Sdalcinl 
512171f87433Sdalcinl   PetscFunctionBegin;
5122d4211eb9SBarry Smith   if (!snes->ksp_ewconv) PetscFunctionReturn(0);
512371f87433Sdalcinl   ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr);
512471dbe336SPeter Brune   kctx->norm_last = snes->norm;
512571f87433Sdalcinl   if (kctx->version == 1) {
51264f00ce20SMatthew G. Knepley     PC        pc;
51274f00ce20SMatthew G. Knepley     PetscBool isNone;
51284f00ce20SMatthew G. Knepley 
51294f00ce20SMatthew G. Knepley     ierr = KSPGetPC(ksp, &pc);CHKERRQ(ierr);
51304f00ce20SMatthew G. Knepley     ierr = PetscObjectTypeCompare((PetscObject) pc, PCNONE, &isNone);CHKERRQ(ierr);
5131b037da10SBarry Smith     ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr);
51324f00ce20SMatthew G. Knepley      if (pcside == PC_RIGHT || isNone) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
513371f87433Sdalcinl       /* KSP residual is true linear residual */
513471f87433Sdalcinl       ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr);
513571f87433Sdalcinl     } else {
513671f87433Sdalcinl       /* KSP residual is preconditioned residual */
513771f87433Sdalcinl       /* compute true linear residual norm */
513871f87433Sdalcinl       ierr = VecDuplicate(b,&lres);CHKERRQ(ierr);
513971f87433Sdalcinl       ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr);
514071f87433Sdalcinl       ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr);
514171f87433Sdalcinl       ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr);
51426bf464f9SBarry Smith       ierr = VecDestroy(&lres);CHKERRQ(ierr);
514371f87433Sdalcinl     }
514471f87433Sdalcinl   }
514571f87433Sdalcinl   PetscFunctionReturn(0);
514671f87433Sdalcinl }
514771f87433Sdalcinl 
5148d4211eb9SBarry Smith /*@
5149d4211eb9SBarry Smith    SNESGetKSP - Returns the KSP context for a SNES solver.
5150d4211eb9SBarry Smith 
5151d4211eb9SBarry Smith    Not Collective, but if SNES object is parallel, then KSP object is parallel
5152d4211eb9SBarry Smith 
5153d4211eb9SBarry Smith    Input Parameter:
5154d4211eb9SBarry Smith .  snes - the SNES context
5155d4211eb9SBarry Smith 
5156d4211eb9SBarry Smith    Output Parameter:
5157d4211eb9SBarry Smith .  ksp - the KSP context
5158d4211eb9SBarry Smith 
5159d4211eb9SBarry Smith    Notes:
5160d4211eb9SBarry Smith    The user can then directly manipulate the KSP context to set various
5161d4211eb9SBarry Smith    options, etc.  Likewise, the user can then extract and manipulate the
5162d4211eb9SBarry Smith    PC contexts as well.
5163d4211eb9SBarry Smith 
5164d4211eb9SBarry Smith    Level: beginner
5165d4211eb9SBarry Smith 
5166d4211eb9SBarry Smith .keywords: SNES, nonlinear, get, KSP, context
5167d4211eb9SBarry Smith 
5168d4211eb9SBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
5169d4211eb9SBarry Smith @*/
5170d4211eb9SBarry Smith PetscErrorCode  SNESGetKSP(SNES snes,KSP *ksp)
517171f87433Sdalcinl {
517271f87433Sdalcinl   PetscErrorCode ierr;
517371f87433Sdalcinl 
517471f87433Sdalcinl   PetscFunctionBegin;
5175d4211eb9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5176d4211eb9SBarry Smith   PetscValidPointer(ksp,2);
5177d4211eb9SBarry Smith 
5178d4211eb9SBarry Smith   if (!snes->ksp) {
5179a5c2985bSBarry Smith     PetscBool monitor = PETSC_FALSE;
5180a5c2985bSBarry Smith 
5181d4211eb9SBarry Smith     ierr = KSPCreate(PetscObjectComm((PetscObject)snes),&snes->ksp);CHKERRQ(ierr);
5182d4211eb9SBarry Smith     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr);
51833bb1ff40SBarry Smith     ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->ksp);CHKERRQ(ierr);
5184d4211eb9SBarry Smith 
5185d5378b5fSDmitry Karpeev     ierr = KSPSetPreSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPreSolve_SNESEW,snes);CHKERRQ(ierr);
5186d5378b5fSDmitry Karpeev     ierr = KSPSetPostSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPostSolve_SNESEW,snes);CHKERRQ(ierr);
5187a5c2985bSBarry Smith 
5188c5929fdfSBarry Smith     ierr = PetscOptionsGetBool(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-ksp_monitor_snes",&monitor,NULL);CHKERRQ(ierr);
5189a5c2985bSBarry Smith     if (monitor) {
5190a5c2985bSBarry Smith       ierr = KSPMonitorSet(snes->ksp,KSPMonitorSNES,snes,NULL);CHKERRQ(ierr);
5191a5c2985bSBarry Smith     }
5192e5f7ee39SBarry Smith     monitor = PETSC_FALSE;
5193c5929fdfSBarry Smith     ierr = PetscOptionsGetBool(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-ksp_monitor_snes_lg",&monitor,NULL);CHKERRQ(ierr);
5194e5f7ee39SBarry Smith     if (monitor) {
5195e5f7ee39SBarry Smith       PetscObject *objs;
51968b0b5a47SLisandro Dalcin       ierr = KSPMonitorSNESLGResidualNormCreate(PetscObjectComm((PetscObject)snes),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,600,600,&objs);CHKERRQ(ierr);
5197e5f7ee39SBarry Smith       objs[0] = (PetscObject) snes;
5198e5f7ee39SBarry Smith       ierr = KSPMonitorSet(snes->ksp,(PetscErrorCode (*)(KSP,PetscInt,PetscReal,void*))KSPMonitorSNESLGResidualNorm,objs,(PetscErrorCode (*)(void**))KSPMonitorSNESLGResidualNormDestroy);CHKERRQ(ierr);
5199e5f7ee39SBarry Smith     }
5200d4211eb9SBarry Smith   }
5201d4211eb9SBarry Smith   *ksp = snes->ksp;
520271f87433Sdalcinl   PetscFunctionReturn(0);
520371f87433Sdalcinl }
52046c699258SBarry Smith 
5205d4211eb9SBarry Smith 
5206af0996ceSBarry Smith #include <petsc/private/dmimpl.h>
52076c699258SBarry Smith /*@
52082a808120SBarry Smith    SNESSetDM - Sets the DM that may be used by some nonlinear solvers or their underlying preconditioners
52096c699258SBarry Smith 
52103f9fe445SBarry Smith    Logically Collective on SNES
52116c699258SBarry Smith 
52126c699258SBarry Smith    Input Parameters:
52132a808120SBarry Smith +  snes - the nonlinear solver context
52142a808120SBarry Smith -  dm - the dm, cannot be NULL
52156c699258SBarry Smith 
5216e03a659cSJed Brown    Notes:
5217e03a659cSJed Brown    A DM can only be used for solving one problem at a time because information about the problem is stored on the DM,
5218e03a659cSJed Brown    even when not using interfaces like DMSNESSetFunction().  Use DMClone() to get a distinct DM when solving different
5219e03a659cSJed Brown    problems using the same function space.
5220e03a659cSJed Brown 
52216c699258SBarry Smith    Level: intermediate
52226c699258SBarry Smith 
52234c2026ceSFande Kong .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM()
52246c699258SBarry Smith @*/
52257087cfbeSBarry Smith PetscErrorCode  SNESSetDM(SNES snes,DM dm)
52266c699258SBarry Smith {
52276c699258SBarry Smith   PetscErrorCode ierr;
5228345fed2cSBarry Smith   KSP            ksp;
5229942e3340SBarry Smith   DMSNES         sdm;
52306c699258SBarry Smith 
52316c699258SBarry Smith   PetscFunctionBegin;
52320700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
52332a808120SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,2);
52342a808120SBarry Smith   ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);
5235942e3340SBarry Smith   if (snes->dm) {               /* Move the DMSNES context over to the new DM unless the new DM already has one */
523651f4b3c7SToby Isaac     if (snes->dm->dmsnes && !dm->dmsnes) {
5237942e3340SBarry Smith       ierr = DMCopyDMSNES(snes->dm,dm);CHKERRQ(ierr);
5238942e3340SBarry Smith       ierr = DMGetDMSNES(snes->dm,&sdm);CHKERRQ(ierr);
5239f5af7f23SKarl Rupp       if (sdm->originaldm == snes->dm) sdm->originaldm = dm; /* Grant write privileges to the replacement DM */
52406cab3a1bSJed Brown     }
5241dc822a44SJed Brown     ierr = DMCoarsenHookRemove(snes->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr);
52426bf464f9SBarry Smith     ierr = DMDestroy(&snes->dm);CHKERRQ(ierr);
52436cab3a1bSJed Brown   }
52446c699258SBarry Smith   snes->dm     = dm;
5245116d1032SJed Brown   snes->dmAuto = PETSC_FALSE;
5246f5af7f23SKarl Rupp 
5247345fed2cSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
5248345fed2cSBarry Smith   ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr);
5249f22f69f0SBarry Smith   ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr);
5250efd4aadfSBarry Smith   if (snes->npc) {
5251efd4aadfSBarry Smith     ierr = SNESSetDM(snes->npc, snes->dm);CHKERRQ(ierr);
5252efd4aadfSBarry Smith     ierr = SNESSetNPCSide(snes,snes->npcside);CHKERRQ(ierr);
52532c155ee1SBarry Smith   }
52546c699258SBarry Smith   PetscFunctionReturn(0);
52556c699258SBarry Smith }
52566c699258SBarry Smith 
52576c699258SBarry Smith /*@
52586c699258SBarry Smith    SNESGetDM - Gets the DM that may be used by some preconditioners
52596c699258SBarry Smith 
52603f9fe445SBarry Smith    Not Collective but DM obtained is parallel on SNES
52616c699258SBarry Smith 
52626c699258SBarry Smith    Input Parameter:
52636c699258SBarry Smith . snes - the preconditioner context
52646c699258SBarry Smith 
52656c699258SBarry Smith    Output Parameter:
52666c699258SBarry Smith .  dm - the dm
52676c699258SBarry Smith 
52686c699258SBarry Smith    Level: intermediate
52696c699258SBarry Smith 
52704c2026ceSFande Kong .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM()
52716c699258SBarry Smith @*/
52727087cfbeSBarry Smith PetscErrorCode  SNESGetDM(SNES snes,DM *dm)
52736c699258SBarry Smith {
52746cab3a1bSJed Brown   PetscErrorCode ierr;
52756cab3a1bSJed Brown 
52766c699258SBarry Smith   PetscFunctionBegin;
52770700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
52786cab3a1bSJed Brown   if (!snes->dm) {
5279ce94432eSBarry Smith     ierr         = DMShellCreate(PetscObjectComm((PetscObject)snes),&snes->dm);CHKERRQ(ierr);
5280116d1032SJed Brown     snes->dmAuto = PETSC_TRUE;
52816cab3a1bSJed Brown   }
52826c699258SBarry Smith   *dm = snes->dm;
52836c699258SBarry Smith   PetscFunctionReturn(0);
52846c699258SBarry Smith }
52850807856dSBarry Smith 
528631823bd8SMatthew G Knepley /*@
5287be95d8f1SBarry Smith   SNESSetNPC - Sets the nonlinear preconditioner to be used.
528831823bd8SMatthew G Knepley 
528931823bd8SMatthew G Knepley   Collective on SNES
529031823bd8SMatthew G Knepley 
529131823bd8SMatthew G Knepley   Input Parameters:
529231823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate()
529331823bd8SMatthew G Knepley - pc   - the preconditioner object
529431823bd8SMatthew G Knepley 
529531823bd8SMatthew G Knepley   Notes:
5296be95d8f1SBarry Smith   Use SNESGetNPC() to retrieve the preconditioner context (for example,
529731823bd8SMatthew G Knepley   to configure it using the API).
529831823bd8SMatthew G Knepley 
529931823bd8SMatthew G Knepley   Level: developer
530031823bd8SMatthew G Knepley 
530131823bd8SMatthew G Knepley .keywords: SNES, set, precondition
53023ad1a0b9SPatrick Farrell .seealso: SNESGetNPC(), SNESHasNPC()
530331823bd8SMatthew G Knepley @*/
5304be95d8f1SBarry Smith PetscErrorCode SNESSetNPC(SNES snes, SNES pc)
530531823bd8SMatthew G Knepley {
530631823bd8SMatthew G Knepley   PetscErrorCode ierr;
530731823bd8SMatthew G Knepley 
530831823bd8SMatthew G Knepley   PetscFunctionBegin;
530931823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
531031823bd8SMatthew G Knepley   PetscValidHeaderSpecific(pc, SNES_CLASSID, 2);
531131823bd8SMatthew G Knepley   PetscCheckSameComm(snes, 1, pc, 2);
531231823bd8SMatthew G Knepley   ierr     = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr);
5313efd4aadfSBarry Smith   ierr     = SNESDestroy(&snes->npc);CHKERRQ(ierr);
5314efd4aadfSBarry Smith   snes->npc = pc;
5315efd4aadfSBarry Smith   ierr     = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->npc);CHKERRQ(ierr);
531631823bd8SMatthew G Knepley   PetscFunctionReturn(0);
531731823bd8SMatthew G Knepley }
531831823bd8SMatthew G Knepley 
531931823bd8SMatthew G Knepley /*@
5320be95d8f1SBarry Smith   SNESGetNPC - Creates a nonlinear preconditioning solver (SNES) to be used to precondition the nonlinear solver.
532131823bd8SMatthew G Knepley 
532231823bd8SMatthew G Knepley   Not Collective
532331823bd8SMatthew G Knepley 
532431823bd8SMatthew G Knepley   Input Parameter:
532531823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate()
532631823bd8SMatthew G Knepley 
532731823bd8SMatthew G Knepley   Output Parameter:
532831823bd8SMatthew G Knepley . pc - preconditioner context
532931823bd8SMatthew G Knepley 
533095452b02SPatrick Sanan   Notes:
533195452b02SPatrick Sanan     If a SNES was previously set with SNESSetNPC() then that SNES is returned.
5332be95d8f1SBarry Smith 
533331823bd8SMatthew G Knepley   Level: developer
533431823bd8SMatthew G Knepley 
533531823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner
53363ad1a0b9SPatrick Farrell .seealso: SNESSetNPC(), SNESHasNPC()
533731823bd8SMatthew G Knepley @*/
5338be95d8f1SBarry Smith PetscErrorCode SNESGetNPC(SNES snes, SNES *pc)
533931823bd8SMatthew G Knepley {
534031823bd8SMatthew G Knepley   PetscErrorCode ierr;
5341a64e098fSPeter Brune   const char     *optionsprefix;
534231823bd8SMatthew G Knepley 
534331823bd8SMatthew G Knepley   PetscFunctionBegin;
534431823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
534531823bd8SMatthew G Knepley   PetscValidPointer(pc, 2);
5346efd4aadfSBarry Smith   if (!snes->npc) {
5347efd4aadfSBarry Smith     ierr = SNESCreate(PetscObjectComm((PetscObject)snes),&snes->npc);CHKERRQ(ierr);
5348efd4aadfSBarry Smith     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->npc,(PetscObject)snes,1);CHKERRQ(ierr);
5349efd4aadfSBarry Smith     ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->npc);CHKERRQ(ierr);
5350a64e098fSPeter Brune     ierr = SNESGetOptionsPrefix(snes,&optionsprefix);CHKERRQ(ierr);
5351efd4aadfSBarry Smith     ierr = SNESSetOptionsPrefix(snes->npc,optionsprefix);CHKERRQ(ierr);
5352efd4aadfSBarry Smith     ierr = SNESAppendOptionsPrefix(snes->npc,"npc_");CHKERRQ(ierr);
5353efd4aadfSBarry Smith     ierr = SNESSetCountersReset(snes->npc,PETSC_FALSE);CHKERRQ(ierr);
535431823bd8SMatthew G Knepley   }
5355efd4aadfSBarry Smith   *pc = snes->npc;
535631823bd8SMatthew G Knepley   PetscFunctionReturn(0);
535731823bd8SMatthew G Knepley }
535831823bd8SMatthew G Knepley 
53593ad1a0b9SPatrick Farrell /*@
53603ad1a0b9SPatrick Farrell   SNESHasNPC - Returns whether a nonlinear preconditioner exists
53613ad1a0b9SPatrick Farrell 
53623ad1a0b9SPatrick Farrell   Not Collective
53633ad1a0b9SPatrick Farrell 
53643ad1a0b9SPatrick Farrell   Input Parameter:
53653ad1a0b9SPatrick Farrell . snes - iterative context obtained from SNESCreate()
53663ad1a0b9SPatrick Farrell 
53673ad1a0b9SPatrick Farrell   Output Parameter:
53683ad1a0b9SPatrick Farrell . has_npc - whether the SNES has an NPC or not
53693ad1a0b9SPatrick Farrell 
53703ad1a0b9SPatrick Farrell   Level: developer
53713ad1a0b9SPatrick Farrell 
53723ad1a0b9SPatrick Farrell .keywords: SNES, has, preconditioner
53733ad1a0b9SPatrick Farrell .seealso: SNESSetNPC(), SNESGetNPC()
53743ad1a0b9SPatrick Farrell @*/
53753ad1a0b9SPatrick Farrell PetscErrorCode SNESHasNPC(SNES snes, PetscBool *has_npc)
53763ad1a0b9SPatrick Farrell {
53773ad1a0b9SPatrick Farrell   PetscFunctionBegin;
53783ad1a0b9SPatrick Farrell   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5379efd4aadfSBarry Smith   *has_npc = (PetscBool) (snes->npc ? PETSC_TRUE : PETSC_FALSE);
53803ad1a0b9SPatrick Farrell   PetscFunctionReturn(0);
53813ad1a0b9SPatrick Farrell }
53823ad1a0b9SPatrick Farrell 
5383c40d0f55SPeter Brune /*@
5384be95d8f1SBarry Smith     SNESSetNPCSide - Sets the preconditioning side.
5385c40d0f55SPeter Brune 
5386c40d0f55SPeter Brune     Logically Collective on SNES
5387c40d0f55SPeter Brune 
5388c40d0f55SPeter Brune     Input Parameter:
5389c40d0f55SPeter Brune .   snes - iterative context obtained from SNESCreate()
5390c40d0f55SPeter Brune 
5391c40d0f55SPeter Brune     Output Parameter:
5392c40d0f55SPeter Brune .   side - the preconditioning side, where side is one of
5393c40d0f55SPeter Brune .vb
53942d547940SBarry Smith       PC_LEFT - left preconditioning
53952d547940SBarry Smith       PC_RIGHT - right preconditioning (default for most nonlinear solvers)
5396c40d0f55SPeter Brune .ve
5397c40d0f55SPeter Brune 
5398c40d0f55SPeter Brune     Options Database Keys:
5399c40d0f55SPeter Brune .   -snes_pc_side <right,left>
5400c40d0f55SPeter Brune 
540195452b02SPatrick Sanan     Notes:
540295452b02SPatrick Sanan     SNESNRICHARDSON and SNESNCG only support left preconditioning.
54032d547940SBarry Smith 
5404c40d0f55SPeter Brune     Level: intermediate
5405c40d0f55SPeter Brune 
5406c40d0f55SPeter Brune .keywords: SNES, set, right, left, side, preconditioner, flag
5407c40d0f55SPeter Brune 
5408be95d8f1SBarry Smith .seealso: SNESGetNPCSide(), KSPSetPCSide()
5409c40d0f55SPeter Brune @*/
5410be95d8f1SBarry Smith PetscErrorCode  SNESSetNPCSide(SNES snes,PCSide side)
5411c40d0f55SPeter Brune {
5412c40d0f55SPeter Brune   PetscFunctionBegin;
5413c40d0f55SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5414c40d0f55SPeter Brune   PetscValidLogicalCollectiveEnum(snes,side,2);
5415efd4aadfSBarry Smith   snes->npcside= side;
5416c40d0f55SPeter Brune   PetscFunctionReturn(0);
5417c40d0f55SPeter Brune }
5418c40d0f55SPeter Brune 
5419c40d0f55SPeter Brune /*@
5420be95d8f1SBarry Smith     SNESGetNPCSide - Gets the preconditioning side.
5421c40d0f55SPeter Brune 
5422c40d0f55SPeter Brune     Not Collective
5423c40d0f55SPeter Brune 
5424c40d0f55SPeter Brune     Input Parameter:
5425c40d0f55SPeter Brune .   snes - iterative context obtained from SNESCreate()
5426c40d0f55SPeter Brune 
5427c40d0f55SPeter Brune     Output Parameter:
5428c40d0f55SPeter Brune .   side - the preconditioning side, where side is one of
5429c40d0f55SPeter Brune .vb
54302d547940SBarry Smith       PC_LEFT - left preconditioning
54312d547940SBarry Smith       PC_RIGHT - right preconditioning (default for most nonlinear solvers)
5432c40d0f55SPeter Brune .ve
5433c40d0f55SPeter Brune 
5434c40d0f55SPeter Brune     Level: intermediate
5435c40d0f55SPeter Brune 
5436c40d0f55SPeter Brune .keywords: SNES, get, right, left, side, preconditioner, flag
5437c40d0f55SPeter Brune 
5438be95d8f1SBarry Smith .seealso: SNESSetNPCSide(), KSPGetPCSide()
5439c40d0f55SPeter Brune @*/
5440be95d8f1SBarry Smith PetscErrorCode  SNESGetNPCSide(SNES snes,PCSide *side)
5441c40d0f55SPeter Brune {
5442c40d0f55SPeter Brune   PetscFunctionBegin;
5443c40d0f55SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5444c40d0f55SPeter Brune   PetscValidPointer(side,2);
5445efd4aadfSBarry Smith   *side = snes->npcside;
5446c40d0f55SPeter Brune   PetscFunctionReturn(0);
5447c40d0f55SPeter Brune }
5448c40d0f55SPeter Brune 
54499e764e56SPeter Brune /*@
54507601faf0SJed Brown   SNESSetLineSearch - Sets the linesearch on the SNES instance.
54519e764e56SPeter Brune 
54529e764e56SPeter Brune   Collective on SNES
54539e764e56SPeter Brune 
54549e764e56SPeter Brune   Input Parameters:
54559e764e56SPeter Brune + snes - iterative context obtained from SNESCreate()
54569e764e56SPeter Brune - linesearch   - the linesearch object
54579e764e56SPeter Brune 
54589e764e56SPeter Brune   Notes:
54597601faf0SJed Brown   Use SNESGetLineSearch() to retrieve the preconditioner context (for example,
54609e764e56SPeter Brune   to configure it using the API).
54619e764e56SPeter Brune 
54629e764e56SPeter Brune   Level: developer
54639e764e56SPeter Brune 
54649e764e56SPeter Brune .keywords: SNES, set, linesearch
54657601faf0SJed Brown .seealso: SNESGetLineSearch()
54669e764e56SPeter Brune @*/
54677601faf0SJed Brown PetscErrorCode SNESSetLineSearch(SNES snes, SNESLineSearch linesearch)
54689e764e56SPeter Brune {
54699e764e56SPeter Brune   PetscErrorCode ierr;
54709e764e56SPeter Brune 
54719e764e56SPeter Brune   PetscFunctionBegin;
54729e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5473f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2);
54749e764e56SPeter Brune   PetscCheckSameComm(snes, 1, linesearch, 2);
54759e764e56SPeter Brune   ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr);
5476f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr);
5477f5af7f23SKarl Rupp 
54789e764e56SPeter Brune   snes->linesearch = linesearch;
5479f5af7f23SKarl Rupp 
54803bb1ff40SBarry Smith   ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch);CHKERRQ(ierr);
54819e764e56SPeter Brune   PetscFunctionReturn(0);
54829e764e56SPeter Brune }
54839e764e56SPeter Brune 
5484a34ceb2aSJed Brown /*@
54857601faf0SJed Brown   SNESGetLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch()
54868141a3b9SPeter Brune   or creates a default line search instance associated with the SNES and returns it.
54879e764e56SPeter Brune 
54889e764e56SPeter Brune   Not Collective
54899e764e56SPeter Brune 
54909e764e56SPeter Brune   Input Parameter:
54919e764e56SPeter Brune . snes - iterative context obtained from SNESCreate()
54929e764e56SPeter Brune 
54939e764e56SPeter Brune   Output Parameter:
54949e764e56SPeter Brune . linesearch - linesearch context
54959e764e56SPeter Brune 
5496162e0bf5SPeter Brune   Level: beginner
54979e764e56SPeter Brune 
54989e764e56SPeter Brune .keywords: SNES, get, linesearch
5499162e0bf5SPeter Brune .seealso: SNESSetLineSearch(), SNESLineSearchCreate()
55009e764e56SPeter Brune @*/
55017601faf0SJed Brown PetscErrorCode SNESGetLineSearch(SNES snes, SNESLineSearch *linesearch)
55029e764e56SPeter Brune {
55039e764e56SPeter Brune   PetscErrorCode ierr;
55049e764e56SPeter Brune   const char     *optionsprefix;
55059e764e56SPeter Brune 
55069e764e56SPeter Brune   PetscFunctionBegin;
55079e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
55089e764e56SPeter Brune   PetscValidPointer(linesearch, 2);
55099e764e56SPeter Brune   if (!snes->linesearch) {
55109e764e56SPeter Brune     ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
551182f516ccSBarry Smith     ierr = SNESLineSearchCreate(PetscObjectComm((PetscObject)snes), &snes->linesearch);CHKERRQ(ierr);
5512f1c6b773SPeter Brune     ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr);
5513b1dca40bSPeter Brune     ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr);
55149e764e56SPeter Brune     ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr);
55153bb1ff40SBarry Smith     ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch);CHKERRQ(ierr);
55169e764e56SPeter Brune   }
55179e764e56SPeter Brune   *linesearch = snes->linesearch;
55189e764e56SPeter Brune   PetscFunctionReturn(0);
55199e764e56SPeter Brune }
55209e764e56SPeter Brune 
552169b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
5522c6db04a5SJed Brown #include <mex.h>
552369b4f73cSBarry Smith 
55248f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext;
55258f6e6473SBarry Smith 
55260807856dSBarry Smith /*
5527bf388a1fSBarry Smith    SNESComputeFunction_Matlab - Calls the function that has been set with SNESSetFunctionMatlab().
55280807856dSBarry Smith 
55290807856dSBarry Smith    Collective on SNES
55300807856dSBarry Smith 
55310807856dSBarry Smith    Input Parameters:
55320807856dSBarry Smith +  snes - the SNES context
55330807856dSBarry Smith -  x - input vector
55340807856dSBarry Smith 
55350807856dSBarry Smith    Output Parameter:
55360807856dSBarry Smith .  y - function vector, as set by SNESSetFunction()
55370807856dSBarry Smith 
55380807856dSBarry Smith    Notes:
55390807856dSBarry Smith    SNESComputeFunction() is typically used within nonlinear solvers
55400807856dSBarry Smith    implementations, so most users would not generally call this routine
55410807856dSBarry Smith    themselves.
55420807856dSBarry Smith 
55430807856dSBarry Smith    Level: developer
55440807856dSBarry Smith 
55450807856dSBarry Smith .keywords: SNES, nonlinear, compute, function
55460807856dSBarry Smith 
55470807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
554861b2408cSBarry Smith */
55497087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx)
55500807856dSBarry Smith {
5551e650e774SBarry Smith   PetscErrorCode    ierr;
55528f6e6473SBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext*)ctx;
55538f6e6473SBarry Smith   int               nlhs  = 1,nrhs = 5;
55548f6e6473SBarry Smith   mxArray           *plhs[1],*prhs[5];
555591621f2eSBarry Smith   long long int     lx = 0,ly = 0,ls = 0;
5556e650e774SBarry Smith 
55570807856dSBarry Smith   PetscFunctionBegin;
55580807856dSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
55590807856dSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
55600807856dSBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
55610807856dSBarry Smith   PetscCheckSameComm(snes,1,x,2);
55620807856dSBarry Smith   PetscCheckSameComm(snes,1,y,3);
55630807856dSBarry Smith 
55640807856dSBarry Smith   /* call Matlab function in ctx with arguments x and y */
5565e650e774SBarry Smith 
556691621f2eSBarry Smith   ierr    = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
5567e650e774SBarry Smith   ierr    = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
5568e650e774SBarry Smith   ierr    = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr);
556991621f2eSBarry Smith   prhs[0] = mxCreateDoubleScalar((double)ls);
557091621f2eSBarry Smith   prhs[1] = mxCreateDoubleScalar((double)lx);
557191621f2eSBarry Smith   prhs[2] = mxCreateDoubleScalar((double)ly);
55728f6e6473SBarry Smith   prhs[3] = mxCreateString(sctx->funcname);
55738f6e6473SBarry Smith   prhs[4] = sctx->ctx;
5574b807a863SBarry Smith   ierr    = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr);
5575e650e774SBarry Smith   ierr    = mxGetScalar(plhs[0]);CHKERRQ(ierr);
5576e650e774SBarry Smith   mxDestroyArray(prhs[0]);
5577e650e774SBarry Smith   mxDestroyArray(prhs[1]);
5578e650e774SBarry Smith   mxDestroyArray(prhs[2]);
55798f6e6473SBarry Smith   mxDestroyArray(prhs[3]);
5580e650e774SBarry Smith   mxDestroyArray(plhs[0]);
55810807856dSBarry Smith   PetscFunctionReturn(0);
55820807856dSBarry Smith }
55830807856dSBarry Smith 
558461b2408cSBarry Smith /*
55850807856dSBarry Smith    SNESSetFunctionMatlab - Sets the function evaluation routine and function
55860807856dSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
5587e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
55880807856dSBarry Smith 
55890807856dSBarry Smith    Logically Collective on SNES
55900807856dSBarry Smith 
55910807856dSBarry Smith    Input Parameters:
55920807856dSBarry Smith +  snes - the SNES context
55930807856dSBarry Smith .  r - vector to store function value
5594f8b49ee9SBarry Smith -  f - function evaluation routine
55950807856dSBarry Smith 
55960807856dSBarry Smith    Notes:
55970807856dSBarry Smith    The Newton-like methods typically solve linear systems of the form
55980807856dSBarry Smith $      f'(x) x = -f(x),
55990807856dSBarry Smith    where f'(x) denotes the Jacobian matrix and f(x) is the function.
56000807856dSBarry Smith 
56010807856dSBarry Smith    Level: beginner
56020807856dSBarry Smith 
5603c5b75c40SBarry Smith    Developer Note:  This bleeds the allocated memory SNESMatlabContext *sctx;
5604c5b75c40SBarry Smith 
56050807856dSBarry Smith .keywords: SNES, nonlinear, set, function
56060807856dSBarry Smith 
56070807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
560861b2408cSBarry Smith */
5609f8b49ee9SBarry Smith PetscErrorCode  SNESSetFunctionMatlab(SNES snes,Vec r,const char *f,mxArray *ctx)
56100807856dSBarry Smith {
56110807856dSBarry Smith   PetscErrorCode    ierr;
56128f6e6473SBarry Smith   SNESMatlabContext *sctx;
56130807856dSBarry Smith 
56140807856dSBarry Smith   PetscFunctionBegin;
56158f6e6473SBarry Smith   /* currently sctx is memory bleed */
5616854ce69bSBarry Smith   ierr = PetscNew(&sctx);CHKERRQ(ierr);
5617f8b49ee9SBarry Smith   ierr = PetscStrallocpy(f,&sctx->funcname);CHKERRQ(ierr);
56188f6e6473SBarry Smith   /*
56198f6e6473SBarry Smith      This should work, but it doesn't
56208f6e6473SBarry Smith   sctx->ctx = ctx;
56218f6e6473SBarry Smith   mexMakeArrayPersistent(sctx->ctx);
56228f6e6473SBarry Smith   */
56238f6e6473SBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
56248f6e6473SBarry Smith   ierr      = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr);
56250807856dSBarry Smith   PetscFunctionReturn(0);
56260807856dSBarry Smith }
562769b4f73cSBarry Smith 
562861b2408cSBarry Smith /*
5629bf388a1fSBarry Smith    SNESComputeJacobian_Matlab - Calls the function that has been set with SNESSetJacobianMatlab().
563061b2408cSBarry Smith 
563161b2408cSBarry Smith    Collective on SNES
563261b2408cSBarry Smith 
563361b2408cSBarry Smith    Input Parameters:
563461b2408cSBarry Smith +  snes - the SNES context
563561b2408cSBarry Smith .  x - input vector
563661b2408cSBarry Smith .  A, B - the matrices
563761b2408cSBarry Smith -  ctx - user context
563861b2408cSBarry Smith 
563961b2408cSBarry Smith    Level: developer
564061b2408cSBarry Smith 
564161b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function
564261b2408cSBarry Smith 
564361b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
564461b2408cSBarry Smith @*/
5645f3229a78SSatish Balay PetscErrorCode  SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat A,Mat B,void *ctx)
564661b2408cSBarry Smith {
564761b2408cSBarry Smith   PetscErrorCode    ierr;
564861b2408cSBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext*)ctx;
564961b2408cSBarry Smith   int               nlhs  = 2,nrhs = 6;
565061b2408cSBarry Smith   mxArray           *plhs[2],*prhs[6];
565161b2408cSBarry Smith   long long int     lx = 0,lA = 0,ls = 0, lB = 0;
565261b2408cSBarry Smith 
565361b2408cSBarry Smith   PetscFunctionBegin;
565461b2408cSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
565561b2408cSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
565661b2408cSBarry Smith 
565761b2408cSBarry Smith   /* call Matlab function in ctx with arguments x and y */
565861b2408cSBarry Smith 
565961b2408cSBarry Smith   ierr    = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
566061b2408cSBarry Smith   ierr    = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
566161b2408cSBarry Smith   ierr    = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr);
566261b2408cSBarry Smith   ierr    = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr);
566361b2408cSBarry Smith   prhs[0] = mxCreateDoubleScalar((double)ls);
566461b2408cSBarry Smith   prhs[1] = mxCreateDoubleScalar((double)lx);
566561b2408cSBarry Smith   prhs[2] = mxCreateDoubleScalar((double)lA);
566661b2408cSBarry Smith   prhs[3] = mxCreateDoubleScalar((double)lB);
566761b2408cSBarry Smith   prhs[4] = mxCreateString(sctx->funcname);
566861b2408cSBarry Smith   prhs[5] = sctx->ctx;
5669b807a863SBarry Smith   ierr    = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr);
567061b2408cSBarry Smith   ierr    = mxGetScalar(plhs[0]);CHKERRQ(ierr);
567161b2408cSBarry Smith   mxDestroyArray(prhs[0]);
567261b2408cSBarry Smith   mxDestroyArray(prhs[1]);
567361b2408cSBarry Smith   mxDestroyArray(prhs[2]);
567461b2408cSBarry Smith   mxDestroyArray(prhs[3]);
567561b2408cSBarry Smith   mxDestroyArray(prhs[4]);
567661b2408cSBarry Smith   mxDestroyArray(plhs[0]);
567761b2408cSBarry Smith   mxDestroyArray(plhs[1]);
567861b2408cSBarry Smith   PetscFunctionReturn(0);
567961b2408cSBarry Smith }
568061b2408cSBarry Smith 
568161b2408cSBarry Smith /*
568261b2408cSBarry Smith    SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
568361b2408cSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
5684e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
568561b2408cSBarry Smith 
568661b2408cSBarry Smith    Logically Collective on SNES
568761b2408cSBarry Smith 
568861b2408cSBarry Smith    Input Parameters:
568961b2408cSBarry Smith +  snes - the SNES context
569061b2408cSBarry Smith .  A,B - Jacobian matrices
5691f8b49ee9SBarry Smith .  J - function evaluation routine
569261b2408cSBarry Smith -  ctx - user context
569361b2408cSBarry Smith 
569461b2408cSBarry Smith    Level: developer
569561b2408cSBarry Smith 
5696c5b75c40SBarry Smith    Developer Note:  This bleeds the allocated memory SNESMatlabContext *sctx;
5697c5b75c40SBarry Smith 
569861b2408cSBarry Smith .keywords: SNES, nonlinear, set, function
569961b2408cSBarry Smith 
5700f8b49ee9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction(), J
570161b2408cSBarry Smith */
5702f8b49ee9SBarry Smith PetscErrorCode  SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *J,mxArray *ctx)
570361b2408cSBarry Smith {
570461b2408cSBarry Smith   PetscErrorCode    ierr;
570561b2408cSBarry Smith   SNESMatlabContext *sctx;
570661b2408cSBarry Smith 
570761b2408cSBarry Smith   PetscFunctionBegin;
570861b2408cSBarry Smith   /* currently sctx is memory bleed */
5709854ce69bSBarry Smith   ierr = PetscNew(&sctx);CHKERRQ(ierr);
5710f8b49ee9SBarry Smith   ierr = PetscStrallocpy(J,&sctx->funcname);CHKERRQ(ierr);
571161b2408cSBarry Smith   /*
571261b2408cSBarry Smith      This should work, but it doesn't
571361b2408cSBarry Smith   sctx->ctx = ctx;
571461b2408cSBarry Smith   mexMakeArrayPersistent(sctx->ctx);
571561b2408cSBarry Smith   */
571661b2408cSBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
571761b2408cSBarry Smith   ierr      = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
571861b2408cSBarry Smith   PetscFunctionReturn(0);
571961b2408cSBarry Smith }
572069b4f73cSBarry Smith 
5721f9eb7ae2SShri Abhyankar /*
5722f9eb7ae2SShri Abhyankar    SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab().
5723f9eb7ae2SShri Abhyankar 
5724f9eb7ae2SShri Abhyankar    Collective on SNES
5725f9eb7ae2SShri Abhyankar 
5726f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction()
5727f9eb7ae2SShri Abhyankar @*/
57287087cfbeSBarry Smith PetscErrorCode  SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx)
5729f9eb7ae2SShri Abhyankar {
5730f9eb7ae2SShri Abhyankar   PetscErrorCode    ierr;
573148f37e70SShri Abhyankar   SNESMatlabContext *sctx = (SNESMatlabContext*)ctx;
5732f9eb7ae2SShri Abhyankar   int               nlhs  = 1,nrhs = 6;
5733f9eb7ae2SShri Abhyankar   mxArray           *plhs[1],*prhs[6];
5734f9eb7ae2SShri Abhyankar   long long int     lx = 0,ls = 0;
5735f9eb7ae2SShri Abhyankar   Vec               x  = snes->vec_sol;
5736f9eb7ae2SShri Abhyankar 
5737f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
5738f9eb7ae2SShri Abhyankar   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5739f9eb7ae2SShri Abhyankar 
5740f9eb7ae2SShri Abhyankar   ierr    = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
5741f9eb7ae2SShri Abhyankar   ierr    = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
5742f9eb7ae2SShri Abhyankar   prhs[0] = mxCreateDoubleScalar((double)ls);
5743f9eb7ae2SShri Abhyankar   prhs[1] = mxCreateDoubleScalar((double)it);
5744f9eb7ae2SShri Abhyankar   prhs[2] = mxCreateDoubleScalar((double)fnorm);
5745f9eb7ae2SShri Abhyankar   prhs[3] = mxCreateDoubleScalar((double)lx);
5746f9eb7ae2SShri Abhyankar   prhs[4] = mxCreateString(sctx->funcname);
5747f9eb7ae2SShri Abhyankar   prhs[5] = sctx->ctx;
5748f9eb7ae2SShri Abhyankar   ierr    = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr);
5749f9eb7ae2SShri Abhyankar   ierr    = mxGetScalar(plhs[0]);CHKERRQ(ierr);
5750f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[0]);
5751f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[1]);
5752f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[2]);
5753f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[3]);
5754f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[4]);
5755f9eb7ae2SShri Abhyankar   mxDestroyArray(plhs[0]);
5756f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
5757f9eb7ae2SShri Abhyankar }
5758f9eb7ae2SShri Abhyankar 
5759f9eb7ae2SShri Abhyankar /*
5760e3c5b3baSBarry Smith    SNESMonitorSetMatlab - Sets the monitor function from MATLAB
5761f9eb7ae2SShri Abhyankar 
5762f9eb7ae2SShri Abhyankar    Level: developer
5763f9eb7ae2SShri Abhyankar 
5764c5b75c40SBarry Smith    Developer Note:  This bleeds the allocated memory SNESMatlabContext *sctx;
5765c5b75c40SBarry Smith 
5766f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function
5767f9eb7ae2SShri Abhyankar 
5768f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
5769f9eb7ae2SShri Abhyankar */
57706e4dcb14SBarry Smith PetscErrorCode  SNESMonitorSetMatlab(SNES snes,const char *f,mxArray *ctx)
5771f9eb7ae2SShri Abhyankar {
5772f9eb7ae2SShri Abhyankar   PetscErrorCode    ierr;
5773f9eb7ae2SShri Abhyankar   SNESMatlabContext *sctx;
5774f9eb7ae2SShri Abhyankar 
5775f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
5776f9eb7ae2SShri Abhyankar   /* currently sctx is memory bleed */
5777854ce69bSBarry Smith   ierr = PetscNew(&sctx);CHKERRQ(ierr);
57786e4dcb14SBarry Smith   ierr = PetscStrallocpy(f,&sctx->funcname);CHKERRQ(ierr);
5779f9eb7ae2SShri Abhyankar   /*
5780f9eb7ae2SShri Abhyankar      This should work, but it doesn't
5781f9eb7ae2SShri Abhyankar   sctx->ctx = ctx;
5782f9eb7ae2SShri Abhyankar   mexMakeArrayPersistent(sctx->ctx);
5783f9eb7ae2SShri Abhyankar   */
5784f9eb7ae2SShri Abhyankar   sctx->ctx = mxDuplicateArray(ctx);
57850298fd71SBarry Smith   ierr      = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,NULL);CHKERRQ(ierr);
5786f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
5787f9eb7ae2SShri Abhyankar }
5788f9eb7ae2SShri Abhyankar 
578969b4f73cSBarry Smith #endif
5790