xref: /petsc/src/snes/interface/snes.c (revision 3565c898c89cc78b131e617771ef663cab4acd4e)
19b94acceSBarry Smith 
2af0996ceSBarry Smith #include <petsc/private/snesimpl.h>      /*I "petscsnes.h"  I*/
307475bc1SBarry Smith #include <petscdmshell.h>
4d96771aaSLisandro Dalcin #include <petscdraw.h>
5a01aa210SMatthew G. Knepley #include <petscds.h>
69b94acceSBarry Smith 
7ace3abfcSBarry Smith PetscBool         SNESRegisterAllCalled = PETSC_FALSE;
80298fd71SBarry Smith PetscFunctionList SNESList              = NULL;
98ba1e511SMatthew Knepley 
108ba1e511SMatthew Knepley /* Logging support */
1122c6f798SBarry Smith PetscClassId  SNES_CLASSID, DMSNES_CLASSID;
1294db00ebSBarry Smith PetscLogEvent SNES_Solve, SNES_FunctionEval, SNES_JacobianEval, SNES_NGSEval, SNES_NGSFuncEval, SNES_NPCSolve, SNES_ObjectiveEval;
13a09944afSBarry Smith 
14e113a28aSBarry Smith /*@
15e113a28aSBarry Smith    SNESSetErrorIfNotConverged - Causes SNESSolve() to generate an error if the solver has not converged.
16e113a28aSBarry Smith 
173f9fe445SBarry Smith    Logically Collective on SNES
18e113a28aSBarry Smith 
19e113a28aSBarry Smith    Input Parameters:
20e113a28aSBarry Smith +  snes - iterative context obtained from SNESCreate()
21e113a28aSBarry Smith -  flg - PETSC_TRUE indicates you want the error generated
22e113a28aSBarry Smith 
23e113a28aSBarry Smith    Options database keys:
24e113a28aSBarry Smith .  -snes_error_if_not_converged : this takes an optional truth value (0/1/no/yes/true/false)
25e113a28aSBarry Smith 
26e113a28aSBarry Smith    Level: intermediate
27e113a28aSBarry Smith 
28e113a28aSBarry Smith    Notes:
29e113a28aSBarry Smith     Normally PETSc continues if a linear solver fails to converge, you can call SNESGetConvergedReason() after a SNESSolve()
30e113a28aSBarry Smith     to determine if it has converged.
31e113a28aSBarry Smith 
32e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero
33e113a28aSBarry Smith 
34e113a28aSBarry Smith .seealso: SNESGetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged()
35e113a28aSBarry Smith @*/
367087cfbeSBarry Smith PetscErrorCode  SNESSetErrorIfNotConverged(SNES snes,PetscBool flg)
37e113a28aSBarry Smith {
38e113a28aSBarry Smith   PetscFunctionBegin;
39e113a28aSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
40acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flg,2);
41e113a28aSBarry Smith   snes->errorifnotconverged = flg;
42e113a28aSBarry Smith   PetscFunctionReturn(0);
43e113a28aSBarry Smith }
44e113a28aSBarry Smith 
45e113a28aSBarry Smith /*@
46e113a28aSBarry Smith    SNESGetErrorIfNotConverged - Will SNESSolve() generate an error if the solver does not converge?
47e113a28aSBarry Smith 
48e113a28aSBarry Smith    Not Collective
49e113a28aSBarry Smith 
50e113a28aSBarry Smith    Input Parameter:
51e113a28aSBarry Smith .  snes - iterative context obtained from SNESCreate()
52e113a28aSBarry Smith 
53e113a28aSBarry Smith    Output Parameter:
54e113a28aSBarry Smith .  flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE
55e113a28aSBarry Smith 
56e113a28aSBarry Smith    Level: intermediate
57e113a28aSBarry Smith 
58e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero
59e113a28aSBarry Smith 
60e113a28aSBarry Smith .seealso:  SNESSetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged()
61e113a28aSBarry Smith @*/
627087cfbeSBarry Smith PetscErrorCode  SNESGetErrorIfNotConverged(SNES snes,PetscBool  *flag)
63e113a28aSBarry Smith {
64e113a28aSBarry Smith   PetscFunctionBegin;
65e113a28aSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
66e113a28aSBarry Smith   PetscValidPointer(flag,2);
67e113a28aSBarry Smith   *flag = snes->errorifnotconverged;
68e113a28aSBarry Smith   PetscFunctionReturn(0);
69e113a28aSBarry Smith }
70e113a28aSBarry Smith 
714fc747eaSLawrence Mitchell /*@
724fc747eaSLawrence Mitchell     SNESSetAlwaysComputesFinalResidual - does the SNES always compute the residual at the final solution?
734fc747eaSLawrence Mitchell 
744fc747eaSLawrence Mitchell    Logically Collective on SNES
754fc747eaSLawrence Mitchell 
764fc747eaSLawrence Mitchell     Input Parameters:
774fc747eaSLawrence Mitchell +   snes - the shell SNES
784fc747eaSLawrence Mitchell -   flg - is the residual computed?
794fc747eaSLawrence Mitchell 
804fc747eaSLawrence Mitchell    Level: advanced
814fc747eaSLawrence Mitchell 
824fc747eaSLawrence Mitchell .seealso: SNESGetAlwaysComputesFinalResidual()
834fc747eaSLawrence Mitchell @*/
844fc747eaSLawrence Mitchell PetscErrorCode  SNESSetAlwaysComputesFinalResidual(SNES snes, PetscBool flg)
854fc747eaSLawrence Mitchell {
864fc747eaSLawrence Mitchell   PetscFunctionBegin;
874fc747eaSLawrence Mitchell   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
884fc747eaSLawrence Mitchell   snes->alwayscomputesfinalresidual = flg;
894fc747eaSLawrence Mitchell   PetscFunctionReturn(0);
904fc747eaSLawrence Mitchell }
914fc747eaSLawrence Mitchell 
924fc747eaSLawrence Mitchell /*@
934fc747eaSLawrence Mitchell     SNESGetAlwaysComputesFinalResidual - does the SNES always compute the residual at the final solution?
944fc747eaSLawrence Mitchell 
954fc747eaSLawrence Mitchell    Logically Collective on SNES
964fc747eaSLawrence Mitchell 
974fc747eaSLawrence Mitchell     Input Parameter:
984fc747eaSLawrence Mitchell .   snes - the shell SNES
994fc747eaSLawrence Mitchell 
1004fc747eaSLawrence Mitchell     Output Parameter:
1014fc747eaSLawrence Mitchell .   flg - is the residual computed?
1024fc747eaSLawrence Mitchell 
1034fc747eaSLawrence Mitchell    Level: advanced
1044fc747eaSLawrence Mitchell 
1054fc747eaSLawrence Mitchell .seealso: SNESSetAlwaysComputesFinalResidual()
1064fc747eaSLawrence Mitchell @*/
1074fc747eaSLawrence Mitchell PetscErrorCode  SNESGetAlwaysComputesFinalResidual(SNES snes, PetscBool *flg)
1084fc747eaSLawrence Mitchell {
1094fc747eaSLawrence Mitchell   PetscFunctionBegin;
1104fc747eaSLawrence Mitchell   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1114fc747eaSLawrence Mitchell   *flg = snes->alwayscomputesfinalresidual;
1124fc747eaSLawrence Mitchell   PetscFunctionReturn(0);
1134fc747eaSLawrence Mitchell }
1144fc747eaSLawrence Mitchell 
115e725d27bSBarry Smith /*@
116bf388a1fSBarry Smith    SNESSetFunctionDomainError - tells SNES that the input vector to your SNESFunction is not
1174936397dSBarry Smith      in the functions domain. For example, negative pressure.
1184936397dSBarry Smith 
1193f9fe445SBarry Smith    Logically Collective on SNES
1204936397dSBarry Smith 
1214936397dSBarry Smith    Input Parameters:
1226a388c36SPeter Brune .  snes - the SNES context
1234936397dSBarry Smith 
12428529972SSatish Balay    Level: advanced
1254936397dSBarry Smith 
1264936397dSBarry Smith .keywords: SNES, view
1274936397dSBarry Smith 
128bf388a1fSBarry Smith .seealso: SNESCreate(), SNESSetFunction(), SNESFunction
1294936397dSBarry Smith @*/
1307087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionDomainError(SNES snes)
1314936397dSBarry Smith {
1324936397dSBarry Smith   PetscFunctionBegin;
1330700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
134422a814eSBarry Smith   if (snes->errorifnotconverged) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"User code indicates input vector is not in the function domain");
1354936397dSBarry Smith   snes->domainerror = PETSC_TRUE;
1364936397dSBarry Smith   PetscFunctionReturn(0);
1374936397dSBarry Smith }
1384936397dSBarry Smith 
1396a388c36SPeter Brune /*@
140c77b2880SPeter Brune    SNESGetFunctionDomainError - Gets the status of the domain error after a call to SNESComputeFunction;
1416a388c36SPeter Brune 
1426a388c36SPeter Brune    Logically Collective on SNES
1436a388c36SPeter Brune 
1446a388c36SPeter Brune    Input Parameters:
1456a388c36SPeter Brune .  snes - the SNES context
1466a388c36SPeter Brune 
1476a388c36SPeter Brune    Output Parameters:
148bf388a1fSBarry Smith .  domainerror - Set to PETSC_TRUE if there's a domain error; PETSC_FALSE otherwise.
1496a388c36SPeter Brune 
1506a388c36SPeter Brune    Level: advanced
1516a388c36SPeter Brune 
1526a388c36SPeter Brune .keywords: SNES, view
1536a388c36SPeter Brune 
154bf388a1fSBarry Smith .seealso: SNESSetFunctionDomainError(), SNESComputeFunction()
1556a388c36SPeter Brune @*/
1566a388c36SPeter Brune PetscErrorCode  SNESGetFunctionDomainError(SNES snes, PetscBool *domainerror)
1576a388c36SPeter Brune {
1586a388c36SPeter Brune   PetscFunctionBegin;
1596a388c36SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1606a388c36SPeter Brune   PetscValidPointer(domainerror, 2);
1616a388c36SPeter Brune   *domainerror = snes->domainerror;
1626a388c36SPeter Brune   PetscFunctionReturn(0);
1636a388c36SPeter Brune }
1646a388c36SPeter Brune 
16555849f57SBarry Smith /*@C
16655849f57SBarry Smith   SNESLoad - Loads a SNES that has been stored in binary  with SNESView().
16755849f57SBarry Smith 
16855849f57SBarry Smith   Collective on PetscViewer
16955849f57SBarry Smith 
17055849f57SBarry Smith   Input Parameters:
17155849f57SBarry Smith + newdm - the newly loaded SNES, this needs to have been created with SNESCreate() or
17255849f57SBarry Smith            some related function before a call to SNESLoad().
17355849f57SBarry Smith - viewer - binary file viewer, obtained from PetscViewerBinaryOpen()
17455849f57SBarry Smith 
17555849f57SBarry Smith    Level: intermediate
17655849f57SBarry Smith 
17755849f57SBarry Smith   Notes:
17855849f57SBarry Smith    The type is determined by the data in the file, any type set into the SNES before this call is ignored.
17955849f57SBarry Smith 
18055849f57SBarry Smith   Notes for advanced users:
18155849f57SBarry Smith   Most users should not need to know the details of the binary storage
18255849f57SBarry Smith   format, since SNESLoad() and TSView() completely hide these details.
18355849f57SBarry Smith   But for anyone who's interested, the standard binary matrix storage
18455849f57SBarry Smith   format is
18555849f57SBarry Smith .vb
18655849f57SBarry Smith      has not yet been determined
18755849f57SBarry Smith .ve
18855849f57SBarry Smith 
18955849f57SBarry Smith .seealso: PetscViewerBinaryOpen(), SNESView(), MatLoad(), VecLoad()
19055849f57SBarry Smith @*/
1912d53ad75SBarry Smith PetscErrorCode  SNESLoad(SNES snes, PetscViewer viewer)
19255849f57SBarry Smith {
19355849f57SBarry Smith   PetscErrorCode ierr;
19455849f57SBarry Smith   PetscBool      isbinary;
195060da220SMatthew G. Knepley   PetscInt       classid;
19655849f57SBarry Smith   char           type[256];
19755849f57SBarry Smith   KSP            ksp;
1982d53ad75SBarry Smith   DM             dm;
1992d53ad75SBarry Smith   DMSNES         dmsnes;
20055849f57SBarry Smith 
20155849f57SBarry Smith   PetscFunctionBegin;
2022d53ad75SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
20355849f57SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
20455849f57SBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
20555849f57SBarry Smith   if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");
20655849f57SBarry Smith 
207060da220SMatthew G. Knepley   ierr = PetscViewerBinaryRead(viewer,&classid,1,NULL,PETSC_INT);CHKERRQ(ierr);
208ce94432eSBarry Smith   if (classid != SNES_FILE_CLASSID) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_WRONG,"Not SNES next in file");
209060da220SMatthew G. Knepley   ierr = PetscViewerBinaryRead(viewer,type,256,NULL,PETSC_CHAR);CHKERRQ(ierr);
2102d53ad75SBarry Smith   ierr = SNESSetType(snes, type);CHKERRQ(ierr);
2112d53ad75SBarry Smith   if (snes->ops->load) {
2122d53ad75SBarry Smith     ierr = (*snes->ops->load)(snes,viewer);CHKERRQ(ierr);
213f2c2a1b9SBarry Smith   }
2142d53ad75SBarry Smith   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2152d53ad75SBarry Smith   ierr = DMGetDMSNES(dm,&dmsnes);CHKERRQ(ierr);
2162d53ad75SBarry Smith   ierr = DMSNESLoad(dmsnes,viewer);CHKERRQ(ierr);
2172d53ad75SBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
21855849f57SBarry Smith   ierr = KSPLoad(ksp,viewer);CHKERRQ(ierr);
21955849f57SBarry Smith   PetscFunctionReturn(0);
22055849f57SBarry Smith }
2216a388c36SPeter Brune 
2229804daf3SBarry Smith #include <petscdraw.h>
223e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
224e04113cfSBarry Smith #include <petscviewersaws.h>
225bfb97211SBarry Smith #endif
2267e2c5f70SBarry Smith /*@C
2279b94acceSBarry Smith    SNESView - Prints the SNES data structure.
2289b94acceSBarry Smith 
2294c49b128SBarry Smith    Collective on SNES
230fee21e36SBarry Smith 
231c7afd0dbSLois Curfman McInnes    Input Parameters:
232c7afd0dbSLois Curfman McInnes +  SNES - the SNES context
233c7afd0dbSLois Curfman McInnes -  viewer - visualization context
234c7afd0dbSLois Curfman McInnes 
2359b94acceSBarry Smith    Options Database Key:
236c8a8ba5cSLois Curfman McInnes .  -snes_view - Calls SNESView() at end of SNESSolve()
2379b94acceSBarry Smith 
2389b94acceSBarry Smith    Notes:
2399b94acceSBarry Smith    The available visualization contexts include
240b0a32e0cSBarry Smith +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
241b0a32e0cSBarry Smith -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
242c8a8ba5cSLois Curfman McInnes          output where only the first processor opens
243c8a8ba5cSLois Curfman McInnes          the file.  All other processors send their
244c8a8ba5cSLois Curfman McInnes          data to the first processor to print.
2459b94acceSBarry Smith 
2463e081fefSLois Curfman McInnes    The user can open an alternative visualization context with
247b0a32e0cSBarry Smith    PetscViewerASCIIOpen() - output to a specified file.
2489b94acceSBarry Smith 
24936851e7fSLois Curfman McInnes    Level: beginner
25036851e7fSLois Curfman McInnes 
2519b94acceSBarry Smith .keywords: SNES, view
2529b94acceSBarry Smith 
253b0a32e0cSBarry Smith .seealso: PetscViewerASCIIOpen()
2549b94acceSBarry Smith @*/
2557087cfbeSBarry Smith PetscErrorCode  SNESView(SNES snes,PetscViewer viewer)
2569b94acceSBarry Smith {
257fa9f3622SBarry Smith   SNESKSPEW      *kctx;
258dfbe8321SBarry Smith   PetscErrorCode ierr;
25994b7f48cSBarry Smith   KSP            ksp;
2607f1410a3SPeter Brune   SNESLineSearch linesearch;
26172a02f06SBarry Smith   PetscBool      iascii,isstring,isbinary,isdraw;
2622d53ad75SBarry Smith   DMSNES         dmsnes;
263e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
264536b137fSBarry Smith   PetscBool      issaws;
265bfb97211SBarry Smith #endif
2669b94acceSBarry Smith 
2673a40ed3dSBarry Smith   PetscFunctionBegin;
2680700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2693050cee2SBarry Smith   if (!viewer) {
270ce94432eSBarry Smith     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&viewer);CHKERRQ(ierr);
2713050cee2SBarry Smith   }
2720700a824SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
273c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,viewer,2);
27474679c65SBarry Smith 
275251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
276251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr);
27755849f57SBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
27872a02f06SBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
279e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
280536b137fSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr);
281bfb97211SBarry Smith #endif
28232077d6dSBarry Smith   if (iascii) {
283dc0571f2SMatthew G. Knepley     SNESNormSchedule normschedule;
284dc0571f2SMatthew G. Knepley 
285dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer);CHKERRQ(ierr);
286fce1e034SJed Brown     if (!snes->setupcalled) {
287fce1e034SJed Brown       ierr = PetscViewerASCIIPrintf(viewer,"  SNES has not been set up so information may be incomplete\n");CHKERRQ(ierr);
288fce1e034SJed Brown     }
289e7788613SBarry Smith     if (snes->ops->view) {
290b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
291e7788613SBarry Smith       ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr);
292b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2930ef38995SBarry Smith     }
29477431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);CHKERRQ(ierr);
29557622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  tolerances: relative=%g, absolute=%g, solution=%g\n",(double)snes->rtol,(double)snes->abstol,(double)snes->stol);CHKERRQ(ierr);
29677431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr);
29777431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr);
298dc0571f2SMatthew G. Knepley     ierr = SNESGetNormSchedule(snes, &normschedule);CHKERRQ(ierr);
299dc0571f2SMatthew G. Knepley     if (normschedule > 0) {ierr = PetscViewerASCIIPrintf(viewer,"  norm schedule %s\n",SNESNormSchedules[normschedule]);CHKERRQ(ierr);}
30017fe4bdfSPeter Brune     if (snes->gridsequence) {
30117fe4bdfSPeter Brune       ierr = PetscViewerASCIIPrintf(viewer,"  total number of grid sequence refinements=%D\n",snes->gridsequence);CHKERRQ(ierr);
30217fe4bdfSPeter Brune     }
3039b94acceSBarry Smith     if (snes->ksp_ewconv) {
304fa9f3622SBarry Smith       kctx = (SNESKSPEW*)snes->kspconvctx;
3059b94acceSBarry Smith       if (kctx) {
30677431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"  Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr);
30757622a8eSBarry 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);
30857622a8eSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    gamma=%g, alpha=%g, alpha2=%g\n",(double)kctx->gamma,(double)kctx->alpha,(double)kctx->alpha2);CHKERRQ(ierr);
3099b94acceSBarry Smith       }
3109b94acceSBarry Smith     }
311eb1f6c34SBarry Smith     if (snes->lagpreconditioner == -1) {
312eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is never rebuilt\n");CHKERRQ(ierr);
313eb1f6c34SBarry Smith     } else if (snes->lagpreconditioner > 1) {
314eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr);
315eb1f6c34SBarry Smith     }
316eb1f6c34SBarry Smith     if (snes->lagjacobian == -1) {
317eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is never rebuilt\n");CHKERRQ(ierr);
318eb1f6c34SBarry Smith     } else if (snes->lagjacobian > 1) {
31942f4f86dSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian);CHKERRQ(ierr);
320eb1f6c34SBarry Smith     }
3210f5bd95cSBarry Smith   } else if (isstring) {
322317d6ea6SBarry Smith     const char *type;
323454a90a3SBarry Smith     ierr = SNESGetType(snes,&type);CHKERRQ(ierr);
324b0a32e0cSBarry Smith     ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr);
32555849f57SBarry Smith   } else if (isbinary) {
32655849f57SBarry Smith     PetscInt    classid = SNES_FILE_CLASSID;
32755849f57SBarry Smith     MPI_Comm    comm;
32855849f57SBarry Smith     PetscMPIInt rank;
32955849f57SBarry Smith     char        type[256];
33055849f57SBarry Smith 
33155849f57SBarry Smith     ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
33255849f57SBarry Smith     ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
33355849f57SBarry Smith     if (!rank) {
33455849f57SBarry Smith       ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
33589d949e2SBarry Smith       ierr = PetscStrncpy(type,((PetscObject)snes)->type_name,sizeof(type));CHKERRQ(ierr);
33689d949e2SBarry Smith       ierr = PetscViewerBinaryWrite(viewer,type,sizeof(type),PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr);
33755849f57SBarry Smith     }
33855849f57SBarry Smith     if (snes->ops->view) {
33955849f57SBarry Smith       ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr);
34055849f57SBarry Smith     }
34172a02f06SBarry Smith   } else if (isdraw) {
34272a02f06SBarry Smith     PetscDraw draw;
34372a02f06SBarry Smith     char      str[36];
34489fd9fafSBarry Smith     PetscReal x,y,bottom,h;
34572a02f06SBarry Smith 
34672a02f06SBarry Smith     ierr   = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
34772a02f06SBarry Smith     ierr   = PetscDrawGetCurrentPoint(draw,&x,&y);CHKERRQ(ierr);
34872a02f06SBarry Smith     ierr   = PetscStrcpy(str,"SNES: ");CHKERRQ(ierr);
34972a02f06SBarry Smith     ierr   = PetscStrcat(str,((PetscObject)snes)->type_name);CHKERRQ(ierr);
35051fa3d41SBarry Smith     ierr   = PetscDrawStringBoxed(draw,x,y,PETSC_DRAW_BLUE,PETSC_DRAW_BLACK,str,NULL,&h);CHKERRQ(ierr);
35189fd9fafSBarry Smith     bottom = y - h;
35272a02f06SBarry Smith     ierr   = PetscDrawPushCurrentPoint(draw,x,bottom);CHKERRQ(ierr);
353c4646bacSPeter Brune     if (snes->ops->view) {
354c4646bacSPeter Brune       ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr);
355c4646bacSPeter Brune     }
356e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
357536b137fSBarry Smith   } else if (issaws) {
358d45a07a7SBarry Smith     PetscMPIInt rank;
3592657e9d9SBarry Smith     const char *name;
360d45a07a7SBarry Smith 
3612657e9d9SBarry Smith     ierr = PetscObjectGetName((PetscObject)snes,&name);CHKERRQ(ierr);
362d45a07a7SBarry Smith     ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
363d45a07a7SBarry Smith     if (!((PetscObject)snes)->amsmem && !rank) {
364d45a07a7SBarry Smith       char       dir[1024];
365d45a07a7SBarry Smith 
366e04113cfSBarry Smith       ierr = PetscObjectViewSAWs((PetscObject)snes,viewer);CHKERRQ(ierr);
3672657e9d9SBarry Smith       ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/its",name);CHKERRQ(ierr);
3682657e9d9SBarry Smith       PetscStackCallSAWs(SAWs_Register,(dir,&snes->iter,1,SAWs_READ,SAWs_INT));
369bfb97211SBarry Smith       if (!snes->conv_hist) {
370a0931e03SBarry Smith         ierr = SNESSetConvergenceHistory(snes,NULL,NULL,PETSC_DECIDE,PETSC_TRUE);CHKERRQ(ierr);
371bfb97211SBarry Smith       }
3722657e9d9SBarry Smith       ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/conv_hist",name);CHKERRQ(ierr);
3732657e9d9SBarry Smith       PetscStackCallSAWs(SAWs_Register,(dir,snes->conv_hist,10,SAWs_READ,SAWs_DOUBLE));
374f05ece33SBarry Smith     }
375bfb97211SBarry Smith #endif
37672a02f06SBarry Smith   }
37772a02f06SBarry Smith   if (snes->linesearch) {
37872a02f06SBarry Smith     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
3797601faf0SJed Brown     ierr = SNESGetLineSearch(snes, &linesearch);CHKERRQ(ierr);
38072a02f06SBarry Smith     ierr = SNESLineSearchView(linesearch, viewer);CHKERRQ(ierr);
38172a02f06SBarry Smith     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
38219bcc07fSBarry Smith   }
38342f4f86dSBarry Smith   if (snes->pc && snes->usespc) {
3844a0c5b0cSMatthew G Knepley     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
3854a0c5b0cSMatthew G Knepley     ierr = SNESView(snes->pc, viewer);CHKERRQ(ierr);
3864a0c5b0cSMatthew G Knepley     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
3874a0c5b0cSMatthew G Knepley   }
3882d53ad75SBarry Smith   ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
3892d53ad75SBarry Smith   ierr = DMGetDMSNES(snes->dm,&dmsnes);CHKERRQ(ierr);
3902d53ad75SBarry Smith   ierr = DMSNESView(dmsnes, viewer);CHKERRQ(ierr);
3912d53ad75SBarry Smith   ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
3922c155ee1SBarry Smith   if (snes->usesksp) {
3932c155ee1SBarry Smith     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
394b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
39594b7f48cSBarry Smith     ierr = KSPView(ksp,viewer);CHKERRQ(ierr);
396b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
3972c155ee1SBarry Smith   }
39872a02f06SBarry Smith   if (isdraw) {
39972a02f06SBarry Smith     PetscDraw draw;
40072a02f06SBarry Smith     ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
40172a02f06SBarry Smith     ierr = PetscDrawPopCurrentPoint(draw);CHKERRQ(ierr);
4027f1410a3SPeter Brune   }
4033a40ed3dSBarry Smith   PetscFunctionReturn(0);
4049b94acceSBarry Smith }
4059b94acceSBarry Smith 
40676b2cf59SMatthew Knepley /*
40776b2cf59SMatthew Knepley   We retain a list of functions that also take SNES command
40876b2cf59SMatthew Knepley   line options. These are called at the end SNESSetFromOptions()
40976b2cf59SMatthew Knepley */
41076b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5
411a7cc72afSBarry Smith static PetscInt numberofsetfromoptions;
4126849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES);
41376b2cf59SMatthew Knepley 
414ac226902SBarry Smith /*@C
41576b2cf59SMatthew Knepley   SNESAddOptionsChecker - Adds an additional function to check for SNES options.
41676b2cf59SMatthew Knepley 
41776b2cf59SMatthew Knepley   Not Collective
41876b2cf59SMatthew Knepley 
41976b2cf59SMatthew Knepley   Input Parameter:
42076b2cf59SMatthew Knepley . snescheck - function that checks for options
42176b2cf59SMatthew Knepley 
42276b2cf59SMatthew Knepley   Level: developer
42376b2cf59SMatthew Knepley 
42476b2cf59SMatthew Knepley .seealso: SNESSetFromOptions()
42576b2cf59SMatthew Knepley @*/
4267087cfbeSBarry Smith PetscErrorCode  SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES))
42776b2cf59SMatthew Knepley {
42876b2cf59SMatthew Knepley   PetscFunctionBegin;
429f23aa3ddSBarry Smith   if (numberofsetfromoptions >= MAXSETFROMOPTIONS) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS);
43076b2cf59SMatthew Knepley   othersetfromoptions[numberofsetfromoptions++] = snescheck;
43176b2cf59SMatthew Knepley   PetscFunctionReturn(0);
43276b2cf59SMatthew Knepley }
43376b2cf59SMatthew Knepley 
4347087cfbeSBarry Smith extern PetscErrorCode  SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*);
435aa3661deSLisandro Dalcin 
436ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool hasOperator, PetscInt version)
437aa3661deSLisandro Dalcin {
438aa3661deSLisandro Dalcin   Mat            J;
439aa3661deSLisandro Dalcin   KSP            ksp;
440aa3661deSLisandro Dalcin   PC             pc;
441ace3abfcSBarry Smith   PetscBool      match;
442aa3661deSLisandro Dalcin   PetscErrorCode ierr;
443895c21f2SBarry Smith   MatNullSpace   nullsp;
444aa3661deSLisandro Dalcin 
445aa3661deSLisandro Dalcin   PetscFunctionBegin;
4460700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
447aa3661deSLisandro Dalcin 
44898613b67SLisandro Dalcin   if (!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) {
44998613b67SLisandro Dalcin     Mat A = snes->jacobian, B = snes->jacobian_pre;
4502a7a6963SBarry Smith     ierr = MatCreateVecs(A ? A : B, NULL,&snes->vec_func);CHKERRQ(ierr);
45198613b67SLisandro Dalcin   }
45298613b67SLisandro Dalcin 
453aa3661deSLisandro Dalcin   if (version == 1) {
454aa3661deSLisandro Dalcin     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
45598613b67SLisandro Dalcin     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
4569c6ac3b3SBarry Smith     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
457aa3661deSLisandro Dalcin   } else if (version == 2) {
458e32f2f54SBarry Smith     if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first");
459570b7f6dSBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) && !defined(PETSC_USE_REAL___FP16)
460aa3661deSLisandro Dalcin     ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr);
461aa3661deSLisandro Dalcin #else
462e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)");
463aa3661deSLisandro Dalcin #endif
464a8248277SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2");
465aa3661deSLisandro Dalcin 
466895c21f2SBarry Smith   /* attach any user provided null space that was on Amat to the newly created matrix free matrix */
467895c21f2SBarry Smith   if (snes->jacobian) {
468895c21f2SBarry Smith     ierr = MatGetNullSpace(snes->jacobian,&nullsp);CHKERRQ(ierr);
469895c21f2SBarry Smith     if (nullsp) {
470895c21f2SBarry Smith       ierr = MatSetNullSpace(J,nullsp);CHKERRQ(ierr);
471895c21f2SBarry Smith     }
472895c21f2SBarry Smith   }
473895c21f2SBarry Smith 
474aa3661deSLisandro Dalcin   ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr);
475d3462f78SMatthew Knepley   if (hasOperator) {
4763232da50SPeter Brune 
477aa3661deSLisandro Dalcin     /* This version replaces the user provided Jacobian matrix with a
478aa3661deSLisandro Dalcin        matrix-free version but still employs the user-provided preconditioner matrix. */
479aa3661deSLisandro Dalcin     ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr);
480aa3661deSLisandro Dalcin   } else {
481aa3661deSLisandro Dalcin     /* This version replaces both the user-provided Jacobian and the user-
4823232da50SPeter Brune      provided preconditioner Jacobian with the default matrix free version. */
483172a4300SPeter Brune     if ((snes->pcside == PC_LEFT) && snes->pc) {
484d728fb7dSPeter Brune       if (!snes->jacobian){ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr);}
485172a4300SPeter Brune     } else {
48628a52e04SBarry Smith       ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,0);CHKERRQ(ierr);
487172a4300SPeter Brune     }
488aa3661deSLisandro Dalcin     /* Force no preconditioner */
489aa3661deSLisandro Dalcin     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
490aa3661deSLisandro Dalcin     ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr);
491251f4c67SDmitry Karpeev     ierr = PetscObjectTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr);
492aa3661deSLisandro Dalcin     if (!match) {
493aa3661deSLisandro Dalcin       ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr);
494aa3661deSLisandro Dalcin       ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr);
495aa3661deSLisandro Dalcin     }
496aa3661deSLisandro Dalcin   }
4976bf464f9SBarry Smith   ierr = MatDestroy(&J);CHKERRQ(ierr);
498aa3661deSLisandro Dalcin   PetscFunctionReturn(0);
499aa3661deSLisandro Dalcin }
500aa3661deSLisandro Dalcin 
501dfe15315SJed Brown static PetscErrorCode DMRestrictHook_SNESVecSol(DM dmfine,Mat Restrict,Vec Rscale,Mat Inject,DM dmcoarse,void *ctx)
502dfe15315SJed Brown {
503dfe15315SJed Brown   SNES           snes = (SNES)ctx;
504dfe15315SJed Brown   PetscErrorCode ierr;
5050298fd71SBarry Smith   Vec            Xfine,Xfine_named = NULL,Xcoarse;
506dfe15315SJed Brown 
507dfe15315SJed Brown   PetscFunctionBegin;
50816ebb321SJed Brown   if (PetscLogPrintInfo) {
50916ebb321SJed Brown     PetscInt finelevel,coarselevel,fineclevel,coarseclevel;
51016ebb321SJed Brown     ierr = DMGetRefineLevel(dmfine,&finelevel);CHKERRQ(ierr);
51116ebb321SJed Brown     ierr = DMGetCoarsenLevel(dmfine,&fineclevel);CHKERRQ(ierr);
51216ebb321SJed Brown     ierr = DMGetRefineLevel(dmcoarse,&coarselevel);CHKERRQ(ierr);
51316ebb321SJed Brown     ierr = DMGetCoarsenLevel(dmcoarse,&coarseclevel);CHKERRQ(ierr);
51416ebb321SJed Brown     ierr = PetscInfo4(dmfine,"Restricting SNES solution vector from level %D-%D to level %D-%D\n",finelevel,fineclevel,coarselevel,coarseclevel);CHKERRQ(ierr);
51516ebb321SJed Brown   }
516dfe15315SJed Brown   if (dmfine == snes->dm) Xfine = snes->vec_sol;
517dfe15315SJed Brown   else {
518dfe15315SJed Brown     ierr  = DMGetNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);
519dfe15315SJed Brown     Xfine = Xfine_named;
520dfe15315SJed Brown   }
521dfe15315SJed Brown   ierr = DMGetNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr);
522907f5c5aSLawrence Mitchell   if (Inject) {
523907f5c5aSLawrence Mitchell     ierr = MatRestrict(Inject,Xfine,Xcoarse);CHKERRQ(ierr);
524907f5c5aSLawrence Mitchell   } else {
525dfe15315SJed Brown     ierr = MatRestrict(Restrict,Xfine,Xcoarse);CHKERRQ(ierr);
526dfe15315SJed Brown     ierr = VecPointwiseMult(Xcoarse,Xcoarse,Rscale);CHKERRQ(ierr);
527907f5c5aSLawrence Mitchell   }
528dfe15315SJed Brown   ierr = DMRestoreNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr);
529dfe15315SJed Brown   if (Xfine_named) {ierr = DMRestoreNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);}
530dfe15315SJed Brown   PetscFunctionReturn(0);
531dfe15315SJed Brown }
532dfe15315SJed Brown 
53316ebb321SJed Brown static PetscErrorCode DMCoarsenHook_SNESVecSol(DM dm,DM dmc,void *ctx)
53416ebb321SJed Brown {
53516ebb321SJed Brown   PetscErrorCode ierr;
53616ebb321SJed Brown 
53716ebb321SJed Brown   PetscFunctionBegin;
53816ebb321SJed Brown   ierr = DMCoarsenHookAdd(dmc,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,ctx);CHKERRQ(ierr);
53916ebb321SJed Brown   PetscFunctionReturn(0);
54016ebb321SJed Brown }
54116ebb321SJed Brown 
542a6950cb2SJed Brown /* This may be called to rediscretize the operator on levels of linear multigrid. The DM shuffle is so the user can
543a6950cb2SJed Brown  * safely call SNESGetDM() in their residual evaluation routine. */
54423ee1639SBarry Smith static PetscErrorCode KSPComputeOperators_SNES(KSP ksp,Mat A,Mat B,void *ctx)
545caa4e7f2SJed Brown {
546caa4e7f2SJed Brown   SNES           snes = (SNES)ctx;
547caa4e7f2SJed Brown   PetscErrorCode ierr;
548caa4e7f2SJed Brown   Mat            Asave = A,Bsave = B;
5490298fd71SBarry Smith   Vec            X,Xnamed = NULL;
550dfe15315SJed Brown   DM             dmsave;
5514e269d77SPeter Brune   void           *ctxsave;
552d1e9a80fSBarry Smith   PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*);
553caa4e7f2SJed Brown 
554caa4e7f2SJed Brown   PetscFunctionBegin;
555dfe15315SJed Brown   dmsave = snes->dm;
556dfe15315SJed Brown   ierr   = KSPGetDM(ksp,&snes->dm);CHKERRQ(ierr);
557dfe15315SJed Brown   if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */
558dfe15315SJed Brown   else {                                     /* We are on a coarser level, this vec was initialized using a DM restrict hook */
559dfe15315SJed Brown     ierr = DMGetNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr);
560dfe15315SJed Brown     X    = Xnamed;
5610298fd71SBarry Smith     ierr = SNESGetJacobian(snes,NULL,NULL,&jac,&ctxsave);CHKERRQ(ierr);
5624e269d77SPeter Brune     /* If the DM's don't match up, the MatFDColoring context needed for the jacobian won't match up either -- fixit. */
5638d359177SBarry Smith     if (jac == SNESComputeJacobianDefaultColor) {
5648d359177SBarry Smith       ierr = SNESSetJacobian(snes,NULL,NULL,SNESComputeJacobianDefaultColor,0);CHKERRQ(ierr);
565dfe15315SJed Brown     }
5664e269d77SPeter Brune   }
5674e269d77SPeter Brune   /* put the previous context back */
5684e269d77SPeter Brune 
569d1e9a80fSBarry Smith   ierr = SNESComputeJacobian(snes,X,A,B);CHKERRQ(ierr);
5708d359177SBarry Smith   if (snes->dm != dmsave && jac == SNESComputeJacobianDefaultColor) {
5710298fd71SBarry Smith     ierr = SNESSetJacobian(snes,NULL,NULL,jac,ctxsave);CHKERRQ(ierr);
5724e269d77SPeter Brune   }
5734e269d77SPeter Brune 
574ce94432eSBarry Smith   if (A != Asave || B != Bsave) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"No support for changing matrices at this time");
575dfe15315SJed Brown   if (Xnamed) {
576dfe15315SJed Brown     ierr = DMRestoreNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr);
577dfe15315SJed Brown   }
578dfe15315SJed Brown   snes->dm = dmsave;
579caa4e7f2SJed Brown   PetscFunctionReturn(0);
580caa4e7f2SJed Brown }
581caa4e7f2SJed Brown 
5826cab3a1bSJed Brown /*@
5836cab3a1bSJed Brown    SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX()
5846cab3a1bSJed Brown 
5856cab3a1bSJed Brown    Collective
5866cab3a1bSJed Brown 
5876cab3a1bSJed Brown    Input Arguments:
5886cab3a1bSJed Brown .  snes - snes to configure
5896cab3a1bSJed Brown 
5906cab3a1bSJed Brown    Level: developer
5916cab3a1bSJed Brown 
5926cab3a1bSJed Brown .seealso: SNESSetUp()
5936cab3a1bSJed Brown @*/
5946cab3a1bSJed Brown PetscErrorCode SNESSetUpMatrices(SNES snes)
5956cab3a1bSJed Brown {
5966cab3a1bSJed Brown   PetscErrorCode ierr;
5976cab3a1bSJed Brown   DM             dm;
598942e3340SBarry Smith   DMSNES         sdm;
5996cab3a1bSJed Brown 
6006cab3a1bSJed Brown   PetscFunctionBegin;
6016cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
602942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
603ce94432eSBarry Smith   if (!sdm->ops->computejacobian) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_PLIB,"DMSNES not properly configured");
604f5af7f23SKarl Rupp   else if (!snes->jacobian && snes->mf) {
6056cab3a1bSJed Brown     Mat  J;
6066cab3a1bSJed Brown     void *functx;
6076cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
6086cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
6096cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
6100298fd71SBarry Smith     ierr = SNESGetFunction(snes,NULL,NULL,&functx);CHKERRQ(ierr);
6113232da50SPeter Brune     ierr = SNESSetJacobian(snes,J,J,0,0);CHKERRQ(ierr);
6126cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
613caa4e7f2SJed Brown   } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) {
6146cab3a1bSJed Brown     Mat J,B;
6156cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
6166cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
6176cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
618b412c318SBarry Smith     ierr = DMCreateMatrix(snes->dm,&B);CHKERRQ(ierr);
61906f20277SJed Brown     /* sdm->computejacobian was already set to reach here */
6200298fd71SBarry Smith     ierr = SNESSetJacobian(snes,J,B,NULL,NULL);CHKERRQ(ierr);
6216cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
6226cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
623caa4e7f2SJed Brown   } else if (!snes->jacobian_pre) {
6241ba9b98eSMatthew G. Knepley     PetscDS   prob;
6256cab3a1bSJed Brown     Mat       J, B;
6261ba9b98eSMatthew G. Knepley     PetscBool hasPrec = PETSC_FALSE;
6271ba9b98eSMatthew G. Knepley 
6286cab3a1bSJed Brown     J    = snes->jacobian;
6291ba9b98eSMatthew G. Knepley     ierr = DMGetDS(dm, &prob);CHKERRQ(ierr);
6301ba9b98eSMatthew G. Knepley     if (prob) {ierr = PetscDSHasJacobianPreconditioner(prob, &hasPrec);CHKERRQ(ierr);}
631ec9a985fSMatthew G. Knepley     if (J)            {ierr = PetscObjectReference((PetscObject) J);CHKERRQ(ierr);}
632ec9a985fSMatthew G. Knepley     else if (hasPrec) {ierr = DMCreateMatrix(snes->dm, &J);CHKERRQ(ierr);}
633b412c318SBarry Smith     ierr = DMCreateMatrix(snes->dm, &B);CHKERRQ(ierr);
6340298fd71SBarry Smith     ierr = SNESSetJacobian(snes, J ? J : B, B, NULL, NULL);CHKERRQ(ierr);
6351ba9b98eSMatthew G. Knepley     ierr = MatDestroy(&J);CHKERRQ(ierr);
6366cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
6376cab3a1bSJed Brown   }
638caa4e7f2SJed Brown   {
639caa4e7f2SJed Brown     KSP ksp;
640caa4e7f2SJed Brown     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
641caa4e7f2SJed Brown     ierr = KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes);CHKERRQ(ierr);
64216ebb321SJed Brown     ierr = DMCoarsenHookAdd(snes->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr);
643caa4e7f2SJed Brown   }
6446cab3a1bSJed Brown   PetscFunctionReturn(0);
6456cab3a1bSJed Brown }
6466cab3a1bSJed Brown 
647fde5950dSBarry Smith /*@C
648fde5950dSBarry Smith    SNESMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user
649fde5950dSBarry Smith 
650fde5950dSBarry Smith    Collective on SNES
651fde5950dSBarry Smith 
652fde5950dSBarry Smith    Input Parameters:
653fde5950dSBarry Smith +  snes - SNES object you wish to monitor
654fde5950dSBarry Smith .  name - the monitor type one is seeking
655fde5950dSBarry Smith .  help - message indicating what monitoring is done
656fde5950dSBarry Smith .  manual - manual page for the monitor
657fde5950dSBarry Smith .  monitor - the monitor function
658fde5950dSBarry 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
659fde5950dSBarry Smith 
660fde5950dSBarry Smith    Level: developer
661fde5950dSBarry Smith 
662fde5950dSBarry Smith .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
663fde5950dSBarry Smith           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
664fde5950dSBarry Smith           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
665fde5950dSBarry Smith           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
666fde5950dSBarry Smith           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
667fde5950dSBarry Smith           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
668fde5950dSBarry Smith           PetscOptionsFList(), PetscOptionsEList()
669fde5950dSBarry Smith @*/
670d43b4f6eSBarry Smith PetscErrorCode  SNESMonitorSetFromOptions(SNES snes,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(SNES,PetscViewerAndFormat*))
671fde5950dSBarry Smith {
672fde5950dSBarry Smith   PetscErrorCode    ierr;
673fde5950dSBarry Smith   PetscViewer       viewer;
674fde5950dSBarry Smith   PetscViewerFormat format;
675fde5950dSBarry Smith   PetscBool         flg;
676fde5950dSBarry Smith 
677fde5950dSBarry Smith   PetscFunctionBegin;
678fde5950dSBarry Smith   ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,name,&viewer,&format,&flg);CHKERRQ(ierr);
679fde5950dSBarry Smith   if (flg) {
680d43b4f6eSBarry Smith     PetscViewerAndFormat *vf;
681d43b4f6eSBarry Smith     ierr = PetscViewerAndFormatCreate(viewer,format,&vf);CHKERRQ(ierr);
682d43b4f6eSBarry Smith     ierr = PetscObjectDereference((PetscObject)viewer);CHKERRQ(ierr);
683fde5950dSBarry Smith     if (monitorsetup) {
684d43b4f6eSBarry Smith       ierr = (*monitorsetup)(snes,vf);CHKERRQ(ierr);
685fde5950dSBarry Smith     }
686d43b4f6eSBarry Smith     ierr = SNESMonitorSet(snes,(PetscErrorCode (*)(SNES,PetscInt,PetscReal,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy);CHKERRQ(ierr);
687fde5950dSBarry Smith   }
688fde5950dSBarry Smith   PetscFunctionReturn(0);
689fde5950dSBarry Smith }
690fde5950dSBarry Smith 
6919b94acceSBarry Smith /*@
69294b7f48cSBarry Smith    SNESSetFromOptions - Sets various SNES and KSP parameters from user options.
6939b94acceSBarry Smith 
694c7afd0dbSLois Curfman McInnes    Collective on SNES
695c7afd0dbSLois Curfman McInnes 
6969b94acceSBarry Smith    Input Parameter:
6979b94acceSBarry Smith .  snes - the SNES context
6989b94acceSBarry Smith 
69936851e7fSLois Curfman McInnes    Options Database Keys:
700722329fbSBarry Smith +  -snes_type <type> - newtonls, newtontr, ngmres, ncg, nrichardson, qn, vi, fas, SNESType for complete list
70182738288SBarry Smith .  -snes_stol - convergence tolerance in terms of the norm
70282738288SBarry Smith                 of the change in the solution between steps
70370441072SBarry Smith .  -snes_atol <abstol> - absolute tolerance of residual norm
704b39c3a46SLois Curfman McInnes .  -snes_rtol <rtol> - relative decrease in tolerance norm from initial
705e4d06f11SPatrick Farrell .  -snes_divergence_tolerance <divtol> - if the residual goes above divtol*rnorm0, exit with divergence
706b39c3a46SLois Curfman McInnes .  -snes_max_it <max_it> - maximum number of iterations
707b39c3a46SLois Curfman McInnes .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
7084839bfe8SBarry Smith .  -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none
709ddf469c8SBarry Smith .  -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops
710a8054027SBarry Smith .  -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild)
711e35cf81dSBarry Smith .  -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild)
712b39c3a46SLois Curfman McInnes .  -snes_trtol <trtol> - trust region tolerance
7132492ecdbSBarry Smith .  -snes_no_convergence_test - skip convergence test in nonlinear
71482738288SBarry Smith                                solver; hence iterations will continue until max_it
7151fbbfb26SLois Curfman McInnes                                or some other criterion is reached. Saves expense
71682738288SBarry Smith                                of convergence test
717fde5950dSBarry Smith .  -snes_monitor [ascii][:filename][:viewer format] - prints residual norm at each iteration. if no filename given prints to stdout
718fde5950dSBarry Smith .  -snes_monitor_solution [ascii binary draw][:filename][:viewer format] - plots solution at each iteration
719fde5950dSBarry Smith .  -snes_monitor_residual [ascii binary draw][:filename][:viewer format] - plots residual (not its norm) at each iteration
720fde5950dSBarry Smith .  -snes_monitor_solution_update [ascii binary draw][:filename][:viewer format] - plots update to solution at each iteration
7214619e776SBarry Smith .  -snes_monitor_lg_residualnorm - plots residual norm at each iteration
722459f5d12SBarry Smith .  -snes_monitor_lg_range - plots residual norm at each iteration
723e24b481bSBarry Smith .  -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
724e2e60de9SPeter Brune .  -snes_fd_color - use finite differences with coloring to compute Jacobian
7255968eb51SBarry Smith .  -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
726fee2055bSBarry Smith -  -snes_converged_reason - print the reason for convergence/divergence after each solve
72782738288SBarry Smith 
72882738288SBarry Smith     Options Database for Eisenstat-Walker method:
729fa9f3622SBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
7304b27c08aSLois Curfman McInnes .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
73136851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
73236851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
73336851e7fSLois Curfman McInnes .  -snes_ksp_ew_gamma <gamma> - Sets gamma
73436851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha <alpha> - Sets alpha
73536851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
73636851e7fSLois Curfman McInnes -  -snes_ksp_ew_threshold <threshold> - Sets threshold
73782738288SBarry Smith 
73811ca99fdSLois Curfman McInnes    Notes:
73911ca99fdSLois Curfman McInnes    To see all options, run your program with the -help option or consult
740a7f22e61SSatish Balay    Users-Manual: ch_snes
74183e2fdc7SBarry Smith 
74236851e7fSLois Curfman McInnes    Level: beginner
74336851e7fSLois Curfman McInnes 
7449b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database
7459b94acceSBarry Smith 
74669ed319cSSatish Balay .seealso: SNESSetOptionsPrefix()
7479b94acceSBarry Smith @*/
7487087cfbeSBarry Smith PetscErrorCode  SNESSetFromOptions(SNES snes)
7499b94acceSBarry Smith {
7508afaa268SBarry Smith   PetscBool      flg,pcset,persist,set;
751d8f46077SPeter Brune   PetscInt       i,indx,lag,grids;
75204d7464bSBarry Smith   const char     *deft        = SNESNEWTONLS;
75385385478SLisandro Dalcin   const char     *convtests[] = {"default","skip"};
75485385478SLisandro Dalcin   SNESKSPEW      *kctx        = NULL;
755e8105e01SRichard Katz   char           type[256], monfilename[PETSC_MAX_PATH_LEN];
75685385478SLisandro Dalcin   PetscErrorCode ierr;
757c40d0f55SPeter Brune   PCSide         pcside;
758a64e098fSPeter Brune   const char     *optionsprefix;
7599b94acceSBarry Smith 
7603a40ed3dSBarry Smith   PetscFunctionBegin;
7610700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
7620f51fdf8SToby Isaac   ierr = SNESRegisterAll();CHKERRQ(ierr);
7633194b578SJed Brown   ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr);
764639ff905SBarry Smith   if (((PetscObject)snes)->type_name) deft = ((PetscObject)snes)->type_name;
765a264d7a6SBarry Smith   ierr = PetscOptionsFList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr);
766d64ed03dSBarry Smith   if (flg) {
767186905e3SBarry Smith     ierr = SNESSetType(snes,type);CHKERRQ(ierr);
7687adad957SLisandro Dalcin   } else if (!((PetscObject)snes)->type_name) {
769186905e3SBarry Smith     ierr = SNESSetType(snes,deft);CHKERRQ(ierr);
770d64ed03dSBarry Smith   }
77194ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,NULL);CHKERRQ(ierr);
77294ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,NULL);CHKERRQ(ierr);
773186905e3SBarry Smith 
77494ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,NULL);CHKERRQ(ierr);
775e4d06f11SPatrick Farrell   ierr = PetscOptionsReal("-snes_divergence_tolerance","Stop if residual norm increases by this factor","SNESSetDivergenceTolerance",snes->divtol,&snes->divtol,NULL);CHKERRQ(ierr);
7760298fd71SBarry Smith   ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,NULL);CHKERRQ(ierr);
7770298fd71SBarry Smith   ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,NULL);CHKERRQ(ierr);
7780298fd71SBarry Smith   ierr = PetscOptionsInt("-snes_max_fail","Maximum nonlinear step failures","SNESSetMaxNonlinearStepFailures",snes->maxFailures,&snes->maxFailures,NULL);CHKERRQ(ierr);
7790298fd71SBarry Smith   ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,NULL);CHKERRQ(ierr);
7800298fd71SBarry Smith   ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,NULL);CHKERRQ(ierr);
78185385478SLisandro Dalcin 
782a8054027SBarry Smith   ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr);
783a8054027SBarry Smith   if (flg) {
784a8054027SBarry Smith     ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr);
785a8054027SBarry Smith   }
78637ec4e1aSPeter Brune   ierr = PetscOptionsBool("-snes_lag_preconditioner_persists","Preconditioner lagging through multiple solves","SNESSetLagPreconditionerPersists",snes->lagjac_persist,&persist,&flg);CHKERRQ(ierr);
78737ec4e1aSPeter Brune   if (flg) {
78837ec4e1aSPeter Brune     ierr = SNESSetLagPreconditionerPersists(snes,persist);CHKERRQ(ierr);
78937ec4e1aSPeter Brune   }
790e35cf81dSBarry Smith   ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr);
791e35cf81dSBarry Smith   if (flg) {
792e35cf81dSBarry Smith     ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr);
793e35cf81dSBarry Smith   }
79437ec4e1aSPeter Brune   ierr = PetscOptionsBool("-snes_lag_jacobian_persists","Jacobian lagging through multiple solves","SNESSetLagJacobianPersists",snes->lagjac_persist,&persist,&flg);CHKERRQ(ierr);
79537ec4e1aSPeter Brune   if (flg) {
79637ec4e1aSPeter Brune     ierr = SNESSetLagJacobianPersists(snes,persist);CHKERRQ(ierr);
79737ec4e1aSPeter Brune   }
79837ec4e1aSPeter Brune 
799efd51863SBarry Smith   ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr);
800efd51863SBarry Smith   if (flg) {
801efd51863SBarry Smith     ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr);
802efd51863SBarry Smith   }
803a8054027SBarry Smith 
80485385478SLisandro Dalcin   ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr);
80585385478SLisandro Dalcin   if (flg) {
80685385478SLisandro Dalcin     switch (indx) {
8078d359177SBarry Smith     case 0: ierr = SNESSetConvergenceTest(snes,SNESConvergedDefault,NULL,NULL);CHKERRQ(ierr); break;
808e2a6519dSDmitry Karpeev     case 1: ierr = SNESSetConvergenceTest(snes,SNESConvergedSkip,NULL,NULL);CHKERRQ(ierr);    break;
80985385478SLisandro Dalcin     }
81085385478SLisandro Dalcin   }
81185385478SLisandro Dalcin 
812365a6726SPeter Brune   ierr = PetscOptionsEList("-snes_norm_schedule","SNES Norm schedule","SNESSetNormSchedule",SNESNormSchedules,5,"function",&indx,&flg);CHKERRQ(ierr);
813365a6726SPeter Brune   if (flg) { ierr = SNESSetNormSchedule(snes,(SNESNormSchedule)indx);CHKERRQ(ierr); }
814fdacfa88SPeter Brune 
81547073ea2SPeter Brune   ierr = PetscOptionsEList("-snes_function_type","SNES Norm schedule","SNESSetFunctionType",SNESFunctionTypes,2,"unpreconditioned",&indx,&flg);CHKERRQ(ierr);
81647073ea2SPeter Brune   if (flg) { ierr = SNESSetFunctionType(snes,(SNESFunctionType)indx);CHKERRQ(ierr); }
817186905e3SBarry Smith 
81885385478SLisandro Dalcin   kctx = (SNESKSPEW*)snes->kspconvctx;
81985385478SLisandro Dalcin 
8200298fd71SBarry Smith   ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,NULL);CHKERRQ(ierr);
821186905e3SBarry Smith 
82294ae4db5SBarry Smith   ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,NULL);CHKERRQ(ierr);
82394ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,NULL);CHKERRQ(ierr);
82494ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,NULL);CHKERRQ(ierr);
82594ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,NULL);CHKERRQ(ierr);
82694ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,NULL);CHKERRQ(ierr);
82794ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,NULL);CHKERRQ(ierr);
82894ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,NULL);CHKERRQ(ierr);
829186905e3SBarry Smith 
83090d69ab7SBarry Smith   flg  = PETSC_FALSE;
8318afaa268SBarry Smith   ierr = PetscOptionsBool("-snes_check_jacobian","Check each Jacobian with a differenced one","SNESUpdateCheckJacobian",flg,&flg,&set);CHKERRQ(ierr);
8328afaa268SBarry Smith   if (set && flg) {
8335341784dSBarry Smith     ierr = SNESSetUpdate(snes,SNESUpdateCheckJacobian);CHKERRQ(ierr);
8345341784dSBarry Smith   }
8355341784dSBarry Smith 
8365341784dSBarry Smith   flg  = PETSC_FALSE;
8378afaa268SBarry Smith   ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,&set);CHKERRQ(ierr);
8388afaa268SBarry Smith   if (set && flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);}
839eabae89aSBarry Smith 
840fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor","Monitor norm of function","SNESMonitorDefault",SNESMonitorDefault,NULL);CHKERRQ(ierr);
841fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_short","Monitor norm of function with fewer digits","SNESMonitorDefaultShort",SNESMonitorDefaultShort,NULL);CHKERRQ(ierr);
842fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_range","Monitor range of elements of function","SNESMonitorRange",SNESMonitorRange,NULL);CHKERRQ(ierr);
843eabae89aSBarry Smith 
844fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_ratio","Monitor ratios of the norm of function for consecutive steps","SNESMonitorRatio",SNESMonitorRatio,SNESMonitorRatioSetUp);CHKERRQ(ierr);
845fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_field","Monitor norm of function (split into fields)","SNESMonitorDefaultField",SNESMonitorDefaultField,NULL);CHKERRQ(ierr);
846fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_solution","View solution at each iteration","SNESMonitorSolution",SNESMonitorSolution,NULL);CHKERRQ(ierr);
847fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_solution_update","View correction at each iteration","SNESMonitorSolutionUpdate",SNESMonitorSolutionUpdate,NULL);CHKERRQ(ierr);
848fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_residual","View residual at each iteration","SNESMonitorResidual",SNESMonitorResidual,NULL);CHKERRQ(ierr);
849fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_jacupdate_spectrum","Print the change in the spectrum of the Jacobian","SNESMonitorJacUpdateSpectrum",SNESMonitorJacUpdateSpectrum,NULL);CHKERRQ(ierr);
850fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_fields","Monitor norm of function per field","SNESMonitorSet",SNESMonitorFields,NULL);CHKERRQ(ierr);
8512db13446SMatthew G. Knepley 
8525180491cSLisandro Dalcin   ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
8535180491cSLisandro Dalcin   if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);}
8545180491cSLisandro Dalcin 
855fde5950dSBarry Smith 
85690d69ab7SBarry Smith   flg  = PETSC_FALSE;
8570298fd71SBarry Smith   ierr = PetscOptionsBool("-snes_monitor_lg_residualnorm","Plot function norm at each iteration","SNESMonitorLGResidualNorm",flg,&flg,NULL);CHKERRQ(ierr);
858459f5d12SBarry Smith   if (flg) {
859d96771aaSLisandro Dalcin     PetscDrawLG ctx;
860459f5d12SBarry Smith 
8616ba87a44SLisandro Dalcin     ierr = SNESMonitorLGCreate(PetscObjectComm((PetscObject)snes),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);CHKERRQ(ierr);
862d96771aaSLisandro Dalcin     ierr = SNESMonitorSet(snes,SNESMonitorLGResidualNorm,ctx,(PetscErrorCode (*)(void**))PetscDrawLGDestroy);CHKERRQ(ierr);
863459f5d12SBarry Smith   }
86490d69ab7SBarry Smith   flg  = PETSC_FALSE;
8650298fd71SBarry Smith   ierr = PetscOptionsBool("-snes_monitor_lg_range","Plot function range at each iteration","SNESMonitorLGRange",flg,&flg,NULL);CHKERRQ(ierr);
866459f5d12SBarry Smith   if (flg) {
867459f5d12SBarry Smith     PetscViewer ctx;
868e24b481bSBarry Smith 
8696ba87a44SLisandro Dalcin     ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);CHKERRQ(ierr);
870459f5d12SBarry Smith     ierr = SNESMonitorSet(snes,SNESMonitorLGRange,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
871459f5d12SBarry Smith   }
8722e7541e6SPeter Brune 
8732e7541e6SPeter Brune 
874cc0c4584SMatthew G. Knepley 
87590d69ab7SBarry Smith   flg  = PETSC_FALSE;
8768d359177SBarry Smith   ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESComputeJacobianDefault",flg,&flg,NULL);CHKERRQ(ierr);
8774b27c08aSLois Curfman McInnes   if (flg) {
8786cab3a1bSJed Brown     void *functx;
8790298fd71SBarry Smith     ierr = SNESGetFunction(snes,NULL,NULL,&functx);CHKERRQ(ierr);
8808d359177SBarry Smith     ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESComputeJacobianDefault,functx);CHKERRQ(ierr);
881ae15b995SBarry Smith     ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr);
8829b94acceSBarry Smith   }
883639f9d9dSBarry Smith 
88444848bc4SPeter Brune   flg  = PETSC_FALSE;
8858d359177SBarry Smith   ierr = PetscOptionsBool("-snes_fd_function","Use finite differences (slow) to compute function from user objective","SNESObjectiveComputeFunctionDefaultFD",flg,&flg,NULL);CHKERRQ(ierr);
88697584545SPeter Brune   if (flg) {
8878d359177SBarry Smith     ierr = SNESSetFunction(snes,NULL,SNESObjectiveComputeFunctionDefaultFD,NULL);CHKERRQ(ierr);
88897584545SPeter Brune   }
88997584545SPeter Brune 
89097584545SPeter Brune   flg  = PETSC_FALSE;
8918d359177SBarry Smith   ierr = PetscOptionsBool("-snes_fd_color","Use finite differences with coloring to compute Jacobian","SNESComputeJacobianDefaultColor",flg,&flg,NULL);CHKERRQ(ierr);
89244848bc4SPeter Brune   if (flg) {
893c52e227fSPeter Brune     DM             dm;
894c52e227fSPeter Brune     DMSNES         sdm;
895c52e227fSPeter Brune     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
896aace71b7SPeter Brune     ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
897aace71b7SPeter Brune     sdm->jacobianctx = NULL;
8988d359177SBarry Smith     ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESComputeJacobianDefaultColor,0);CHKERRQ(ierr);
89944848bc4SPeter Brune     ierr = PetscInfo(snes,"Setting default finite difference coloring Jacobian matrix\n");CHKERRQ(ierr);
90044848bc4SPeter Brune   }
90144848bc4SPeter Brune 
902aa3661deSLisandro Dalcin   flg  = PETSC_FALSE;
903d8f46077SPeter Brune   ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&snes->mf_operator,&flg);CHKERRQ(ierr);
904d8f46077SPeter Brune   if (flg && snes->mf_operator) {
905a8248277SBarry Smith     snes->mf_operator = PETSC_TRUE;
906d8f46077SPeter Brune     snes->mf          = PETSC_TRUE;
907a8248277SBarry Smith   }
908aa3661deSLisandro Dalcin   flg  = PETSC_FALSE;
909d8f46077SPeter Brune   ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&snes->mf,&flg);CHKERRQ(ierr);
910d8f46077SPeter Brune   if (!flg && snes->mf_operator) snes->mf = PETSC_TRUE;
911d8f46077SPeter Brune   ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",snes->mf_version,&snes->mf_version,0);CHKERRQ(ierr);
912d28543b3SPeter Brune 
913c40d0f55SPeter Brune   flg  = PETSC_FALSE;
914be95d8f1SBarry Smith   ierr = SNESGetNPCSide(snes,&pcside);CHKERRQ(ierr);
915be95d8f1SBarry Smith   ierr = PetscOptionsEnum("-snes_npc_side","SNES nonlinear preconditioner side","SNESSetNPCSide",PCSides,(PetscEnum)pcside,(PetscEnum*)&pcside,&flg);CHKERRQ(ierr);
916be95d8f1SBarry Smith   if (flg) {ierr = SNESSetNPCSide(snes,pcside);CHKERRQ(ierr);}
917c40d0f55SPeter Brune 
918e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
9198a70d858SHong Zhang   /*
9208a70d858SHong Zhang     Publish convergence information using SAWs
9218a70d858SHong Zhang   */
9228a70d858SHong Zhang   flg  = PETSC_FALSE;
9238a70d858SHong Zhang   ierr = PetscOptionsBool("-snes_monitor_saws","Publish SNES progress using SAWs","SNESMonitorSet",flg,&flg,NULL);CHKERRQ(ierr);
9248a70d858SHong Zhang   if (flg) {
9258a70d858SHong Zhang     void *ctx;
9268a70d858SHong Zhang     ierr = SNESMonitorSAWsCreate(snes,&ctx);CHKERRQ(ierr);
9278a70d858SHong Zhang     ierr = SNESMonitorSet(snes,SNESMonitorSAWs,ctx,SNESMonitorSAWsDestroy);CHKERRQ(ierr);
9288a70d858SHong Zhang   }
9298a70d858SHong Zhang #endif
9308a70d858SHong Zhang #if defined(PETSC_HAVE_SAWS)
931b90c6cbeSBarry Smith   {
932b90c6cbeSBarry Smith   PetscBool set;
933b90c6cbeSBarry Smith   flg  = PETSC_FALSE;
9348a70d858SHong Zhang   ierr = PetscOptionsBool("-snes_saws_block","Block for SAWs at end of SNESSolve","PetscObjectSAWsBlock",((PetscObject)snes)->amspublishblock,&flg,&set);CHKERRQ(ierr);
935b90c6cbeSBarry Smith   if (set) {
936e04113cfSBarry Smith     ierr = PetscObjectSAWsSetBlock((PetscObject)snes,flg);CHKERRQ(ierr);
937b90c6cbeSBarry Smith   }
938b90c6cbeSBarry Smith   }
939b90c6cbeSBarry Smith #endif
940b90c6cbeSBarry Smith 
94176b2cf59SMatthew Knepley   for (i = 0; i < numberofsetfromoptions; i++) {
94276b2cf59SMatthew Knepley     ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr);
94376b2cf59SMatthew Knepley   }
94476b2cf59SMatthew Knepley 
945e7788613SBarry Smith   if (snes->ops->setfromoptions) {
946e55864a3SBarry Smith     ierr = (*snes->ops->setfromoptions)(PetscOptionsObject,snes);CHKERRQ(ierr);
947639f9d9dSBarry Smith   }
9485d973c19SBarry Smith 
9495d973c19SBarry Smith   /* process any options handlers added with PetscObjectAddOptionsHandler() */
9500633abcbSJed Brown   ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)snes);CHKERRQ(ierr);
951b0a32e0cSBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
9524bbc92c1SBarry Smith 
9539e764e56SPeter Brune   if (!snes->linesearch) {
9547601faf0SJed Brown     ierr = SNESGetLineSearch(snes, &snes->linesearch);CHKERRQ(ierr);
9559e764e56SPeter Brune   }
956f1c6b773SPeter Brune   ierr = SNESLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr);
9579e764e56SPeter Brune 
9586991f827SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
9596991f827SBarry Smith   ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre);CHKERRQ(ierr);
9606991f827SBarry Smith   ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr);
9616991f827SBarry Smith 
962be95d8f1SBarry Smith   /* if someone has set the SNES NPC type, create it. */
96351e86f29SPeter Brune   ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
964c5929fdfSBarry Smith   ierr = PetscOptionsHasName(((PetscObject)snes)->options,optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr);
96551e86f29SPeter Brune   if (pcset && (!snes->pc)) {
966be95d8f1SBarry Smith     ierr = SNESGetNPC(snes, &snes->pc);CHKERRQ(ierr);
96751e86f29SPeter Brune   }
9683a40ed3dSBarry Smith   PetscFunctionReturn(0);
9699b94acceSBarry Smith }
9709b94acceSBarry Smith 
971bb9467b5SJed Brown /*@C
972d25893d9SBarry Smith    SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for
973d25893d9SBarry Smith    the nonlinear solvers.
974d25893d9SBarry Smith 
975d25893d9SBarry Smith    Logically Collective on SNES
976d25893d9SBarry Smith 
977d25893d9SBarry Smith    Input Parameters:
978d25893d9SBarry Smith +  snes - the SNES context
979d25893d9SBarry Smith .  compute - function to compute the context
980d25893d9SBarry Smith -  destroy - function to destroy the context
981d25893d9SBarry Smith 
982d25893d9SBarry Smith    Level: intermediate
983d25893d9SBarry Smith 
984bb9467b5SJed Brown    Notes:
985bb9467b5SJed Brown    This function is currently not available from Fortran.
986bb9467b5SJed Brown 
987d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context
988d25893d9SBarry Smith 
989d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext()
990d25893d9SBarry Smith @*/
991d25893d9SBarry Smith PetscErrorCode  SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**))
992d25893d9SBarry Smith {
993d25893d9SBarry Smith   PetscFunctionBegin;
994d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
995d25893d9SBarry Smith   snes->ops->usercompute = compute;
996d25893d9SBarry Smith   snes->ops->userdestroy = destroy;
997d25893d9SBarry Smith   PetscFunctionReturn(0);
998d25893d9SBarry Smith }
999a847f771SSatish Balay 
1000b07ff414SBarry Smith /*@
10019b94acceSBarry Smith    SNESSetApplicationContext - Sets the optional user-defined context for
10029b94acceSBarry Smith    the nonlinear solvers.
10039b94acceSBarry Smith 
10043f9fe445SBarry Smith    Logically Collective on SNES
1005fee21e36SBarry Smith 
1006c7afd0dbSLois Curfman McInnes    Input Parameters:
1007c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1008c7afd0dbSLois Curfman McInnes -  usrP - optional user context
1009c7afd0dbSLois Curfman McInnes 
101036851e7fSLois Curfman McInnes    Level: intermediate
101136851e7fSLois Curfman McInnes 
1012daf670e6SBarry Smith    Fortran Notes: To use this from Fortran you must write a Fortran interface definition for this
1013daf670e6SBarry Smith     function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument.
1014daf670e6SBarry Smith 
10159b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context
10169b94acceSBarry Smith 
1017ecaffddaSVictor Eijkhout .seealso: SNESGetApplicationContext()
10189b94acceSBarry Smith @*/
10197087cfbeSBarry Smith PetscErrorCode  SNESSetApplicationContext(SNES snes,void *usrP)
10209b94acceSBarry Smith {
10211b2093e4SBarry Smith   PetscErrorCode ierr;
1022b07ff414SBarry Smith   KSP            ksp;
10231b2093e4SBarry Smith 
10243a40ed3dSBarry Smith   PetscFunctionBegin;
10250700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1026b07ff414SBarry Smith   ierr       = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
1027b07ff414SBarry Smith   ierr       = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr);
10289b94acceSBarry Smith   snes->user = usrP;
10293a40ed3dSBarry Smith   PetscFunctionReturn(0);
10309b94acceSBarry Smith }
103174679c65SBarry Smith 
1032b07ff414SBarry Smith /*@
10339b94acceSBarry Smith    SNESGetApplicationContext - Gets the user-defined context for the
10349b94acceSBarry Smith    nonlinear solvers.
10359b94acceSBarry Smith 
1036c7afd0dbSLois Curfman McInnes    Not Collective
1037c7afd0dbSLois Curfman McInnes 
10389b94acceSBarry Smith    Input Parameter:
10399b94acceSBarry Smith .  snes - SNES context
10409b94acceSBarry Smith 
10419b94acceSBarry Smith    Output Parameter:
10429b94acceSBarry Smith .  usrP - user context
10439b94acceSBarry Smith 
1044daf670e6SBarry Smith    Fortran Notes: To use this from Fortran you must write a Fortran interface definition for this
1045daf670e6SBarry Smith     function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument.
1046daf670e6SBarry Smith 
104736851e7fSLois Curfman McInnes    Level: intermediate
104836851e7fSLois Curfman McInnes 
10499b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context
10509b94acceSBarry Smith 
10519b94acceSBarry Smith .seealso: SNESSetApplicationContext()
10529b94acceSBarry Smith @*/
1053e71120c6SJed Brown PetscErrorCode  SNESGetApplicationContext(SNES snes,void *usrP)
10549b94acceSBarry Smith {
10553a40ed3dSBarry Smith   PetscFunctionBegin;
10560700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1057e71120c6SJed Brown   *(void**)usrP = snes->user;
10583a40ed3dSBarry Smith   PetscFunctionReturn(0);
10599b94acceSBarry Smith }
106074679c65SBarry Smith 
10619b94acceSBarry Smith /*@
1062*3565c898SBarry Smith    SNESSetUseMatrixFree - indicates that SNES should use matrix free finite difference matrix vector products internally to apply
1063*3565c898SBarry Smith                           the Jacobian.
1064*3565c898SBarry Smith 
1065*3565c898SBarry Smith    Collective on SNES
1066*3565c898SBarry Smith 
1067*3565c898SBarry Smith    Input Parameters:
1068*3565c898SBarry Smith +  snes - SNES context
1069*3565c898SBarry 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
1070*3565c898SBarry Smith -  mf_operator - use matrix-free only for the Amat used by SNESSetJacobian(), this means the user provided Pmat will continue to be used
1071*3565c898SBarry Smith 
1072*3565c898SBarry Smith    Options Database:
1073*3565c898SBarry Smith + -snes_mf - use matrix free for both the mat and pmat operator
1074*3565c898SBarry Smith - -snes_mf_operator - use matrix free only for the mat operator
1075*3565c898SBarry Smith 
1076*3565c898SBarry Smith    Level: intermediate
1077*3565c898SBarry Smith 
1078*3565c898SBarry Smith .keywords: SNES, nonlinear, get, iteration, number,
1079*3565c898SBarry Smith 
1080*3565c898SBarry Smith .seealso:   SNESGetUseMatrixFree(), MatCreateSNESMF()
1081*3565c898SBarry Smith @*/
1082*3565c898SBarry Smith PetscErrorCode  SNESSetUseMatrixFree(SNES snes,PetscBool mf_operator,PetscBool mf)
1083*3565c898SBarry Smith {
1084*3565c898SBarry Smith   PetscFunctionBegin;
1085*3565c898SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1086*3565c898SBarry Smith   if (mf && !mf_operator) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_INCOMP,"If using mf must also use mf_operator");
1087*3565c898SBarry Smith   snes->mf          = mf;
1088*3565c898SBarry Smith   snes->mf_operator = mf_operator;
1089*3565c898SBarry Smith   PetscFunctionReturn(0);
1090*3565c898SBarry Smith }
1091*3565c898SBarry Smith 
1092*3565c898SBarry Smith /*@
1093*3565c898SBarry Smith    SNESGetUseMatrixFree - indicates if the SNES uses matrix free finite difference matrix vector products to apply
1094*3565c898SBarry Smith                           the Jacobian.
1095*3565c898SBarry Smith 
1096*3565c898SBarry Smith    Collective on SNES
1097*3565c898SBarry Smith 
1098*3565c898SBarry Smith    Input Parameter:
1099*3565c898SBarry Smith .  snes - SNES context
1100*3565c898SBarry Smith 
1101*3565c898SBarry Smith    Output Parameters:
1102*3565c898SBarry 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
1103*3565c898SBarry Smith -  mf_operator - use matrix-free only for the Amat used by SNESSetJacobian(), this means the user provided Pmat will continue to be used
1104*3565c898SBarry Smith 
1105*3565c898SBarry Smith    Options Database:
1106*3565c898SBarry Smith + -snes_mf - use matrix free for both the mat and pmat operator
1107*3565c898SBarry Smith - -snes_mf_operator - use matrix free only for the mat operator
1108*3565c898SBarry Smith 
1109*3565c898SBarry Smith    Level: intermediate
1110*3565c898SBarry Smith 
1111*3565c898SBarry Smith .keywords: SNES, nonlinear, get, iteration, number,
1112*3565c898SBarry Smith 
1113*3565c898SBarry Smith .seealso:   SNESSetUseMatrixFree(), MatCreateSNESMF()
1114*3565c898SBarry Smith @*/
1115*3565c898SBarry Smith PetscErrorCode  SNESGetUseMatrixFree(SNES snes,PetscBool *mf_operator,PetscBool *mf)
1116*3565c898SBarry Smith {
1117*3565c898SBarry Smith   PetscFunctionBegin;
1118*3565c898SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1119*3565c898SBarry Smith   if (mf)          *mf          = snes->mf;
1120*3565c898SBarry Smith   if (mf_operator) *mf_operator = snes->mf_operator;
1121*3565c898SBarry Smith   PetscFunctionReturn(0);
1122*3565c898SBarry Smith }
1123*3565c898SBarry Smith 
1124*3565c898SBarry Smith /*@
1125c8228a4eSBarry Smith    SNESGetIterationNumber - Gets the number of nonlinear iterations completed
1126c8228a4eSBarry Smith    at this time.
11279b94acceSBarry Smith 
1128c7afd0dbSLois Curfman McInnes    Not Collective
1129c7afd0dbSLois Curfman McInnes 
11309b94acceSBarry Smith    Input Parameter:
11319b94acceSBarry Smith .  snes - SNES context
11329b94acceSBarry Smith 
11339b94acceSBarry Smith    Output Parameter:
11349b94acceSBarry Smith .  iter - iteration number
11359b94acceSBarry Smith 
1136c8228a4eSBarry Smith    Notes:
1137c8228a4eSBarry Smith    For example, during the computation of iteration 2 this would return 1.
1138c8228a4eSBarry Smith 
1139c8228a4eSBarry Smith    This is useful for using lagged Jacobians (where one does not recompute the
114008405cd6SLois Curfman McInnes    Jacobian at each SNES iteration). For example, the code
114108405cd6SLois Curfman McInnes .vb
114208405cd6SLois Curfman McInnes       ierr = SNESGetIterationNumber(snes,&it);
114308405cd6SLois Curfman McInnes       if (!(it % 2)) {
114408405cd6SLois Curfman McInnes         [compute Jacobian here]
114508405cd6SLois Curfman McInnes       }
114608405cd6SLois Curfman McInnes .ve
1147c8228a4eSBarry Smith    can be used in your ComputeJacobian() function to cause the Jacobian to be
114808405cd6SLois Curfman McInnes    recomputed every second SNES iteration.
1149c8228a4eSBarry Smith 
115036851e7fSLois Curfman McInnes    Level: intermediate
115136851e7fSLois Curfman McInnes 
11522b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number,
11532b668275SBarry Smith 
115471dbe336SPeter Brune .seealso:   SNESGetLinearSolveIterations()
11559b94acceSBarry Smith @*/
11567087cfbeSBarry Smith PetscErrorCode  SNESGetIterationNumber(SNES snes,PetscInt *iter)
11579b94acceSBarry Smith {
11583a40ed3dSBarry Smith   PetscFunctionBegin;
11590700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11604482741eSBarry Smith   PetscValidIntPointer(iter,2);
11619b94acceSBarry Smith   *iter = snes->iter;
11623a40ed3dSBarry Smith   PetscFunctionReturn(0);
11639b94acceSBarry Smith }
116474679c65SBarry Smith 
1165360c497dSPeter Brune /*@
1166360c497dSPeter Brune    SNESSetIterationNumber - Sets the current iteration number.
1167360c497dSPeter Brune 
1168360c497dSPeter Brune    Not Collective
1169360c497dSPeter Brune 
1170360c497dSPeter Brune    Input Parameter:
1171360c497dSPeter Brune .  snes - SNES context
1172360c497dSPeter Brune .  iter - iteration number
1173360c497dSPeter Brune 
1174360c497dSPeter Brune    Level: developer
1175360c497dSPeter Brune 
1176360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number,
1177360c497dSPeter Brune 
117871dbe336SPeter Brune .seealso:   SNESGetLinearSolveIterations()
1179360c497dSPeter Brune @*/
1180360c497dSPeter Brune PetscErrorCode  SNESSetIterationNumber(SNES snes,PetscInt iter)
1181360c497dSPeter Brune {
1182360c497dSPeter Brune   PetscErrorCode ierr;
1183360c497dSPeter Brune 
1184360c497dSPeter Brune   PetscFunctionBegin;
1185360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1186e04113cfSBarry Smith   ierr       = PetscObjectSAWsTakeAccess((PetscObject)snes);CHKERRQ(ierr);
1187360c497dSPeter Brune   snes->iter = iter;
1188e04113cfSBarry Smith   ierr       = PetscObjectSAWsGrantAccess((PetscObject)snes);CHKERRQ(ierr);
1189360c497dSPeter Brune   PetscFunctionReturn(0);
1190360c497dSPeter Brune }
1191360c497dSPeter Brune 
11929b94acceSBarry Smith /*@
1193b850b91aSLisandro Dalcin    SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
11949b94acceSBarry Smith    attempted by the nonlinear solver.
11959b94acceSBarry Smith 
1196c7afd0dbSLois Curfman McInnes    Not Collective
1197c7afd0dbSLois Curfman McInnes 
11989b94acceSBarry Smith    Input Parameter:
11999b94acceSBarry Smith .  snes - SNES context
12009b94acceSBarry Smith 
12019b94acceSBarry Smith    Output Parameter:
12029b94acceSBarry Smith .  nfails - number of unsuccessful steps attempted
12039b94acceSBarry Smith 
1204c96a6f78SLois Curfman McInnes    Notes:
1205c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
1206c96a6f78SLois Curfman McInnes 
120736851e7fSLois Curfman McInnes    Level: intermediate
120836851e7fSLois Curfman McInnes 
12099b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
121058ebbce7SBarry Smith 
1211e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
121258ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures()
12139b94acceSBarry Smith @*/
12147087cfbeSBarry Smith PetscErrorCode  SNESGetNonlinearStepFailures(SNES snes,PetscInt *nfails)
12159b94acceSBarry Smith {
12163a40ed3dSBarry Smith   PetscFunctionBegin;
12170700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
12184482741eSBarry Smith   PetscValidIntPointer(nfails,2);
121950ffb88aSMatthew Knepley   *nfails = snes->numFailures;
122050ffb88aSMatthew Knepley   PetscFunctionReturn(0);
122150ffb88aSMatthew Knepley }
122250ffb88aSMatthew Knepley 
122350ffb88aSMatthew Knepley /*@
1224b850b91aSLisandro Dalcin    SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
122550ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
122650ffb88aSMatthew Knepley 
122750ffb88aSMatthew Knepley    Not Collective
122850ffb88aSMatthew Knepley 
122950ffb88aSMatthew Knepley    Input Parameters:
123050ffb88aSMatthew Knepley +  snes     - SNES context
123150ffb88aSMatthew Knepley -  maxFails - maximum of unsuccessful steps
123250ffb88aSMatthew Knepley 
123350ffb88aSMatthew Knepley    Level: intermediate
123450ffb88aSMatthew Knepley 
123550ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
123658ebbce7SBarry Smith 
1237e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
123858ebbce7SBarry Smith           SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
123950ffb88aSMatthew Knepley @*/
12407087cfbeSBarry Smith PetscErrorCode  SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
124150ffb88aSMatthew Knepley {
124250ffb88aSMatthew Knepley   PetscFunctionBegin;
12430700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
124450ffb88aSMatthew Knepley   snes->maxFailures = maxFails;
124550ffb88aSMatthew Knepley   PetscFunctionReturn(0);
124650ffb88aSMatthew Knepley }
124750ffb88aSMatthew Knepley 
124850ffb88aSMatthew Knepley /*@
1249b850b91aSLisandro Dalcin    SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
125050ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
125150ffb88aSMatthew Knepley 
125250ffb88aSMatthew Knepley    Not Collective
125350ffb88aSMatthew Knepley 
125450ffb88aSMatthew Knepley    Input Parameter:
125550ffb88aSMatthew Knepley .  snes     - SNES context
125650ffb88aSMatthew Knepley 
125750ffb88aSMatthew Knepley    Output Parameter:
125850ffb88aSMatthew Knepley .  maxFails - maximum of unsuccessful steps
125950ffb88aSMatthew Knepley 
126050ffb88aSMatthew Knepley    Level: intermediate
126150ffb88aSMatthew Knepley 
126250ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
126358ebbce7SBarry Smith 
1264e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
126558ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
126658ebbce7SBarry Smith 
126750ffb88aSMatthew Knepley @*/
12687087cfbeSBarry Smith PetscErrorCode  SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
126950ffb88aSMatthew Knepley {
127050ffb88aSMatthew Knepley   PetscFunctionBegin;
12710700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
12724482741eSBarry Smith   PetscValidIntPointer(maxFails,2);
127350ffb88aSMatthew Knepley   *maxFails = snes->maxFailures;
12743a40ed3dSBarry Smith   PetscFunctionReturn(0);
12759b94acceSBarry Smith }
1276a847f771SSatish Balay 
12772541af92SBarry Smith /*@
12782541af92SBarry Smith    SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations
12792541af92SBarry Smith      done by SNES.
12802541af92SBarry Smith 
12812541af92SBarry Smith    Not Collective
12822541af92SBarry Smith 
12832541af92SBarry Smith    Input Parameter:
12842541af92SBarry Smith .  snes     - SNES context
12852541af92SBarry Smith 
12862541af92SBarry Smith    Output Parameter:
12872541af92SBarry Smith .  nfuncs - number of evaluations
12882541af92SBarry Smith 
12892541af92SBarry Smith    Level: intermediate
12902541af92SBarry Smith 
1291971e163fSPeter Brune    Notes: Reset every time SNESSolve is called unless SNESSetCountersReset() is used.
1292971e163fSPeter Brune 
12932541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
129458ebbce7SBarry Smith 
1295971e163fSPeter Brune .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), SNESSetCountersReset()
12962541af92SBarry Smith @*/
12977087cfbeSBarry Smith PetscErrorCode  SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs)
12982541af92SBarry Smith {
12992541af92SBarry Smith   PetscFunctionBegin;
13000700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
13012541af92SBarry Smith   PetscValidIntPointer(nfuncs,2);
13022541af92SBarry Smith   *nfuncs = snes->nfuncs;
13032541af92SBarry Smith   PetscFunctionReturn(0);
13042541af92SBarry Smith }
13052541af92SBarry Smith 
13063d4c4710SBarry Smith /*@
13073d4c4710SBarry Smith    SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
13083d4c4710SBarry Smith    linear solvers.
13093d4c4710SBarry Smith 
13103d4c4710SBarry Smith    Not Collective
13113d4c4710SBarry Smith 
13123d4c4710SBarry Smith    Input Parameter:
13133d4c4710SBarry Smith .  snes - SNES context
13143d4c4710SBarry Smith 
13153d4c4710SBarry Smith    Output Parameter:
13163d4c4710SBarry Smith .  nfails - number of failed solves
13173d4c4710SBarry Smith 
13189d85da0cSMatthew G. Knepley    Level: intermediate
13199d85da0cSMatthew G. Knepley 
13209d85da0cSMatthew G. Knepley    Options Database Keys:
13219d85da0cSMatthew G. Knepley . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated
13229d85da0cSMatthew G. Knepley 
13233d4c4710SBarry Smith    Notes:
13243d4c4710SBarry Smith    This counter is reset to zero for each successive call to SNESSolve().
13253d4c4710SBarry Smith 
13263d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
132758ebbce7SBarry Smith 
1328e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures()
13293d4c4710SBarry Smith @*/
13307087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveFailures(SNES snes,PetscInt *nfails)
13313d4c4710SBarry Smith {
13323d4c4710SBarry Smith   PetscFunctionBegin;
13330700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
13343d4c4710SBarry Smith   PetscValidIntPointer(nfails,2);
13353d4c4710SBarry Smith   *nfails = snes->numLinearSolveFailures;
13363d4c4710SBarry Smith   PetscFunctionReturn(0);
13373d4c4710SBarry Smith }
13383d4c4710SBarry Smith 
13393d4c4710SBarry Smith /*@
13403d4c4710SBarry Smith    SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
13413d4c4710SBarry Smith    allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE
13423d4c4710SBarry Smith 
13433f9fe445SBarry Smith    Logically Collective on SNES
13443d4c4710SBarry Smith 
13453d4c4710SBarry Smith    Input Parameters:
13463d4c4710SBarry Smith +  snes     - SNES context
13473d4c4710SBarry Smith -  maxFails - maximum allowed linear solve failures
13483d4c4710SBarry Smith 
13493d4c4710SBarry Smith    Level: intermediate
13503d4c4710SBarry Smith 
13519d85da0cSMatthew G. Knepley    Options Database Keys:
13529d85da0cSMatthew G. Knepley . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated
13539d85da0cSMatthew G. Knepley 
1354a6796414SBarry Smith    Notes: By default this is 0; that is SNES returns on the first failed linear solve
13553d4c4710SBarry Smith 
13563d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
13573d4c4710SBarry Smith 
135858ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations()
13593d4c4710SBarry Smith @*/
13607087cfbeSBarry Smith PetscErrorCode  SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
13613d4c4710SBarry Smith {
13623d4c4710SBarry Smith   PetscFunctionBegin;
13630700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1364c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxFails,2);
13653d4c4710SBarry Smith   snes->maxLinearSolveFailures = maxFails;
13663d4c4710SBarry Smith   PetscFunctionReturn(0);
13673d4c4710SBarry Smith }
13683d4c4710SBarry Smith 
13693d4c4710SBarry Smith /*@
13703d4c4710SBarry Smith    SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
13713d4c4710SBarry Smith      are allowed before SNES terminates
13723d4c4710SBarry Smith 
13733d4c4710SBarry Smith    Not Collective
13743d4c4710SBarry Smith 
13753d4c4710SBarry Smith    Input Parameter:
13763d4c4710SBarry Smith .  snes     - SNES context
13773d4c4710SBarry Smith 
13783d4c4710SBarry Smith    Output Parameter:
13793d4c4710SBarry Smith .  maxFails - maximum of unsuccessful solves allowed
13803d4c4710SBarry Smith 
13813d4c4710SBarry Smith    Level: intermediate
13823d4c4710SBarry Smith 
13833d4c4710SBarry Smith    Notes: By default this is 1; that is SNES returns on the first failed linear solve
13843d4c4710SBarry Smith 
13853d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
13863d4c4710SBarry Smith 
1387e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(),
13883d4c4710SBarry Smith @*/
13897087cfbeSBarry Smith PetscErrorCode  SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
13903d4c4710SBarry Smith {
13913d4c4710SBarry Smith   PetscFunctionBegin;
13920700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
13933d4c4710SBarry Smith   PetscValidIntPointer(maxFails,2);
13943d4c4710SBarry Smith   *maxFails = snes->maxLinearSolveFailures;
13953d4c4710SBarry Smith   PetscFunctionReturn(0);
13963d4c4710SBarry Smith }
13973d4c4710SBarry Smith 
1398c96a6f78SLois Curfman McInnes /*@
1399b850b91aSLisandro Dalcin    SNESGetLinearSolveIterations - Gets the total number of linear iterations
1400c96a6f78SLois Curfman McInnes    used by the nonlinear solver.
1401c96a6f78SLois Curfman McInnes 
1402c7afd0dbSLois Curfman McInnes    Not Collective
1403c7afd0dbSLois Curfman McInnes 
1404c96a6f78SLois Curfman McInnes    Input Parameter:
1405c96a6f78SLois Curfman McInnes .  snes - SNES context
1406c96a6f78SLois Curfman McInnes 
1407c96a6f78SLois Curfman McInnes    Output Parameter:
1408c96a6f78SLois Curfman McInnes .  lits - number of linear iterations
1409c96a6f78SLois Curfman McInnes 
1410c96a6f78SLois Curfman McInnes    Notes:
1411971e163fSPeter Brune    This counter is reset to zero for each successive call to SNESSolve() unless SNESSetCountersReset() is used.
1412c96a6f78SLois Curfman McInnes 
1413010be392SBarry 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
1414010be392SBarry Smith    then call KSPGetIterationNumber() after the failed solve.
1415010be392SBarry Smith 
141636851e7fSLois Curfman McInnes    Level: intermediate
141736851e7fSLois Curfman McInnes 
1418c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations
14192b668275SBarry Smith 
142071dbe336SPeter Brune .seealso:  SNESGetIterationNumber(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESSetCountersReset()
1421c96a6f78SLois Curfman McInnes @*/
14227087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveIterations(SNES snes,PetscInt *lits)
1423c96a6f78SLois Curfman McInnes {
14243a40ed3dSBarry Smith   PetscFunctionBegin;
14250700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
14264482741eSBarry Smith   PetscValidIntPointer(lits,2);
1427c96a6f78SLois Curfman McInnes   *lits = snes->linear_its;
14283a40ed3dSBarry Smith   PetscFunctionReturn(0);
1429c96a6f78SLois Curfman McInnes }
1430c96a6f78SLois Curfman McInnes 
1431971e163fSPeter Brune /*@
1432971e163fSPeter Brune    SNESSetCountersReset - Sets whether or not the counters for linear iterations and function evaluations
1433971e163fSPeter Brune    are reset every time SNESSolve() is called.
1434971e163fSPeter Brune 
1435971e163fSPeter Brune    Logically Collective on SNES
1436971e163fSPeter Brune 
1437971e163fSPeter Brune    Input Parameter:
1438971e163fSPeter Brune +  snes - SNES context
1439971e163fSPeter Brune -  reset - whether to reset the counters or not
1440971e163fSPeter Brune 
1441971e163fSPeter Brune    Notes:
1442fa19ca70SBarry Smith    This defaults to PETSC_TRUE
1443971e163fSPeter Brune 
1444971e163fSPeter Brune    Level: developer
1445971e163fSPeter Brune 
1446971e163fSPeter Brune .keywords: SNES, nonlinear, set, reset, number, linear, iterations
1447971e163fSPeter Brune 
1448734794cfSBarry Smith .seealso:  SNESGetNumberFunctionEvals(), SNESGetLinearSolveIterations(), SNESGetNPC()
1449971e163fSPeter Brune @*/
1450971e163fSPeter Brune PetscErrorCode  SNESSetCountersReset(SNES snes,PetscBool reset)
1451971e163fSPeter Brune {
1452971e163fSPeter Brune   PetscFunctionBegin;
1453971e163fSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1454971e163fSPeter Brune   PetscValidLogicalCollectiveBool(snes,reset,2);
1455971e163fSPeter Brune   snes->counters_reset = reset;
1456971e163fSPeter Brune   PetscFunctionReturn(0);
1457971e163fSPeter Brune }
1458971e163fSPeter Brune 
145982bf6240SBarry Smith 
14602999313aSBarry Smith /*@
14612999313aSBarry Smith    SNESSetKSP - Sets a KSP context for the SNES object to use
14622999313aSBarry Smith 
14632999313aSBarry Smith    Not Collective, but the SNES and KSP objects must live on the same MPI_Comm
14642999313aSBarry Smith 
14652999313aSBarry Smith    Input Parameters:
14662999313aSBarry Smith +  snes - the SNES context
14672999313aSBarry Smith -  ksp - the KSP context
14682999313aSBarry Smith 
14692999313aSBarry Smith    Notes:
14702999313aSBarry Smith    The SNES object already has its KSP object, you can obtain with SNESGetKSP()
14712999313aSBarry Smith    so this routine is rarely needed.
14722999313aSBarry Smith 
14732999313aSBarry Smith    The KSP object that is already in the SNES object has its reference count
14742999313aSBarry Smith    decreased by one.
14752999313aSBarry Smith 
14762999313aSBarry Smith    Level: developer
14772999313aSBarry Smith 
14782999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
14792999313aSBarry Smith 
14802999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
14812999313aSBarry Smith @*/
14827087cfbeSBarry Smith PetscErrorCode  SNESSetKSP(SNES snes,KSP ksp)
14832999313aSBarry Smith {
14842999313aSBarry Smith   PetscErrorCode ierr;
14852999313aSBarry Smith 
14862999313aSBarry Smith   PetscFunctionBegin;
14870700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
14880700a824SBarry Smith   PetscValidHeaderSpecific(ksp,KSP_CLASSID,2);
14892999313aSBarry Smith   PetscCheckSameComm(snes,1,ksp,2);
14907dcf0eaaSdalcinl   ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr);
1491906ed7ccSBarry Smith   if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);}
14922999313aSBarry Smith   snes->ksp = ksp;
14932999313aSBarry Smith   PetscFunctionReturn(0);
14942999313aSBarry Smith }
14952999313aSBarry Smith 
14969b94acceSBarry Smith /* -----------------------------------------------------------*/
149752baeb72SSatish Balay /*@
14989b94acceSBarry Smith    SNESCreate - Creates a nonlinear solver context.
14999b94acceSBarry Smith 
1500c7afd0dbSLois Curfman McInnes    Collective on MPI_Comm
1501c7afd0dbSLois Curfman McInnes 
1502c7afd0dbSLois Curfman McInnes    Input Parameters:
1503906ed7ccSBarry Smith .  comm - MPI communicator
15049b94acceSBarry Smith 
15059b94acceSBarry Smith    Output Parameter:
15069b94acceSBarry Smith .  outsnes - the new SNES context
15079b94acceSBarry Smith 
1508c7afd0dbSLois Curfman McInnes    Options Database Keys:
1509c7afd0dbSLois Curfman McInnes +   -snes_mf - Activates default matrix-free Jacobian-vector products,
1510c7afd0dbSLois Curfman McInnes                and no preconditioning matrix
1511c7afd0dbSLois Curfman McInnes .   -snes_mf_operator - Activates default matrix-free Jacobian-vector
1512c7afd0dbSLois Curfman McInnes                products, and a user-provided preconditioning matrix
1513c7afd0dbSLois Curfman McInnes                as set by SNESSetJacobian()
1514c7afd0dbSLois Curfman McInnes -   -snes_fd - Uses (slow!) finite differences to compute Jacobian
1515c1f60f51SBarry Smith 
151636851e7fSLois Curfman McInnes    Level: beginner
151736851e7fSLois Curfman McInnes 
15189b94acceSBarry Smith .keywords: SNES, nonlinear, create, context
15199b94acceSBarry Smith 
1520a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner()
1521a8054027SBarry Smith 
15229b94acceSBarry Smith @*/
15237087cfbeSBarry Smith PetscErrorCode  SNESCreate(MPI_Comm comm,SNES *outsnes)
15249b94acceSBarry Smith {
1525dfbe8321SBarry Smith   PetscErrorCode ierr;
15269b94acceSBarry Smith   SNES           snes;
1527fa9f3622SBarry Smith   SNESKSPEW      *kctx;
152837fcc0dbSBarry Smith 
15293a40ed3dSBarry Smith   PetscFunctionBegin;
1530ed1caa07SMatthew Knepley   PetscValidPointer(outsnes,2);
15310298fd71SBarry Smith   *outsnes = NULL;
1532607a6623SBarry Smith   ierr = SNESInitializePackage();CHKERRQ(ierr);
15338ba1e511SMatthew Knepley 
153473107ff1SLisandro Dalcin   ierr = PetscHeaderCreate(snes,SNES_CLASSID,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr);
15357adad957SLisandro Dalcin 
15368d359177SBarry Smith   snes->ops->converged    = SNESConvergedDefault;
15372c155ee1SBarry Smith   snes->usesksp           = PETSC_TRUE;
153888976e71SPeter Brune   snes->tolerancesset     = PETSC_FALSE;
15399b94acceSBarry Smith   snes->max_its           = 50;
15409750a799SBarry Smith   snes->max_funcs         = 10000;
15419b94acceSBarry Smith   snes->norm              = 0.0;
1542365a6726SPeter Brune   snes->normschedule      = SNES_NORM_ALWAYS;
15436c67d002SPeter Brune   snes->functype          = SNES_FUNCTION_DEFAULT;
15443a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE)
15453a2046daSBarry Smith   snes->rtol              = 1.e-5;
15463a2046daSBarry Smith #else
1547b4874afaSBarry Smith   snes->rtol              = 1.e-8;
15483a2046daSBarry Smith #endif
1549b4874afaSBarry Smith   snes->ttol              = 0.0;
15503a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE)
15513a2046daSBarry Smith   snes->abstol            = 1.e-25;
15523a2046daSBarry Smith #else
155370441072SBarry Smith   snes->abstol            = 1.e-50;
15543a2046daSBarry Smith #endif
15557cd0ae37SLisandro Dalcin #if defined(PETSC_USE_REAL_SINGLE)
15567cd0ae37SLisandro Dalcin   snes->stol              = 1.e-5;
15577cd0ae37SLisandro Dalcin #else
1558c60f73f4SPeter Brune   snes->stol              = 1.e-8;
15597cd0ae37SLisandro Dalcin #endif
15603a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE)
15613a2046daSBarry Smith   snes->deltatol          = 1.e-6;
15623a2046daSBarry Smith #else
15634b27c08aSLois Curfman McInnes   snes->deltatol          = 1.e-12;
15643a2046daSBarry Smith #endif
1565e37c518bSBarry Smith   snes->divtol            = 1.e4;
1566e37c518bSBarry Smith   snes->rnorm0            = 0;
15679b94acceSBarry Smith   snes->nfuncs            = 0;
156850ffb88aSMatthew Knepley   snes->numFailures       = 0;
156950ffb88aSMatthew Knepley   snes->maxFailures       = 1;
15707a00f4a9SLois Curfman McInnes   snes->linear_its        = 0;
1571e35cf81dSBarry Smith   snes->lagjacobian       = 1;
157237ec4e1aSPeter Brune   snes->jac_iter          = 0;
157337ec4e1aSPeter Brune   snes->lagjac_persist    = PETSC_FALSE;
1574a8054027SBarry Smith   snes->lagpreconditioner = 1;
157537ec4e1aSPeter Brune   snes->pre_iter          = 0;
157637ec4e1aSPeter Brune   snes->lagpre_persist    = PETSC_FALSE;
1577639f9d9dSBarry Smith   snes->numbermonitors    = 0;
15789b94acceSBarry Smith   snes->data              = 0;
15794dc4c822SBarry Smith   snes->setupcalled       = PETSC_FALSE;
1580186905e3SBarry Smith   snes->ksp_ewconv        = PETSC_FALSE;
15816f24a144SLois Curfman McInnes   snes->nwork             = 0;
158258c9b817SLisandro Dalcin   snes->work              = 0;
158358c9b817SLisandro Dalcin   snes->nvwork            = 0;
158458c9b817SLisandro Dalcin   snes->vwork             = 0;
1585758f92a0SBarry Smith   snes->conv_hist_len     = 0;
1586758f92a0SBarry Smith   snes->conv_hist_max     = 0;
15870298fd71SBarry Smith   snes->conv_hist         = NULL;
15880298fd71SBarry Smith   snes->conv_hist_its     = NULL;
1589758f92a0SBarry Smith   snes->conv_hist_reset   = PETSC_TRUE;
1590971e163fSPeter Brune   snes->counters_reset    = PETSC_TRUE;
1591e4ed7901SPeter Brune   snes->vec_func_init_set = PETSC_FALSE;
1592184914b5SBarry Smith   snes->reason            = SNES_CONVERGED_ITERATING;
1593c40d0f55SPeter Brune   snes->pcside            = PC_RIGHT;
1594c40d0f55SPeter Brune 
1595d8f46077SPeter Brune   snes->mf          = PETSC_FALSE;
1596d8f46077SPeter Brune   snes->mf_operator = PETSC_FALSE;
1597d8f46077SPeter Brune   snes->mf_version  = 1;
1598d8f46077SPeter Brune 
15993d4c4710SBarry Smith   snes->numLinearSolveFailures = 0;
16003d4c4710SBarry Smith   snes->maxLinearSolveFailures = 1;
16013d4c4710SBarry Smith 
1602349187a7SBarry Smith   snes->vizerotolerance = 1.e-8;
1603349187a7SBarry Smith 
16044fc747eaSLawrence Mitchell   /* Set this to true if the implementation of SNESSolve_XXX does compute the residual at the final solution. */
16054fc747eaSLawrence Mitchell   snes->alwayscomputesfinalresidual = PETSC_FALSE;
16064fc747eaSLawrence Mitchell 
16079b94acceSBarry Smith   /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
1608b00a9115SJed Brown   ierr = PetscNewLog(snes,&kctx);CHKERRQ(ierr);
1609f5af7f23SKarl Rupp 
16109b94acceSBarry Smith   snes->kspconvctx  = (void*)kctx;
16119b94acceSBarry Smith   kctx->version     = 2;
16129b94acceSBarry Smith   kctx->rtol_0      = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
16139b94acceSBarry Smith                              this was too large for some test cases */
161475567043SBarry Smith   kctx->rtol_last   = 0.0;
16159b94acceSBarry Smith   kctx->rtol_max    = .9;
16169b94acceSBarry Smith   kctx->gamma       = 1.0;
161762d1f40fSBarry Smith   kctx->alpha       = .5*(1.0 + PetscSqrtReal(5.0));
161871f87433Sdalcinl   kctx->alpha2      = kctx->alpha;
16199b94acceSBarry Smith   kctx->threshold   = .1;
162075567043SBarry Smith   kctx->lresid_last = 0.0;
162175567043SBarry Smith   kctx->norm_last   = 0.0;
16229b94acceSBarry Smith 
16239b94acceSBarry Smith   *outsnes = snes;
16243a40ed3dSBarry Smith   PetscFunctionReturn(0);
16259b94acceSBarry Smith }
16269b94acceSBarry Smith 
162788f0584fSBarry Smith /*MC
1628411c0326SBarry Smith     SNESFunction - Functional form used to convey the nonlinear function to be solved by SNES
162988f0584fSBarry Smith 
163088f0584fSBarry Smith      Synopsis:
1631411c0326SBarry Smith      #include "petscsnes.h"
1632411c0326SBarry Smith      PetscErrorCode SNESFunction(SNES snes,Vec x,Vec f,void *ctx);
163388f0584fSBarry Smith 
163488f0584fSBarry Smith      Input Parameters:
163588f0584fSBarry Smith +     snes - the SNES context
163688f0584fSBarry Smith .     x    - state at which to evaluate residual
163788f0584fSBarry Smith -     ctx     - optional user-defined function context, passed in with SNESSetFunction()
163888f0584fSBarry Smith 
163988f0584fSBarry Smith      Output Parameter:
164088f0584fSBarry Smith .     f  - vector to put residual (function value)
164188f0584fSBarry Smith 
1642878cb397SSatish Balay    Level: intermediate
1643878cb397SSatish Balay 
164488f0584fSBarry Smith .seealso:   SNESSetFunction(), SNESGetFunction()
164588f0584fSBarry Smith M*/
164688f0584fSBarry Smith 
16479b94acceSBarry Smith /*@C
16489b94acceSBarry Smith    SNESSetFunction - Sets the function evaluation routine and function
16499b94acceSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
16509b94acceSBarry Smith    equations.
16519b94acceSBarry Smith 
16523f9fe445SBarry Smith    Logically Collective on SNES
1653fee21e36SBarry Smith 
1654c7afd0dbSLois Curfman McInnes    Input Parameters:
1655c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1656c7afd0dbSLois Curfman McInnes .  r - vector to store function value
1657f8b49ee9SBarry Smith .  f - function evaluation routine; see SNESFunction for calling sequence details
1658c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
16590298fd71SBarry Smith          function evaluation routine (may be NULL)
16609b94acceSBarry Smith 
16619b94acceSBarry Smith    Notes:
16629b94acceSBarry Smith    The Newton-like methods typically solve linear systems of the form
16639b94acceSBarry Smith $      f'(x) x = -f(x),
1664c7afd0dbSLois Curfman McInnes    where f'(x) denotes the Jacobian matrix and f(x) is the function.
16659b94acceSBarry Smith 
166636851e7fSLois Curfman McInnes    Level: beginner
166736851e7fSLois Curfman McInnes 
16689b94acceSBarry Smith .keywords: SNES, nonlinear, set, function
16699b94acceSBarry Smith 
1670bf388a1fSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard(), SNESFunction
16719b94acceSBarry Smith @*/
1672f8b49ee9SBarry Smith PetscErrorCode  SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx)
16739b94acceSBarry Smith {
167485385478SLisandro Dalcin   PetscErrorCode ierr;
16756cab3a1bSJed Brown   DM             dm;
16766cab3a1bSJed Brown 
16773a40ed3dSBarry Smith   PetscFunctionBegin;
16780700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1679d2a683ecSLisandro Dalcin   if (r) {
1680d2a683ecSLisandro Dalcin     PetscValidHeaderSpecific(r,VEC_CLASSID,2);
1681d2a683ecSLisandro Dalcin     PetscCheckSameComm(snes,1,r,2);
168285385478SLisandro Dalcin     ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr);
16836bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
1684f5af7f23SKarl Rupp 
168585385478SLisandro Dalcin     snes->vec_func = r;
1686d2a683ecSLisandro Dalcin   }
16876cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
1688f8b49ee9SBarry Smith   ierr = DMSNESSetFunction(dm,f,ctx);CHKERRQ(ierr);
16893a40ed3dSBarry Smith   PetscFunctionReturn(0);
16909b94acceSBarry Smith }
16919b94acceSBarry Smith 
1692646217ecSPeter Brune 
1693e4ed7901SPeter Brune /*@C
1694e4ed7901SPeter Brune    SNESSetInitialFunction - Sets the function vector to be used as the
1695e4ed7901SPeter Brune    function norm at the initialization of the method.  In some
1696e4ed7901SPeter Brune    instances, the user has precomputed the function before calling
1697e4ed7901SPeter Brune    SNESSolve.  This function allows one to avoid a redundant call
1698e4ed7901SPeter Brune    to SNESComputeFunction in that case.
1699e4ed7901SPeter Brune 
1700e4ed7901SPeter Brune    Logically Collective on SNES
1701e4ed7901SPeter Brune 
1702e4ed7901SPeter Brune    Input Parameters:
1703e4ed7901SPeter Brune +  snes - the SNES context
1704e4ed7901SPeter Brune -  f - vector to store function value
1705e4ed7901SPeter Brune 
1706e4ed7901SPeter Brune    Notes:
1707e4ed7901SPeter Brune    This should not be modified during the solution procedure.
1708e4ed7901SPeter Brune 
1709e4ed7901SPeter Brune    This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning.
1710e4ed7901SPeter Brune 
1711e4ed7901SPeter Brune    Level: developer
1712e4ed7901SPeter Brune 
1713e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function
1714e4ed7901SPeter Brune 
1715e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunctionNorm()
1716e4ed7901SPeter Brune @*/
1717e4ed7901SPeter Brune PetscErrorCode  SNESSetInitialFunction(SNES snes, Vec f)
1718e4ed7901SPeter Brune {
1719e4ed7901SPeter Brune   PetscErrorCode ierr;
1720e4ed7901SPeter Brune   Vec            vec_func;
1721e4ed7901SPeter Brune 
1722e4ed7901SPeter Brune   PetscFunctionBegin;
1723e4ed7901SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1724e4ed7901SPeter Brune   PetscValidHeaderSpecific(f,VEC_CLASSID,2);
1725e4ed7901SPeter Brune   PetscCheckSameComm(snes,1,f,2);
17265c9e203fSPeter Brune   if (snes->pcside == PC_LEFT && snes->functype == SNES_FUNCTION_PRECONDITIONED) {
1727902f982fSPeter Brune     snes->vec_func_init_set = PETSC_FALSE;
1728902f982fSPeter Brune     PetscFunctionReturn(0);
1729902f982fSPeter Brune   }
17300298fd71SBarry Smith   ierr = SNESGetFunction(snes,&vec_func,NULL,NULL);CHKERRQ(ierr);
1731e4ed7901SPeter Brune   ierr = VecCopy(f, vec_func);CHKERRQ(ierr);
1732f5af7f23SKarl Rupp 
1733217b9c2eSPeter Brune   snes->vec_func_init_set = PETSC_TRUE;
1734e4ed7901SPeter Brune   PetscFunctionReturn(0);
1735e4ed7901SPeter Brune }
1736e4ed7901SPeter Brune 
1737534ebe21SPeter Brune /*@
1738365a6726SPeter Brune    SNESSetNormSchedule - Sets the SNESNormSchedule used in covergence and monitoring
1739534ebe21SPeter Brune    of the SNES method.
1740534ebe21SPeter Brune 
1741534ebe21SPeter Brune    Logically Collective on SNES
1742534ebe21SPeter Brune 
1743534ebe21SPeter Brune    Input Parameters:
1744534ebe21SPeter Brune +  snes - the SNES context
1745365a6726SPeter Brune -  normschedule - the frequency of norm computation
1746534ebe21SPeter Brune 
1747517f1916SMatthew G. Knepley    Options Database Key:
1748517f1916SMatthew G. Knepley .  -snes_norm_schedule <none, always, initialonly, finalonly, initalfinalonly>
1749517f1916SMatthew G. Knepley 
1750534ebe21SPeter Brune    Notes:
1751365a6726SPeter Brune    Only certain SNES methods support certain SNESNormSchedules.  Most require evaluation
1752534ebe21SPeter Brune    of the nonlinear function and the taking of its norm at every iteration to
1753534ebe21SPeter Brune    even ensure convergence at all.  However, methods such as custom Gauss-Seidel methods
1754be95d8f1SBarry Smith    (SNESNGS) and the like do not require the norm of the function to be computed, and therfore
1755534ebe21SPeter Brune    may either be monitored for convergence or not.  As these are often used as nonlinear
1756534ebe21SPeter Brune    preconditioners, monitoring the norm of their error is not a useful enterprise within
1757534ebe21SPeter Brune    their solution.
1758534ebe21SPeter Brune 
1759534ebe21SPeter Brune    Level: developer
1760534ebe21SPeter Brune 
1761534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type
1762534ebe21SPeter Brune 
1763365a6726SPeter Brune .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
1764534ebe21SPeter Brune @*/
1765365a6726SPeter Brune PetscErrorCode  SNESSetNormSchedule(SNES snes, SNESNormSchedule normschedule)
1766534ebe21SPeter Brune {
1767534ebe21SPeter Brune   PetscFunctionBegin;
1768534ebe21SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1769365a6726SPeter Brune   snes->normschedule = normschedule;
1770534ebe21SPeter Brune   PetscFunctionReturn(0);
1771534ebe21SPeter Brune }
1772534ebe21SPeter Brune 
1773534ebe21SPeter Brune 
1774534ebe21SPeter Brune /*@
1775365a6726SPeter Brune    SNESGetNormSchedule - Gets the SNESNormSchedule used in covergence and monitoring
1776534ebe21SPeter Brune    of the SNES method.
1777534ebe21SPeter Brune 
1778534ebe21SPeter Brune    Logically Collective on SNES
1779534ebe21SPeter Brune 
1780534ebe21SPeter Brune    Input Parameters:
1781534ebe21SPeter Brune +  snes - the SNES context
1782365a6726SPeter Brune -  normschedule - the type of the norm used
1783534ebe21SPeter Brune 
1784534ebe21SPeter Brune    Level: advanced
1785534ebe21SPeter Brune 
1786534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type
1787534ebe21SPeter Brune 
1788365a6726SPeter Brune .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
1789534ebe21SPeter Brune @*/
1790365a6726SPeter Brune PetscErrorCode  SNESGetNormSchedule(SNES snes, SNESNormSchedule *normschedule)
1791534ebe21SPeter Brune {
1792534ebe21SPeter Brune   PetscFunctionBegin;
1793534ebe21SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1794365a6726SPeter Brune   *normschedule = snes->normschedule;
1795534ebe21SPeter Brune   PetscFunctionReturn(0);
1796534ebe21SPeter Brune }
1797534ebe21SPeter Brune 
179847073ea2SPeter Brune 
1799c5ce4427SMatthew G. Knepley /*@
1800c5ce4427SMatthew G. Knepley   SNESSetFunctionNorm - Sets the last computed residual norm.
1801c5ce4427SMatthew G. Knepley 
1802c5ce4427SMatthew G. Knepley   Logically Collective on SNES
1803c5ce4427SMatthew G. Knepley 
1804c5ce4427SMatthew G. Knepley   Input Parameters:
1805c5ce4427SMatthew G. Knepley + snes - the SNES context
1806c5ce4427SMatthew G. Knepley 
1807c5ce4427SMatthew G. Knepley - normschedule - the frequency of norm computation
1808c5ce4427SMatthew G. Knepley 
1809c5ce4427SMatthew G. Knepley   Level: developer
1810c5ce4427SMatthew G. Knepley 
1811c5ce4427SMatthew G. Knepley .keywords: SNES, nonlinear, set, function, norm, type
1812c5ce4427SMatthew G. Knepley .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
1813c5ce4427SMatthew G. Knepley @*/
1814c5ce4427SMatthew G. Knepley PetscErrorCode SNESSetFunctionNorm(SNES snes, PetscReal norm)
1815c5ce4427SMatthew G. Knepley {
1816c5ce4427SMatthew G. Knepley   PetscFunctionBegin;
1817c5ce4427SMatthew G. Knepley   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1818c5ce4427SMatthew G. Knepley   snes->norm = norm;
1819c5ce4427SMatthew G. Knepley   PetscFunctionReturn(0);
1820c5ce4427SMatthew G. Knepley }
1821c5ce4427SMatthew G. Knepley 
1822c5ce4427SMatthew G. Knepley /*@
1823c5ce4427SMatthew G. Knepley   SNESGetFunctionNorm - Gets the last computed norm of the residual
1824c5ce4427SMatthew G. Knepley 
1825c5ce4427SMatthew G. Knepley   Not Collective
1826c5ce4427SMatthew G. Knepley 
1827c5ce4427SMatthew G. Knepley   Input Parameter:
1828c5ce4427SMatthew G. Knepley . snes - the SNES context
1829c5ce4427SMatthew G. Knepley 
1830c5ce4427SMatthew G. Knepley   Output Parameter:
1831c5ce4427SMatthew G. Knepley . norm - the last computed residual norm
1832c5ce4427SMatthew G. Knepley 
1833c5ce4427SMatthew G. Knepley   Level: developer
1834c5ce4427SMatthew G. Knepley 
1835c5ce4427SMatthew G. Knepley .keywords: SNES, nonlinear, set, function, norm, type
1836c5ce4427SMatthew G. Knepley .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
1837c5ce4427SMatthew G. Knepley @*/
1838c5ce4427SMatthew G. Knepley PetscErrorCode SNESGetFunctionNorm(SNES snes, PetscReal *norm)
1839c5ce4427SMatthew G. Knepley {
1840c5ce4427SMatthew G. Knepley   PetscFunctionBegin;
1841c5ce4427SMatthew G. Knepley   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1842c5ce4427SMatthew G. Knepley   PetscValidPointer(norm, 2);
1843c5ce4427SMatthew G. Knepley   *norm = snes->norm;
1844c5ce4427SMatthew G. Knepley   PetscFunctionReturn(0);
1845c5ce4427SMatthew G. Knepley }
1846c5ce4427SMatthew G. Knepley 
184747073ea2SPeter Brune /*@C
184847073ea2SPeter Brune    SNESSetFunctionType - Sets the SNESNormSchedule used in covergence and monitoring
184947073ea2SPeter Brune    of the SNES method.
185047073ea2SPeter Brune 
185147073ea2SPeter Brune    Logically Collective on SNES
185247073ea2SPeter Brune 
185347073ea2SPeter Brune    Input Parameters:
185447073ea2SPeter Brune +  snes - the SNES context
185547073ea2SPeter Brune -  normschedule - the frequency of norm computation
185647073ea2SPeter Brune 
185747073ea2SPeter Brune    Notes:
185847073ea2SPeter Brune    Only certain SNES methods support certain SNESNormSchedules.  Most require evaluation
185947073ea2SPeter Brune    of the nonlinear function and the taking of its norm at every iteration to
186047073ea2SPeter Brune    even ensure convergence at all.  However, methods such as custom Gauss-Seidel methods
1861be95d8f1SBarry Smith    (SNESNGS) and the like do not require the norm of the function to be computed, and therfore
186247073ea2SPeter Brune    may either be monitored for convergence or not.  As these are often used as nonlinear
186347073ea2SPeter Brune    preconditioners, monitoring the norm of their error is not a useful enterprise within
186447073ea2SPeter Brune    their solution.
186547073ea2SPeter Brune 
186647073ea2SPeter Brune    Level: developer
186747073ea2SPeter Brune 
186847073ea2SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type
186947073ea2SPeter Brune 
187047073ea2SPeter Brune .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
187147073ea2SPeter Brune @*/
187247073ea2SPeter Brune PetscErrorCode  SNESSetFunctionType(SNES snes, SNESFunctionType type)
187347073ea2SPeter Brune {
187447073ea2SPeter Brune   PetscFunctionBegin;
187547073ea2SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
187647073ea2SPeter Brune   snes->functype = type;
187747073ea2SPeter Brune   PetscFunctionReturn(0);
187847073ea2SPeter Brune }
187947073ea2SPeter Brune 
188047073ea2SPeter Brune 
188147073ea2SPeter Brune /*@C
188247073ea2SPeter Brune    SNESGetFunctionType - Gets the SNESNormSchedule used in covergence and monitoring
188347073ea2SPeter Brune    of the SNES method.
188447073ea2SPeter Brune 
188547073ea2SPeter Brune    Logically Collective on SNES
188647073ea2SPeter Brune 
188747073ea2SPeter Brune    Input Parameters:
188847073ea2SPeter Brune +  snes - the SNES context
188947073ea2SPeter Brune -  normschedule - the type of the norm used
189047073ea2SPeter Brune 
189147073ea2SPeter Brune    Level: advanced
189247073ea2SPeter Brune 
189347073ea2SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type
189447073ea2SPeter Brune 
189547073ea2SPeter Brune .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
189647073ea2SPeter Brune @*/
189747073ea2SPeter Brune PetscErrorCode  SNESGetFunctionType(SNES snes, SNESFunctionType *type)
189847073ea2SPeter Brune {
189947073ea2SPeter Brune   PetscFunctionBegin;
190047073ea2SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
190147073ea2SPeter Brune   *type = snes->functype;
1902534ebe21SPeter Brune   PetscFunctionReturn(0);
1903534ebe21SPeter Brune }
1904534ebe21SPeter Brune 
1905bf388a1fSBarry Smith /*MC
1906be95d8f1SBarry Smith     SNESNGSFunction - function used to convey a Gauss-Seidel sweep on the nonlinear function
1907bf388a1fSBarry Smith 
1908bf388a1fSBarry Smith      Synopsis:
1909aaa7dc30SBarry Smith      #include <petscsnes.h>
1910be95d8f1SBarry Smith $    SNESNGSFunction(SNES snes,Vec x,Vec b,void *ctx);
1911bf388a1fSBarry Smith 
1912bf388a1fSBarry Smith +  X   - solution vector
1913bf388a1fSBarry Smith .  B   - RHS vector
1914bf388a1fSBarry Smith -  ctx - optional user-defined Gauss-Seidel context
1915bf388a1fSBarry Smith 
1916878cb397SSatish Balay    Level: intermediate
1917878cb397SSatish Balay 
1918be95d8f1SBarry Smith .seealso:   SNESSetNGS(), SNESGetNGS()
1919bf388a1fSBarry Smith M*/
1920bf388a1fSBarry Smith 
1921c79ef259SPeter Brune /*@C
1922be95d8f1SBarry Smith    SNESSetNGS - Sets the user nonlinear Gauss-Seidel routine for
1923c79ef259SPeter Brune    use with composed nonlinear solvers.
1924c79ef259SPeter Brune 
1925c79ef259SPeter Brune    Input Parameters:
1926c79ef259SPeter Brune +  snes   - the SNES context
1927be95d8f1SBarry Smith .  f - function evaluation routine to apply Gauss-Seidel see SNESNGSFunction
1928c79ef259SPeter Brune -  ctx    - [optional] user-defined context for private data for the
19290298fd71SBarry Smith             smoother evaluation routine (may be NULL)
1930c79ef259SPeter Brune 
1931c79ef259SPeter Brune    Notes:
1932be95d8f1SBarry Smith    The NGS routines are used by the composed nonlinear solver to generate
1933c79ef259SPeter Brune     a problem appropriate update to the solution, particularly FAS.
1934c79ef259SPeter Brune 
1935d28543b3SPeter Brune    Level: intermediate
1936c79ef259SPeter Brune 
1937d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel
1938c79ef259SPeter Brune 
1939be95d8f1SBarry Smith .seealso: SNESGetFunction(), SNESComputeNGS()
1940c79ef259SPeter Brune @*/
1941be95d8f1SBarry Smith PetscErrorCode SNESSetNGS(SNES snes,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx)
19426cab3a1bSJed Brown {
19436cab3a1bSJed Brown   PetscErrorCode ierr;
19446cab3a1bSJed Brown   DM             dm;
19456cab3a1bSJed Brown 
1946646217ecSPeter Brune   PetscFunctionBegin;
19476cab3a1bSJed Brown   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
19486cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
1949be95d8f1SBarry Smith   ierr = DMSNESSetNGS(dm,f,ctx);CHKERRQ(ierr);
1950646217ecSPeter Brune   PetscFunctionReturn(0);
1951646217ecSPeter Brune }
1952646217ecSPeter Brune 
195382b59a81SJed Brown PETSC_EXTERN PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx)
19548b0a5094SBarry Smith {
19558b0a5094SBarry Smith   PetscErrorCode ierr;
1956e03ab78fSPeter Brune   DM             dm;
1957942e3340SBarry Smith   DMSNES         sdm;
19586cab3a1bSJed Brown 
19598b0a5094SBarry Smith   PetscFunctionBegin;
1960e03ab78fSPeter Brune   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
1961942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
19628b0a5094SBarry Smith   /*  A(x)*x - b(x) */
196322c6f798SBarry Smith   if (sdm->ops->computepfunction) {
196422c6f798SBarry Smith     ierr = (*sdm->ops->computepfunction)(snes,x,f,sdm->pctx);CHKERRQ(ierr);
196522c6f798SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard function.");
1966e03ab78fSPeter Brune 
196722c6f798SBarry Smith   if (sdm->ops->computepjacobian) {
1968d1e9a80fSBarry Smith     ierr = (*sdm->ops->computepjacobian)(snes,x,snes->jacobian,snes->jacobian_pre,sdm->pctx);CHKERRQ(ierr);
196974e1e8c1SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard matrix.");
19708b0a5094SBarry Smith   ierr = VecScale(f,-1.0);CHKERRQ(ierr);
197195eabcedSBarry Smith   ierr = MatMultAdd(snes->jacobian,x,f,f);CHKERRQ(ierr);
19728b0a5094SBarry Smith   PetscFunctionReturn(0);
19738b0a5094SBarry Smith }
19748b0a5094SBarry Smith 
1975d1e9a80fSBarry Smith PETSC_EXTERN PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat J,Mat B,void *ctx)
19768b0a5094SBarry Smith {
19778b0a5094SBarry Smith   PetscFunctionBegin;
1978e03ab78fSPeter Brune   /* the jacobian matrix should be pre-filled in SNESPicardComputeFunction */
19798b0a5094SBarry Smith   PetscFunctionReturn(0);
19808b0a5094SBarry Smith }
19818b0a5094SBarry Smith 
19828b0a5094SBarry Smith /*@C
19830d04baf8SBarry Smith    SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization)
19848b0a5094SBarry Smith 
19858b0a5094SBarry Smith    Logically Collective on SNES
19868b0a5094SBarry Smith 
19878b0a5094SBarry Smith    Input Parameters:
19888b0a5094SBarry Smith +  snes - the SNES context
19898b0a5094SBarry Smith .  r - vector to store function value
1990f8b49ee9SBarry Smith .  b - function evaluation routine
1991e5d3d808SBarry Smith .  Amat - matrix with which A(x) x - b(x) is to be computed
1992e5d3d808SBarry Smith .  Pmat - matrix from which preconditioner is computed (usually the same as Amat)
1993411c0326SBarry Smith .  J  - function to compute matrix value, see SNESJacobianFunction for details on its calling sequence
19948b0a5094SBarry Smith -  ctx - [optional] user-defined context for private data for the
19950298fd71SBarry Smith          function evaluation routine (may be NULL)
19968b0a5094SBarry Smith 
19978b0a5094SBarry Smith    Notes:
1998f450aa47SBarry 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
1999f450aa47SBarry 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.
2000f450aa47SBarry Smith 
20018b0a5094SBarry Smith     One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both
20028b0a5094SBarry Smith 
20038b0a5094SBarry 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}
20048b0a5094SBarry 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.
20058b0a5094SBarry Smith 
20068b0a5094SBarry Smith      Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner.
20078b0a5094SBarry Smith 
20080d04baf8SBarry Smith    We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then
20090d04baf8SBarry Smith    the direct Picard iteration A(x^n) x^{n+1} = b(x^n)
20108b0a5094SBarry Smith 
20118b0a5094SBarry 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
20128b0a5094SBarry 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
20138b0a5094SBarry Smith    different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-).
20148b0a5094SBarry Smith 
2015f450aa47SBarry Smith    Level: intermediate
20168b0a5094SBarry Smith 
20178b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function
20188b0a5094SBarry Smith 
2019411c0326SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard(), SNESJacobianFunction
20208b0a5094SBarry Smith @*/
2021d1e9a80fSBarry 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)
20228b0a5094SBarry Smith {
20238b0a5094SBarry Smith   PetscErrorCode ierr;
2024e03ab78fSPeter Brune   DM             dm;
2025e03ab78fSPeter Brune 
20268b0a5094SBarry Smith   PetscFunctionBegin;
20278b0a5094SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2028e03ab78fSPeter Brune   ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr);
2029f8b49ee9SBarry Smith   ierr = DMSNESSetPicard(dm,b,J,ctx);CHKERRQ(ierr);
20308b0a5094SBarry Smith   ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr);
2031e5d3d808SBarry Smith   ierr = SNESSetJacobian(snes,Amat,Pmat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr);
20328b0a5094SBarry Smith   PetscFunctionReturn(0);
20338b0a5094SBarry Smith }
20348b0a5094SBarry Smith 
20357971a8bfSPeter Brune /*@C
20367971a8bfSPeter Brune    SNESGetPicard - Returns the context for the Picard iteration
20377971a8bfSPeter Brune 
20387971a8bfSPeter Brune    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
20397971a8bfSPeter Brune 
20407971a8bfSPeter Brune    Input Parameter:
20417971a8bfSPeter Brune .  snes - the SNES context
20427971a8bfSPeter Brune 
20437971a8bfSPeter Brune    Output Parameter:
20440298fd71SBarry Smith +  r - the function (or NULL)
2045f8b49ee9SBarry Smith .  f - the function (or NULL); see SNESFunction for calling sequence details
2046e4357dc4SBarry Smith .  Amat - the matrix used to defined the operation A(x) x - b(x) (or NULL)
2047e4357dc4SBarry Smith .  Pmat  - the matrix from which the preconditioner will be constructed (or NULL)
2048f8b49ee9SBarry Smith .  J - the function for matrix evaluation (or NULL); see SNESJacobianFunction for calling sequence details
20490298fd71SBarry Smith -  ctx - the function context (or NULL)
20507971a8bfSPeter Brune 
20517971a8bfSPeter Brune    Level: advanced
20527971a8bfSPeter Brune 
20537971a8bfSPeter Brune .keywords: SNES, nonlinear, get, function
20547971a8bfSPeter Brune 
2055e4357dc4SBarry Smith .seealso: SNESSetPicard(), SNESGetFunction(), SNESGetJacobian(), SNESGetDM(), SNESFunction, SNESJacobianFunction
20567971a8bfSPeter Brune @*/
2057d1e9a80fSBarry 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)
20587971a8bfSPeter Brune {
20597971a8bfSPeter Brune   PetscErrorCode ierr;
20607971a8bfSPeter Brune   DM             dm;
20617971a8bfSPeter Brune 
20627971a8bfSPeter Brune   PetscFunctionBegin;
20637971a8bfSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
20640298fd71SBarry Smith   ierr = SNESGetFunction(snes,r,NULL,NULL);CHKERRQ(ierr);
2065e4357dc4SBarry Smith   ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr);
20667971a8bfSPeter Brune   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2067f8b49ee9SBarry Smith   ierr = DMSNESGetPicard(dm,f,J,ctx);CHKERRQ(ierr);
20687971a8bfSPeter Brune   PetscFunctionReturn(0);
20697971a8bfSPeter Brune }
20707971a8bfSPeter Brune 
2071d25893d9SBarry Smith /*@C
2072d25893d9SBarry Smith    SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem
2073d25893d9SBarry Smith 
2074d25893d9SBarry Smith    Logically Collective on SNES
2075d25893d9SBarry Smith 
2076d25893d9SBarry Smith    Input Parameters:
2077d25893d9SBarry Smith +  snes - the SNES context
2078d25893d9SBarry Smith .  func - function evaluation routine
2079d25893d9SBarry Smith -  ctx - [optional] user-defined context for private data for the
20800298fd71SBarry Smith          function evaluation routine (may be NULL)
2081d25893d9SBarry Smith 
2082d25893d9SBarry Smith    Calling sequence of func:
2083d25893d9SBarry Smith $    func (SNES snes,Vec x,void *ctx);
2084d25893d9SBarry Smith 
2085d25893d9SBarry Smith .  f - function vector
2086d25893d9SBarry Smith -  ctx - optional user-defined function context
2087d25893d9SBarry Smith 
2088d25893d9SBarry Smith    Level: intermediate
2089d25893d9SBarry Smith 
2090d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function
2091d25893d9SBarry Smith 
2092d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
2093d25893d9SBarry Smith @*/
2094d25893d9SBarry Smith PetscErrorCode  SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx)
2095d25893d9SBarry Smith {
2096d25893d9SBarry Smith   PetscFunctionBegin;
2097d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2098d25893d9SBarry Smith   if (func) snes->ops->computeinitialguess = func;
2099d25893d9SBarry Smith   if (ctx)  snes->initialguessP            = ctx;
2100d25893d9SBarry Smith   PetscFunctionReturn(0);
2101d25893d9SBarry Smith }
2102d25893d9SBarry Smith 
21033ab0aad5SBarry Smith /* --------------------------------------------------------------- */
21041096aae1SMatthew Knepley /*@C
21051096aae1SMatthew Knepley    SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
21061096aae1SMatthew Knepley    it assumes a zero right hand side.
21071096aae1SMatthew Knepley 
21083f9fe445SBarry Smith    Logically Collective on SNES
21091096aae1SMatthew Knepley 
21101096aae1SMatthew Knepley    Input Parameter:
21111096aae1SMatthew Knepley .  snes - the SNES context
21121096aae1SMatthew Knepley 
21131096aae1SMatthew Knepley    Output Parameter:
21140298fd71SBarry Smith .  rhs - the right hand side vector or NULL if the right hand side vector is null
21151096aae1SMatthew Knepley 
21161096aae1SMatthew Knepley    Level: intermediate
21171096aae1SMatthew Knepley 
21181096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side
21191096aae1SMatthew Knepley 
212085385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
21211096aae1SMatthew Knepley @*/
21227087cfbeSBarry Smith PetscErrorCode  SNESGetRhs(SNES snes,Vec *rhs)
21231096aae1SMatthew Knepley {
21241096aae1SMatthew Knepley   PetscFunctionBegin;
21250700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
21261096aae1SMatthew Knepley   PetscValidPointer(rhs,2);
212785385478SLisandro Dalcin   *rhs = snes->vec_rhs;
21281096aae1SMatthew Knepley   PetscFunctionReturn(0);
21291096aae1SMatthew Knepley }
21301096aae1SMatthew Knepley 
21319b94acceSBarry Smith /*@
2132bf388a1fSBarry Smith    SNESComputeFunction - Calls the function that has been set with SNESSetFunction().
21339b94acceSBarry Smith 
2134c7afd0dbSLois Curfman McInnes    Collective on SNES
2135c7afd0dbSLois Curfman McInnes 
21369b94acceSBarry Smith    Input Parameters:
2137c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2138c7afd0dbSLois Curfman McInnes -  x - input vector
21399b94acceSBarry Smith 
21409b94acceSBarry Smith    Output Parameter:
21413638b69dSLois Curfman McInnes .  y - function vector, as set by SNESSetFunction()
21429b94acceSBarry Smith 
21431bffabb2SLois Curfman McInnes    Notes:
214436851e7fSLois Curfman McInnes    SNESComputeFunction() is typically used within nonlinear solvers
214536851e7fSLois Curfman McInnes    implementations, so most users would not generally call this routine
214636851e7fSLois Curfman McInnes    themselves.
214736851e7fSLois Curfman McInnes 
214836851e7fSLois Curfman McInnes    Level: developer
214936851e7fSLois Curfman McInnes 
21509b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function
21519b94acceSBarry Smith 
2152a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction()
21539b94acceSBarry Smith @*/
21547087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction(SNES snes,Vec x,Vec y)
21559b94acceSBarry Smith {
2156dfbe8321SBarry Smith   PetscErrorCode ierr;
21576cab3a1bSJed Brown   DM             dm;
2158942e3340SBarry Smith   DMSNES         sdm;
21599b94acceSBarry Smith 
21603a40ed3dSBarry Smith   PetscFunctionBegin;
21610700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
21620700a824SBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
21630700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2164c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,x,2);
2165c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,3);
216662796dfbSBarry Smith   ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);
2167184914b5SBarry Smith 
21686cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2169942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
217032f3f7c2SPeter Brune   if (sdm->ops->computefunction) {
217194db00ebSBarry Smith     if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) {
2172ccf3c845SPeter Brune       ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
217394db00ebSBarry Smith     }
21745edff71fSBarry Smith     ierr = VecLockPush(x);CHKERRQ(ierr);
2175d64ed03dSBarry Smith     PetscStackPush("SNES user function");
217622c6f798SBarry Smith     ierr = (*sdm->ops->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr);
2177d64ed03dSBarry Smith     PetscStackPop;
21785edff71fSBarry Smith     ierr = VecLockPop(x);CHKERRQ(ierr);
217994db00ebSBarry Smith     if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) {
2180ccf3c845SPeter Brune       ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
218194db00ebSBarry Smith     }
2182c90fad12SPeter Brune   } else if (snes->vec_rhs) {
2183c90fad12SPeter Brune     ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr);
2184644e2e5bSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve().");
218585385478SLisandro Dalcin   if (snes->vec_rhs) {
218685385478SLisandro Dalcin     ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr);
21873ab0aad5SBarry Smith   }
2188ae3c334cSLois Curfman McInnes   snes->nfuncs++;
2189422a814eSBarry Smith   /*
2190422a814eSBarry Smith      domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will
2191422a814eSBarry Smith      propagate the value to all processes
2192422a814eSBarry Smith   */
2193422a814eSBarry Smith   if (snes->domainerror) {
2194422a814eSBarry Smith     ierr = VecSetInf(y);CHKERRQ(ierr);
2195422a814eSBarry Smith   }
21963a40ed3dSBarry Smith   PetscFunctionReturn(0);
21979b94acceSBarry Smith }
21989b94acceSBarry Smith 
2199c79ef259SPeter Brune /*@
2200be95d8f1SBarry Smith    SNESComputeNGS - Calls the Gauss-Seidel function that has been set with  SNESSetNGS().
2201c79ef259SPeter Brune 
2202c79ef259SPeter Brune    Collective on SNES
2203c79ef259SPeter Brune 
2204c79ef259SPeter Brune    Input Parameters:
2205c79ef259SPeter Brune +  snes - the SNES context
2206c79ef259SPeter Brune .  x - input vector
2207c79ef259SPeter Brune -  b - rhs vector
2208c79ef259SPeter Brune 
2209c79ef259SPeter Brune    Output Parameter:
2210c79ef259SPeter Brune .  x - new solution vector
2211c79ef259SPeter Brune 
2212c79ef259SPeter Brune    Notes:
2213be95d8f1SBarry Smith    SNESComputeNGS() is typically used within composed nonlinear solver
2214c79ef259SPeter Brune    implementations, so most users would not generally call this routine
2215c79ef259SPeter Brune    themselves.
2216c79ef259SPeter Brune 
2217c79ef259SPeter Brune    Level: developer
2218c79ef259SPeter Brune 
2219c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function
2220c79ef259SPeter Brune 
2221be95d8f1SBarry Smith .seealso: SNESSetNGS(), SNESComputeFunction()
2222c79ef259SPeter Brune @*/
2223be95d8f1SBarry Smith PetscErrorCode  SNESComputeNGS(SNES snes,Vec b,Vec x)
2224646217ecSPeter Brune {
2225646217ecSPeter Brune   PetscErrorCode ierr;
22266cab3a1bSJed Brown   DM             dm;
2227942e3340SBarry Smith   DMSNES         sdm;
2228646217ecSPeter Brune 
2229646217ecSPeter Brune   PetscFunctionBegin;
2230646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2231646217ecSPeter Brune   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2232646217ecSPeter Brune   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3);
2233646217ecSPeter Brune   PetscCheckSameComm(snes,1,x,2);
2234646217ecSPeter Brune   if (b) PetscCheckSameComm(snes,1,b,3);
223562796dfbSBarry Smith   if (b) {ierr = VecValidValues(b,2,PETSC_TRUE);CHKERRQ(ierr);}
2236be95d8f1SBarry Smith   ierr = PetscLogEventBegin(SNES_NGSEval,snes,x,b,0);CHKERRQ(ierr);
22376cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2238942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
223922c6f798SBarry Smith   if (sdm->ops->computegs) {
22405edff71fSBarry Smith     if (b) {ierr = VecLockPush(b);CHKERRQ(ierr);}
2241be95d8f1SBarry Smith     PetscStackPush("SNES user NGS");
224222c6f798SBarry Smith     ierr = (*sdm->ops->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr);
2243646217ecSPeter Brune     PetscStackPop;
22445edff71fSBarry Smith     if (b) {ierr = VecLockPop(b);CHKERRQ(ierr);}
2245be95d8f1SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetNGS() before SNESComputeNGS(), likely called from SNESSolve().");
2246be95d8f1SBarry Smith   ierr = PetscLogEventEnd(SNES_NGSEval,snes,x,b,0);CHKERRQ(ierr);
2247646217ecSPeter Brune   PetscFunctionReturn(0);
2248646217ecSPeter Brune }
2249646217ecSPeter Brune 
225062fef451SLois Curfman McInnes /*@
2251bf388a1fSBarry Smith    SNESComputeJacobian - Computes the Jacobian matrix that has been set with SNESSetJacobian().
225262fef451SLois Curfman McInnes 
2253c7afd0dbSLois Curfman McInnes    Collective on SNES and Mat
2254c7afd0dbSLois Curfman McInnes 
225562fef451SLois Curfman McInnes    Input Parameters:
2256c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2257c7afd0dbSLois Curfman McInnes -  x - input vector
225862fef451SLois Curfman McInnes 
225962fef451SLois Curfman McInnes    Output Parameters:
2260c7afd0dbSLois Curfman McInnes +  A - Jacobian matrix
2261d1e9a80fSBarry Smith -  B - optional preconditioning matrix
2262fee21e36SBarry Smith 
2263e35cf81dSBarry Smith   Options Database Keys:
2264e35cf81dSBarry Smith +    -snes_lag_preconditioner <lag>
2265693365a8SJed Brown .    -snes_lag_jacobian <lag>
2266693365a8SJed Brown .    -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences
2267693365a8SJed Brown .    -snes_compare_explicit_draw  - Compare the computed Jacobian to the finite difference Jacobian and draw the result
2268693365a8SJed Brown .    -snes_compare_explicit_contour  - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result
22694c30e9fbSJed Brown .    -snes_compare_operator  - Make the comparison options above use the operator instead of the preconditioning matrix
227094d6a431SBarry Smith .    -snes_compare_coloring - Compute the finite difference Jacobian using coloring and display norms of difference
2271c01495d3SJed Brown .    -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences
2272c01495d3SJed Brown .    -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold
2273c01495d3SJed Brown .    -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
2274c01495d3SJed Brown .    -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
22754c30e9fbSJed Brown .    -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences
2276c01495d3SJed Brown -    -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences
2277c01495d3SJed Brown 
2278e35cf81dSBarry Smith 
227962fef451SLois Curfman McInnes    Notes:
228062fef451SLois Curfman McInnes    Most users should not need to explicitly call this routine, as it
228162fef451SLois Curfman McInnes    is used internally within the nonlinear solvers.
228262fef451SLois Curfman McInnes 
228336851e7fSLois Curfman McInnes    Level: developer
228436851e7fSLois Curfman McInnes 
228562fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix
228662fef451SLois Curfman McInnes 
2287e35cf81dSBarry Smith .seealso:  SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian()
228862fef451SLois Curfman McInnes @*/
2289d1e9a80fSBarry Smith PetscErrorCode  SNESComputeJacobian(SNES snes,Vec X,Mat A,Mat B)
22909b94acceSBarry Smith {
2291dfbe8321SBarry Smith   PetscErrorCode ierr;
2292ace3abfcSBarry Smith   PetscBool      flag;
22936cab3a1bSJed Brown   DM             dm;
2294942e3340SBarry Smith   DMSNES         sdm;
2295e0e3a89bSBarry Smith   KSP            ksp;
22963a40ed3dSBarry Smith 
22973a40ed3dSBarry Smith   PetscFunctionBegin;
22980700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
22990700a824SBarry Smith   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
2300c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,X,2);
230162796dfbSBarry Smith   ierr = VecValidValues(X,2,PETSC_TRUE);CHKERRQ(ierr);
23026cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2303942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
23043232da50SPeter Brune 
2305ce94432eSBarry Smith   if (!sdm->ops->computejacobian) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc");
2306ebd3b9afSBarry Smith 
2307ebd3b9afSBarry Smith   /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */
2308ebd3b9afSBarry Smith 
2309fe3ffe1eSBarry Smith   if (snes->lagjacobian == -2) {
2310fe3ffe1eSBarry Smith     snes->lagjacobian = -1;
2311f5af7f23SKarl Rupp 
2312fe3ffe1eSBarry Smith     ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr);
2313fe3ffe1eSBarry Smith   } else if (snes->lagjacobian == -1) {
2314e35cf81dSBarry Smith     ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr);
231594ab13aaSBarry Smith     ierr = PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag);CHKERRQ(ierr);
2316ebd3b9afSBarry Smith     if (flag) {
231794ab13aaSBarry Smith       ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
231894ab13aaSBarry Smith       ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2319ebd3b9afSBarry Smith     }
2320e35cf81dSBarry Smith     PetscFunctionReturn(0);
232137ec4e1aSPeter Brune   } else if (snes->lagjacobian > 1 && (snes->iter + snes->jac_iter) % snes->lagjacobian) {
2322e35cf81dSBarry Smith     ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr);
232394ab13aaSBarry Smith     ierr = PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag);CHKERRQ(ierr);
2324ebd3b9afSBarry Smith     if (flag) {
232594ab13aaSBarry Smith       ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
232694ab13aaSBarry Smith       ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2327ebd3b9afSBarry Smith     }
2328e35cf81dSBarry Smith     PetscFunctionReturn(0);
2329e35cf81dSBarry Smith   }
2330d728fb7dSPeter Brune   if (snes->pc && snes->pcside == PC_LEFT) {
233194ab13aaSBarry Smith       ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
233294ab13aaSBarry Smith       ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2333d728fb7dSPeter Brune       PetscFunctionReturn(0);
2334d728fb7dSPeter Brune   }
2335e35cf81dSBarry Smith 
233694ab13aaSBarry Smith   ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,A,B);CHKERRQ(ierr);
23375edff71fSBarry Smith   ierr = VecLockPush(X);CHKERRQ(ierr);
2338d64ed03dSBarry Smith   PetscStackPush("SNES user Jacobian function");
2339d1e9a80fSBarry Smith   ierr = (*sdm->ops->computejacobian)(snes,X,A,B,sdm->jacobianctx);CHKERRQ(ierr);
2340d64ed03dSBarry Smith   PetscStackPop;
23415edff71fSBarry Smith   ierr = VecLockPop(X);CHKERRQ(ierr);
234294ab13aaSBarry Smith   ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,A,B);CHKERRQ(ierr);
2343a8054027SBarry Smith 
2344e0e3a89bSBarry Smith   /* the next line ensures that snes->ksp exists */
2345e0e3a89bSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
23463b4f5425SBarry Smith   if (snes->lagpreconditioner == -2) {
23473b4f5425SBarry Smith     ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr);
2348d1e9a80fSBarry Smith     ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE);CHKERRQ(ierr);
23493b4f5425SBarry Smith     snes->lagpreconditioner = -1;
23503b4f5425SBarry Smith   } else if (snes->lagpreconditioner == -1) {
2351a8054027SBarry Smith     ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr);
2352d1e9a80fSBarry Smith     ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE);CHKERRQ(ierr);
235337ec4e1aSPeter Brune   } else if (snes->lagpreconditioner > 1 && (snes->iter + snes->pre_iter) % snes->lagpreconditioner) {
2354a8054027SBarry Smith     ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr);
2355d1e9a80fSBarry Smith     ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE);CHKERRQ(ierr);
2356d1e9a80fSBarry Smith   } else {
2357d1e9a80fSBarry Smith     ierr = PetscInfo(snes,"Rebuilding preconditioner\n");CHKERRQ(ierr);
2358d1e9a80fSBarry Smith     ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE);CHKERRQ(ierr);
2359a8054027SBarry Smith   }
2360a8054027SBarry Smith 
23616d84be18SBarry Smith   /* make sure user returned a correct Jacobian and preconditioner */
236294ab13aaSBarry Smith   /* PetscValidHeaderSpecific(A,MAT_CLASSID,3);
236394ab13aaSBarry Smith     PetscValidHeaderSpecific(B,MAT_CLASSID,4);   */
2364693365a8SJed Brown   {
2365693365a8SJed Brown     PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE;
236627b0f280SBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_explicit",NULL,NULL,&flag);CHKERRQ(ierr);
236727b0f280SBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",NULL,NULL,&flag_draw);CHKERRQ(ierr);
236827b0f280SBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",NULL,NULL,&flag_contour);CHKERRQ(ierr);
236927b0f280SBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_operator",NULL,NULL,&flag_operator);CHKERRQ(ierr);
2370693365a8SJed Brown     if (flag || flag_draw || flag_contour) {
23710298fd71SBarry Smith       Mat          Bexp_mine = NULL,Bexp,FDexp;
2372693365a8SJed Brown       PetscViewer  vdraw,vstdout;
23736b3a5b13SJed Brown       PetscBool    flg;
2374693365a8SJed Brown       if (flag_operator) {
237594ab13aaSBarry Smith         ierr = MatComputeExplicitOperator(A,&Bexp_mine);CHKERRQ(ierr);
2376693365a8SJed Brown         Bexp = Bexp_mine;
2377693365a8SJed Brown       } else {
2378693365a8SJed Brown         /* See if the preconditioning matrix can be viewed and added directly */
237994ab13aaSBarry Smith         ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr);
238094ab13aaSBarry Smith         if (flg) Bexp = B;
2381693365a8SJed Brown         else {
2382693365a8SJed Brown           /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */
238394ab13aaSBarry Smith           ierr = MatComputeExplicitOperator(B,&Bexp_mine);CHKERRQ(ierr);
2384693365a8SJed Brown           Bexp = Bexp_mine;
2385693365a8SJed Brown         }
2386693365a8SJed Brown       }
2387693365a8SJed Brown       ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr);
2388d1e9a80fSBarry Smith       ierr = SNESComputeJacobianDefault(snes,X,FDexp,FDexp,NULL);CHKERRQ(ierr);
2389ce94432eSBarry Smith       ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout);CHKERRQ(ierr);
2390693365a8SJed Brown       if (flag_draw || flag_contour) {
2391ce94432eSBarry Smith         ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
2392693365a8SJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
23930298fd71SBarry Smith       } else vdraw = NULL;
2394693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator ? "Jacobian" : "preconditioning Jacobian");CHKERRQ(ierr);
2395693365a8SJed Brown       if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);}
2396693365a8SJed Brown       if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);}
2397693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr);
2398693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
2399693365a8SJed Brown       if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);}
2400693365a8SJed Brown       ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2401693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr);
2402693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
2403693365a8SJed Brown       if (vdraw) {              /* Always use contour for the difference */
2404693365a8SJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
2405693365a8SJed Brown         ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);
2406693365a8SJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
2407693365a8SJed Brown       }
2408693365a8SJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
2409693365a8SJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
2410693365a8SJed Brown       ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr);
2411693365a8SJed Brown       ierr = MatDestroy(&FDexp);CHKERRQ(ierr);
2412693365a8SJed Brown     }
2413693365a8SJed Brown   }
24144c30e9fbSJed Brown   {
24156719d8e4SJed Brown     PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE;
24166719d8e4SJed Brown     PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON;
241727b0f280SBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring",NULL,NULL,&flag);CHKERRQ(ierr);
241827b0f280SBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring_display",NULL,NULL,&flag_display);CHKERRQ(ierr);
241927b0f280SBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",NULL,NULL,&flag_draw);CHKERRQ(ierr);
242027b0f280SBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",NULL,NULL,&flag_contour);CHKERRQ(ierr);
242127b0f280SBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",NULL,NULL,&flag_threshold);CHKERRQ(ierr);
242227b0f280SBarry Smith     if (flag_threshold) {
2423c5929fdfSBarry Smith       ierr = PetscOptionsGetReal(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,NULL);CHKERRQ(ierr);
2424c5929fdfSBarry Smith       ierr = PetscOptionsGetReal(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,NULL);CHKERRQ(ierr);
242527b0f280SBarry Smith     }
24266719d8e4SJed Brown     if (flag || flag_display || flag_draw || flag_contour || flag_threshold) {
24274c30e9fbSJed Brown       Mat            Bfd;
24284c30e9fbSJed Brown       PetscViewer    vdraw,vstdout;
2429335efc43SPeter Brune       MatColoring    coloring;
24304c30e9fbSJed Brown       ISColoring     iscoloring;
24314c30e9fbSJed Brown       MatFDColoring  matfdcoloring;
24324c30e9fbSJed Brown       PetscErrorCode (*func)(SNES,Vec,Vec,void*);
24334c30e9fbSJed Brown       void           *funcctx;
24346719d8e4SJed Brown       PetscReal      norm1,norm2,normmax;
24354c30e9fbSJed Brown 
243694ab13aaSBarry Smith       ierr = MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr);
2437335efc43SPeter Brune       ierr = MatColoringCreate(Bfd,&coloring);CHKERRQ(ierr);
2438335efc43SPeter Brune       ierr = MatColoringSetType(coloring,MATCOLORINGSL);CHKERRQ(ierr);
2439335efc43SPeter Brune       ierr = MatColoringSetFromOptions(coloring);CHKERRQ(ierr);
2440335efc43SPeter Brune       ierr = MatColoringApply(coloring,&iscoloring);CHKERRQ(ierr);
2441335efc43SPeter Brune       ierr = MatColoringDestroy(&coloring);CHKERRQ(ierr);
24424c30e9fbSJed Brown       ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr);
2443f86b9fbaSHong Zhang       ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr);
2444f86b9fbaSHong Zhang       ierr = MatFDColoringSetUp(Bfd,iscoloring,matfdcoloring);CHKERRQ(ierr);
24454c30e9fbSJed Brown       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
24464c30e9fbSJed Brown 
24474c30e9fbSJed Brown       /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */
24480298fd71SBarry Smith       ierr = SNESGetFunction(snes,NULL,&func,&funcctx);CHKERRQ(ierr);
24494c30e9fbSJed Brown       ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode (*)(void))func,funcctx);CHKERRQ(ierr);
24504c30e9fbSJed Brown       ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr);
24514c30e9fbSJed Brown       ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr);
24524c30e9fbSJed Brown       ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr);
2453d1e9a80fSBarry Smith       ierr = MatFDColoringApply(Bfd,matfdcoloring,X,snes);CHKERRQ(ierr);
24544c30e9fbSJed Brown       ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr);
24554c30e9fbSJed Brown 
2456ce94432eSBarry Smith       ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout);CHKERRQ(ierr);
24574c30e9fbSJed Brown       if (flag_draw || flag_contour) {
2458ce94432eSBarry Smith         ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
24594c30e9fbSJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
24600298fd71SBarry Smith       } else vdraw = NULL;
24614c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr);
246294ab13aaSBarry Smith       if (flag_display) {ierr = MatView(B,vstdout);CHKERRQ(ierr);}
246394ab13aaSBarry Smith       if (vdraw) {ierr = MatView(B,vdraw);CHKERRQ(ierr);}
24644c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr);
24656719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
24664c30e9fbSJed Brown       if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);}
246794ab13aaSBarry Smith       ierr = MatAYPX(Bfd,-1.0,B,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
24684c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr);
24696719d8e4SJed Brown       ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr);
24704c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr);
247157622a8eSBarry 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);
24726719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
24734c30e9fbSJed Brown       if (vdraw) {              /* Always use contour for the difference */
24744c30e9fbSJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
24754c30e9fbSJed Brown         ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);
24764c30e9fbSJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
24774c30e9fbSJed Brown       }
24784c30e9fbSJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
24796719d8e4SJed Brown 
24806719d8e4SJed Brown       if (flag_threshold) {
24816719d8e4SJed Brown         PetscInt bs,rstart,rend,i;
248294ab13aaSBarry Smith         ierr = MatGetBlockSize(B,&bs);CHKERRQ(ierr);
248394ab13aaSBarry Smith         ierr = MatGetOwnershipRange(B,&rstart,&rend);CHKERRQ(ierr);
24846719d8e4SJed Brown         for (i=rstart; i<rend; i++) {
24856719d8e4SJed Brown           const PetscScalar *ba,*ca;
24866719d8e4SJed Brown           const PetscInt    *bj,*cj;
24876719d8e4SJed Brown           PetscInt          bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1;
24886719d8e4SJed Brown           PetscReal         maxentry = 0,maxdiff = 0,maxrdiff = 0;
248994ab13aaSBarry Smith           ierr = MatGetRow(B,i,&bn,&bj,&ba);CHKERRQ(ierr);
24906719d8e4SJed Brown           ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
249194ab13aaSBarry Smith           if (bn != cn) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold");
24926719d8e4SJed Brown           for (j=0; j<bn; j++) {
24936719d8e4SJed Brown             PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
24946719d8e4SJed Brown             if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) {
24956719d8e4SJed Brown               maxentrycol = bj[j];
24966719d8e4SJed Brown               maxentry    = PetscRealPart(ba[j]);
24976719d8e4SJed Brown             }
24986719d8e4SJed Brown             if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) {
24996719d8e4SJed Brown               maxdiffcol = bj[j];
25006719d8e4SJed Brown               maxdiff    = PetscRealPart(ca[j]);
25016719d8e4SJed Brown             }
25026719d8e4SJed Brown             if (rdiff > maxrdiff) {
25036719d8e4SJed Brown               maxrdiffcol = bj[j];
25046719d8e4SJed Brown               maxrdiff    = rdiff;
25056719d8e4SJed Brown             }
25066719d8e4SJed Brown           }
25076719d8e4SJed Brown           if (maxrdiff > 1) {
250857622a8eSBarry 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);
25096719d8e4SJed Brown             for (j=0; j<bn; j++) {
25106719d8e4SJed Brown               PetscReal rdiff;
25116719d8e4SJed Brown               rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
25126719d8e4SJed Brown               if (rdiff > 1) {
251357622a8eSBarry Smith                 ierr = PetscViewerASCIIPrintf(vstdout," (%D,%g:%g)",bj[j],(double)PetscRealPart(ba[j]),(double)PetscRealPart(ca[j]));CHKERRQ(ierr);
25146719d8e4SJed Brown               }
25156719d8e4SJed Brown             }
25166719d8e4SJed Brown             ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr);
25176719d8e4SJed Brown           }
251894ab13aaSBarry Smith           ierr = MatRestoreRow(B,i,&bn,&bj,&ba);CHKERRQ(ierr);
25196719d8e4SJed Brown           ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
25206719d8e4SJed Brown         }
25216719d8e4SJed Brown       }
25224c30e9fbSJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
25234c30e9fbSJed Brown       ierr = MatDestroy(&Bfd);CHKERRQ(ierr);
25244c30e9fbSJed Brown     }
25254c30e9fbSJed Brown   }
25263a40ed3dSBarry Smith   PetscFunctionReturn(0);
25279b94acceSBarry Smith }
25289b94acceSBarry Smith 
2529bf388a1fSBarry Smith /*MC
2530411c0326SBarry Smith     SNESJacobianFunction - Function used to convey the nonlinear Jacobian of the function to be solved by SNES
2531bf388a1fSBarry Smith 
2532bf388a1fSBarry Smith      Synopsis:
2533411c0326SBarry Smith      #include "petscsnes.h"
2534411c0326SBarry Smith      PetscErrorCode SNESJacobianFunction(SNES snes,Vec x,Mat Amat,Mat Pmat,void *ctx);
2535bf388a1fSBarry Smith 
2536bf388a1fSBarry Smith +  x - input vector
2537e5d3d808SBarry Smith .  Amat - the matrix that defines the (approximate) Jacobian
2538e5d3d808SBarry Smith .  Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat.
2539bf388a1fSBarry Smith -  ctx - [optional] user-defined Jacobian context
2540bf388a1fSBarry Smith 
2541878cb397SSatish Balay    Level: intermediate
2542878cb397SSatish Balay 
2543bf388a1fSBarry Smith .seealso:   SNESSetFunction(), SNESGetFunction(), SNESSetJacobian(), SNESGetJacobian()
2544bf388a1fSBarry Smith M*/
2545bf388a1fSBarry Smith 
25469b94acceSBarry Smith /*@C
25479b94acceSBarry Smith    SNESSetJacobian - Sets the function to compute Jacobian as well as the
2548044dda88SLois Curfman McInnes    location to store the matrix.
25499b94acceSBarry Smith 
25503f9fe445SBarry Smith    Logically Collective on SNES and Mat
2551c7afd0dbSLois Curfman McInnes 
25529b94acceSBarry Smith    Input Parameters:
2553c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2554e5d3d808SBarry Smith .  Amat - the matrix that defines the (approximate) Jacobian
2555e5d3d808SBarry Smith .  Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat.
2556411c0326SBarry Smith .  J - Jacobian evaluation routine (if NULL then SNES retains any previously set value), see SNESJacobianFunction for details
2557c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
25580298fd71SBarry Smith          Jacobian evaluation routine (may be NULL) (if NULL then SNES retains any previously set value)
25599b94acceSBarry Smith 
25609b94acceSBarry Smith    Notes:
2561e5d3d808SBarry Smith    If the Amat matrix and Pmat matrix are different you must call MatAssemblyBegin/End() on
256216913363SBarry Smith    each matrix.
256316913363SBarry Smith 
2564895c21f2SBarry Smith    If you know the operator Amat has a null space you can use MatSetNullSpace() and MatSetTransposeNullSpace() to supply the null
2565895c21f2SBarry Smith    space to Amat and the KSP solvers will automatically use that null space as needed during the solution process.
2566895c21f2SBarry Smith 
25678d359177SBarry Smith    If using SNESComputeJacobianDefaultColor() to assemble a Jacobian, the ctx argument
2568a8a26c1eSJed Brown    must be a MatFDColoring.
2569a8a26c1eSJed Brown 
2570c3cc8fd1SJed Brown    Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian.  One common
2571c3cc8fd1SJed Brown    example is to use the "Picard linearization" which only differentiates through the highest order parts of each term.
2572c3cc8fd1SJed Brown 
257336851e7fSLois Curfman McInnes    Level: beginner
257436851e7fSLois Curfman McInnes 
25759b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix
25769b94acceSBarry Smith 
2577411c0326SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESComputeJacobianDefaultColor(), MatStructure, J,
2578411c0326SBarry Smith           SNESSetPicard(), SNESJacobianFunction
25799b94acceSBarry Smith @*/
2580d1e9a80fSBarry Smith PetscErrorCode  SNESSetJacobian(SNES snes,Mat Amat,Mat Pmat,PetscErrorCode (*J)(SNES,Vec,Mat,Mat,void*),void *ctx)
25819b94acceSBarry Smith {
2582dfbe8321SBarry Smith   PetscErrorCode ierr;
25836cab3a1bSJed Brown   DM             dm;
25843a7fca6bSBarry Smith 
25853a40ed3dSBarry Smith   PetscFunctionBegin;
25860700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2587e5d3d808SBarry Smith   if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2);
2588e5d3d808SBarry Smith   if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_CLASSID,3);
2589e5d3d808SBarry Smith   if (Amat) PetscCheckSameComm(snes,1,Amat,2);
2590e5d3d808SBarry Smith   if (Pmat) PetscCheckSameComm(snes,1,Pmat,3);
25916cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2592f8b49ee9SBarry Smith   ierr = DMSNESSetJacobian(dm,J,ctx);CHKERRQ(ierr);
2593e5d3d808SBarry Smith   if (Amat) {
2594e5d3d808SBarry Smith     ierr = PetscObjectReference((PetscObject)Amat);CHKERRQ(ierr);
25956bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
2596f5af7f23SKarl Rupp 
2597e5d3d808SBarry Smith     snes->jacobian = Amat;
25983a7fca6bSBarry Smith   }
2599e5d3d808SBarry Smith   if (Pmat) {
2600e5d3d808SBarry Smith     ierr = PetscObjectReference((PetscObject)Pmat);CHKERRQ(ierr);
26016bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
2602f5af7f23SKarl Rupp 
2603e5d3d808SBarry Smith     snes->jacobian_pre = Pmat;
26043a7fca6bSBarry Smith   }
26053a40ed3dSBarry Smith   PetscFunctionReturn(0);
26069b94acceSBarry Smith }
260762fef451SLois Curfman McInnes 
2608c2aafc4cSSatish Balay /*@C
2609b4fd4287SBarry Smith    SNESGetJacobian - Returns the Jacobian matrix and optionally the user
2610b4fd4287SBarry Smith    provided context for evaluating the Jacobian.
2611b4fd4287SBarry Smith 
2612c7afd0dbSLois Curfman McInnes    Not Collective, but Mat object will be parallel if SNES object is
2613c7afd0dbSLois Curfman McInnes 
2614b4fd4287SBarry Smith    Input Parameter:
2615b4fd4287SBarry Smith .  snes - the nonlinear solver context
2616b4fd4287SBarry Smith 
2617b4fd4287SBarry Smith    Output Parameters:
2618e5d3d808SBarry Smith +  Amat - location to stash (approximate) Jacobian matrix (or NULL)
2619e5d3d808SBarry Smith .  Pmat - location to stash matrix used to compute the preconditioner (or NULL)
2620411c0326SBarry Smith .  J - location to put Jacobian function (or NULL), see SNESJacobianFunction for details on its calling sequence
26210298fd71SBarry Smith -  ctx - location to stash Jacobian ctx (or NULL)
2622fee21e36SBarry Smith 
262336851e7fSLois Curfman McInnes    Level: advanced
262436851e7fSLois Curfman McInnes 
2625411c0326SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian(), SNESJacobianFunction, SNESGetFunction()
2626b4fd4287SBarry Smith @*/
2627d1e9a80fSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *Amat,Mat *Pmat,PetscErrorCode (**J)(SNES,Vec,Mat,Mat,void*),void **ctx)
2628b4fd4287SBarry Smith {
26296cab3a1bSJed Brown   PetscErrorCode ierr;
26306cab3a1bSJed Brown   DM             dm;
2631942e3340SBarry Smith   DMSNES         sdm;
26326cab3a1bSJed Brown 
26333a40ed3dSBarry Smith   PetscFunctionBegin;
26340700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2635e5d3d808SBarry Smith   if (Amat) *Amat = snes->jacobian;
2636e5d3d808SBarry Smith   if (Pmat) *Pmat = snes->jacobian_pre;
26376cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2638942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
2639f8b49ee9SBarry Smith   if (J) *J = sdm->ops->computejacobian;
26406cab3a1bSJed Brown   if (ctx) *ctx = sdm->jacobianctx;
26413a40ed3dSBarry Smith   PetscFunctionReturn(0);
2642b4fd4287SBarry Smith }
2643b4fd4287SBarry Smith 
26449b94acceSBarry Smith /*@
26459b94acceSBarry Smith    SNESSetUp - Sets up the internal data structures for the later use
2646272ac6f2SLois Curfman McInnes    of a nonlinear solver.
26479b94acceSBarry Smith 
2648fee21e36SBarry Smith    Collective on SNES
2649fee21e36SBarry Smith 
2650c7afd0dbSLois Curfman McInnes    Input Parameters:
265170e92668SMatthew Knepley .  snes - the SNES context
2652c7afd0dbSLois Curfman McInnes 
2653272ac6f2SLois Curfman McInnes    Notes:
2654272ac6f2SLois Curfman McInnes    For basic use of the SNES solvers the user need not explicitly call
2655272ac6f2SLois Curfman McInnes    SNESSetUp(), since these actions will automatically occur during
2656272ac6f2SLois Curfman McInnes    the call to SNESSolve().  However, if one wishes to control this
2657272ac6f2SLois Curfman McInnes    phase separately, SNESSetUp() should be called after SNESCreate()
2658272ac6f2SLois Curfman McInnes    and optional routines of the form SNESSetXXX(), but before SNESSolve().
2659272ac6f2SLois Curfman McInnes 
266036851e7fSLois Curfman McInnes    Level: advanced
266136851e7fSLois Curfman McInnes 
26629b94acceSBarry Smith .keywords: SNES, nonlinear, setup
26639b94acceSBarry Smith 
26649b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
26659b94acceSBarry Smith @*/
26667087cfbeSBarry Smith PetscErrorCode  SNESSetUp(SNES snes)
26679b94acceSBarry Smith {
2668dfbe8321SBarry Smith   PetscErrorCode ierr;
26696cab3a1bSJed Brown   DM             dm;
2670942e3340SBarry Smith   DMSNES         sdm;
2671c35f09e5SBarry Smith   SNESLineSearch linesearch, pclinesearch;
26726e2a1849SPeter Brune   void           *lsprectx,*lspostctx;
26736b2b7091SBarry Smith   PetscErrorCode (*precheck)(SNESLineSearch,Vec,Vec,PetscBool*,void*);
26746b2b7091SBarry Smith   PetscErrorCode (*postcheck)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*);
26756e2a1849SPeter Brune   PetscErrorCode (*func)(SNES,Vec,Vec,void*);
26766e2a1849SPeter Brune   Vec            f,fpc;
26776e2a1849SPeter Brune   void           *funcctx;
2678d1e9a80fSBarry Smith   PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*);
26791eb13d49SPeter Brune   void           *jacctx,*appctx;
268032b97717SPeter Brune   Mat            j,jpre;
26813a40ed3dSBarry Smith 
26823a40ed3dSBarry Smith   PetscFunctionBegin;
26830700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
26844dc4c822SBarry Smith   if (snes->setupcalled) PetscFunctionReturn(0);
26859b94acceSBarry Smith 
26867adad957SLisandro Dalcin   if (!((PetscObject)snes)->type_name) {
268704d7464bSBarry Smith     ierr = SNESSetType(snes,SNESNEWTONLS);CHKERRQ(ierr);
268885385478SLisandro Dalcin   }
268985385478SLisandro Dalcin 
26900298fd71SBarry Smith   ierr = SNESGetFunction(snes,&snes->vec_func,NULL,NULL);CHKERRQ(ierr);
269158c9b817SLisandro Dalcin 
26926cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2693942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
2694ce94432eSBarry Smith   if (!sdm->ops->computefunction) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Function never provided to SNES object");
269522c6f798SBarry Smith   if (!sdm->ops->computejacobian) {
26968d359177SBarry Smith     ierr = DMSNESSetJacobian(dm,SNESComputeJacobianDefaultColor,NULL);CHKERRQ(ierr);
269719f7a02aSBarry Smith   }
26986cab3a1bSJed Brown   if (!snes->vec_func) {
26996cab3a1bSJed Brown     ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr);
2700214df951SJed Brown   }
2701efd51863SBarry Smith 
270222d28d08SBarry Smith   if (!snes->ksp) {
270322d28d08SBarry Smith     ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);
270422d28d08SBarry Smith   }
2705b710008aSBarry Smith 
270622d28d08SBarry Smith   if (!snes->linesearch) {
27077601faf0SJed Brown     ierr = SNESGetLineSearch(snes, &snes->linesearch);CHKERRQ(ierr);
270822d28d08SBarry Smith   }
2709ed07d7d7SPeter Brune   ierr = SNESLineSearchSetFunction(snes->linesearch,SNESComputeFunction);CHKERRQ(ierr);
27109e764e56SPeter Brune 
2711172a4300SPeter Brune   if (snes->pc && (snes->pcside == PC_LEFT)) {
2712172a4300SPeter Brune     snes->mf          = PETSC_TRUE;
2713172a4300SPeter Brune     snes->mf_operator = PETSC_FALSE;
2714172a4300SPeter Brune   }
2715d8f46077SPeter Brune 
27166e2a1849SPeter Brune   if (snes->pc) {
27176e2a1849SPeter Brune     /* copy the DM over */
27186e2a1849SPeter Brune     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
27196e2a1849SPeter Brune     ierr = SNESSetDM(snes->pc,dm);CHKERRQ(ierr);
27206e2a1849SPeter Brune 
27216e2a1849SPeter Brune     ierr = SNESGetFunction(snes,&f,&func,&funcctx);CHKERRQ(ierr);
27226e2a1849SPeter Brune     ierr = VecDuplicate(f,&fpc);CHKERRQ(ierr);
27236e2a1849SPeter Brune     ierr = SNESSetFunction(snes->pc,fpc,func,funcctx);CHKERRQ(ierr);
272432b97717SPeter Brune     ierr = SNESGetJacobian(snes,&j,&jpre,&jac,&jacctx);CHKERRQ(ierr);
272532b97717SPeter Brune     ierr = SNESSetJacobian(snes->pc,j,jpre,jac,jacctx);CHKERRQ(ierr);
27261eb13d49SPeter Brune     ierr = SNESGetApplicationContext(snes,&appctx);CHKERRQ(ierr);
27271eb13d49SPeter Brune     ierr = SNESSetApplicationContext(snes->pc,appctx);CHKERRQ(ierr);
27286e2a1849SPeter Brune     ierr = VecDestroy(&fpc);CHKERRQ(ierr);
27296e2a1849SPeter Brune 
27306e2a1849SPeter Brune     /* copy the function pointers over */
27316e2a1849SPeter Brune     ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)snes,(PetscObject)snes->pc);CHKERRQ(ierr);
27326e2a1849SPeter Brune 
27336e2a1849SPeter Brune     /* default to 1 iteration */
2734140836e4SPeter Brune     ierr = SNESSetTolerances(snes->pc,0.0,0.0,0.0,1,snes->pc->max_funcs);CHKERRQ(ierr);
2735a9936a0cSPeter Brune     if (snes->pcside==PC_RIGHT) {
2736365a6726SPeter Brune       ierr = SNESSetNormSchedule(snes->pc,SNES_NORM_FINAL_ONLY);CHKERRQ(ierr);
2737a9936a0cSPeter Brune     } else {
2738365a6726SPeter Brune       ierr = SNESSetNormSchedule(snes->pc,SNES_NORM_NONE);CHKERRQ(ierr);
2739a9936a0cSPeter Brune     }
27406e2a1849SPeter Brune     ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr);
27416e2a1849SPeter Brune 
27426e2a1849SPeter Brune     /* copy the line search context over */
27437601faf0SJed Brown     ierr = SNESGetLineSearch(snes,&linesearch);CHKERRQ(ierr);
27447601faf0SJed Brown     ierr = SNESGetLineSearch(snes->pc,&pclinesearch);CHKERRQ(ierr);
27456b2b7091SBarry Smith     ierr = SNESLineSearchGetPreCheck(linesearch,&precheck,&lsprectx);CHKERRQ(ierr);
27466b2b7091SBarry Smith     ierr = SNESLineSearchGetPostCheck(linesearch,&postcheck,&lspostctx);CHKERRQ(ierr);
27476b2b7091SBarry Smith     ierr = SNESLineSearchSetPreCheck(pclinesearch,precheck,lsprectx);CHKERRQ(ierr);
27486b2b7091SBarry Smith     ierr = SNESLineSearchSetPostCheck(pclinesearch,postcheck,lspostctx);CHKERRQ(ierr);
27496e2a1849SPeter Brune     ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch);CHKERRQ(ierr);
27506e2a1849SPeter Brune   }
275132b97717SPeter Brune   if (snes->mf) {
275232b97717SPeter Brune     ierr = SNESSetUpMatrixFree_Private(snes, snes->mf_operator, snes->mf_version);CHKERRQ(ierr);
275332b97717SPeter Brune   }
275432b97717SPeter Brune   if (snes->ops->usercompute && !snes->user) {
275532b97717SPeter Brune     ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr);
275632b97717SPeter Brune   }
27576e2a1849SPeter Brune 
275837ec4e1aSPeter Brune   snes->jac_iter = 0;
275937ec4e1aSPeter Brune   snes->pre_iter = 0;
276037ec4e1aSPeter Brune 
2761410397dcSLisandro Dalcin   if (snes->ops->setup) {
2762410397dcSLisandro Dalcin     ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr);
2763410397dcSLisandro Dalcin   }
276458c9b817SLisandro Dalcin 
27656c67d002SPeter Brune   if (snes->pc && (snes->pcside == PC_LEFT)) {
27666c67d002SPeter Brune     if (snes->functype == SNES_FUNCTION_PRECONDITIONED) {
276755d4788fSPeter Brune       ierr = SNESGetLineSearch(snes,&linesearch);CHKERRQ(ierr);
2768be95d8f1SBarry Smith       ierr = SNESLineSearchSetFunction(linesearch,SNESComputeFunctionDefaultNPC);CHKERRQ(ierr);
27696c67d002SPeter Brune     }
27706c67d002SPeter Brune   }
27716c67d002SPeter Brune 
27727aaed0d8SBarry Smith   snes->setupcalled = PETSC_TRUE;
27733a40ed3dSBarry Smith   PetscFunctionReturn(0);
27749b94acceSBarry Smith }
27759b94acceSBarry Smith 
277637596af1SLisandro Dalcin /*@
277737596af1SLisandro Dalcin    SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats
277837596af1SLisandro Dalcin 
277937596af1SLisandro Dalcin    Collective on SNES
278037596af1SLisandro Dalcin 
278137596af1SLisandro Dalcin    Input Parameter:
278237596af1SLisandro Dalcin .  snes - iterative context obtained from SNESCreate()
278337596af1SLisandro Dalcin 
2784d25893d9SBarry Smith    Level: intermediate
2785d25893d9SBarry Smith 
2786d25893d9SBarry Smith    Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext()
278737596af1SLisandro Dalcin 
278837596af1SLisandro Dalcin .keywords: SNES, destroy
278937596af1SLisandro Dalcin 
279037596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve()
279137596af1SLisandro Dalcin @*/
279237596af1SLisandro Dalcin PetscErrorCode  SNESReset(SNES snes)
279337596af1SLisandro Dalcin {
279437596af1SLisandro Dalcin   PetscErrorCode ierr;
279537596af1SLisandro Dalcin 
279637596af1SLisandro Dalcin   PetscFunctionBegin;
279737596af1SLisandro Dalcin   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2798d25893d9SBarry Smith   if (snes->ops->userdestroy && snes->user) {
2799d25893d9SBarry Smith     ierr       = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr);
28000298fd71SBarry Smith     snes->user = NULL;
2801d25893d9SBarry Smith   }
28028a23116dSBarry Smith   if (snes->pc) {
28038a23116dSBarry Smith     ierr = SNESReset(snes->pc);CHKERRQ(ierr);
28048a23116dSBarry Smith   }
28058a23116dSBarry Smith 
280637596af1SLisandro Dalcin   if (snes->ops->reset) {
280737596af1SLisandro Dalcin     ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr);
280837596af1SLisandro Dalcin   }
28099e764e56SPeter Brune   if (snes->ksp) {
28109e764e56SPeter Brune     ierr = KSPReset(snes->ksp);CHKERRQ(ierr);
28119e764e56SPeter Brune   }
28129e764e56SPeter Brune 
28139e764e56SPeter Brune   if (snes->linesearch) {
2814f1c6b773SPeter Brune     ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr);
28159e764e56SPeter Brune   }
28169e764e56SPeter Brune 
28176bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
28186bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
28196bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr);
28206bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
28216bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
28226bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
2823c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);
2824c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);
2825f5af7f23SKarl Rupp 
282640fdac6aSLawrence Mitchell   snes->alwayscomputesfinalresidual = PETSC_FALSE;
282740fdac6aSLawrence Mitchell 
282837596af1SLisandro Dalcin   snes->nwork       = snes->nvwork = 0;
282937596af1SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
283037596af1SLisandro Dalcin   PetscFunctionReturn(0);
283137596af1SLisandro Dalcin }
283237596af1SLisandro Dalcin 
283352baeb72SSatish Balay /*@
28349b94acceSBarry Smith    SNESDestroy - Destroys the nonlinear solver context that was created
28359b94acceSBarry Smith    with SNESCreate().
28369b94acceSBarry Smith 
2837c7afd0dbSLois Curfman McInnes    Collective on SNES
2838c7afd0dbSLois Curfman McInnes 
28399b94acceSBarry Smith    Input Parameter:
28409b94acceSBarry Smith .  snes - the SNES context
28419b94acceSBarry Smith 
284236851e7fSLois Curfman McInnes    Level: beginner
284336851e7fSLois Curfman McInnes 
28449b94acceSBarry Smith .keywords: SNES, nonlinear, destroy
28459b94acceSBarry Smith 
284663a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve()
28479b94acceSBarry Smith @*/
28486bf464f9SBarry Smith PetscErrorCode  SNESDestroy(SNES *snes)
28499b94acceSBarry Smith {
28506849ba73SBarry Smith   PetscErrorCode ierr;
28513a40ed3dSBarry Smith 
28523a40ed3dSBarry Smith   PetscFunctionBegin;
28536bf464f9SBarry Smith   if (!*snes) PetscFunctionReturn(0);
28546bf464f9SBarry Smith   PetscValidHeaderSpecific((*snes),SNES_CLASSID,1);
28556bf464f9SBarry Smith   if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);}
2856d4bb536fSBarry Smith 
28576bf464f9SBarry Smith   ierr = SNESReset((*snes));CHKERRQ(ierr);
28588a23116dSBarry Smith   ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr);
28596b8b9a38SLisandro Dalcin 
2860e04113cfSBarry Smith   /* if memory was published with SAWs then destroy it */
2861e04113cfSBarry Smith   ierr = PetscObjectSAWsViewOff((PetscObject)*snes);CHKERRQ(ierr);
28626bf464f9SBarry Smith   if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);}
28636d4c513bSLisandro Dalcin 
28646bf464f9SBarry Smith   ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr);
28656bf464f9SBarry Smith   ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr);
2866f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr);
28676b8b9a38SLisandro Dalcin 
28686bf464f9SBarry Smith   ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr);
28696bf464f9SBarry Smith   if ((*snes)->ops->convergeddestroy) {
28706bf464f9SBarry Smith     ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr);
28716b8b9a38SLisandro Dalcin   }
28726bf464f9SBarry Smith   if ((*snes)->conv_malloc) {
28736bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr);
28746bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr);
287558c9b817SLisandro Dalcin   }
28766bf464f9SBarry Smith   ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr);
2877a79aaaedSSatish Balay   ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr);
28783a40ed3dSBarry Smith   PetscFunctionReturn(0);
28799b94acceSBarry Smith }
28809b94acceSBarry Smith 
28819b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */
28829b94acceSBarry Smith 
2883a8054027SBarry Smith /*@
2884a8054027SBarry Smith    SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.
2885a8054027SBarry Smith 
28863f9fe445SBarry Smith    Logically Collective on SNES
2887a8054027SBarry Smith 
2888a8054027SBarry Smith    Input Parameters:
2889a8054027SBarry Smith +  snes - the SNES context
2890a8054027SBarry 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
28913b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2892a8054027SBarry Smith 
2893a8054027SBarry Smith    Options Database Keys:
2894a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2895a8054027SBarry Smith 
2896a8054027SBarry Smith    Notes:
2897a8054027SBarry Smith    The default is 1
2898a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2899a8054027SBarry Smith    If  -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use
2900a8054027SBarry Smith 
2901a8054027SBarry Smith    Level: intermediate
2902a8054027SBarry Smith 
2903a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2904a8054027SBarry Smith 
2905e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2906a8054027SBarry Smith 
2907a8054027SBarry Smith @*/
29087087cfbeSBarry Smith PetscErrorCode  SNESSetLagPreconditioner(SNES snes,PetscInt lag)
2909a8054027SBarry Smith {
2910a8054027SBarry Smith   PetscFunctionBegin;
29110700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2912e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2913e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2914c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2915a8054027SBarry Smith   snes->lagpreconditioner = lag;
2916a8054027SBarry Smith   PetscFunctionReturn(0);
2917a8054027SBarry Smith }
2918a8054027SBarry Smith 
2919efd51863SBarry Smith /*@
2920efd51863SBarry Smith    SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does
2921efd51863SBarry Smith 
2922efd51863SBarry Smith    Logically Collective on SNES
2923efd51863SBarry Smith 
2924efd51863SBarry Smith    Input Parameters:
2925efd51863SBarry Smith +  snes - the SNES context
2926efd51863SBarry Smith -  steps - the number of refinements to do, defaults to 0
2927efd51863SBarry Smith 
2928efd51863SBarry Smith    Options Database Keys:
2929efd51863SBarry Smith .    -snes_grid_sequence <steps>
2930efd51863SBarry Smith 
2931efd51863SBarry Smith    Level: intermediate
2932efd51863SBarry Smith 
2933c0df2a02SJed Brown    Notes:
2934c0df2a02SJed Brown    Use SNESGetSolution() to extract the fine grid solution after grid sequencing.
2935c0df2a02SJed Brown 
2936efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2937efd51863SBarry Smith 
2938fa19ca70SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetGridSequence()
2939efd51863SBarry Smith 
2940efd51863SBarry Smith @*/
2941efd51863SBarry Smith PetscErrorCode  SNESSetGridSequence(SNES snes,PetscInt steps)
2942efd51863SBarry Smith {
2943efd51863SBarry Smith   PetscFunctionBegin;
2944efd51863SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2945efd51863SBarry Smith   PetscValidLogicalCollectiveInt(snes,steps,2);
2946efd51863SBarry Smith   snes->gridsequence = steps;
2947efd51863SBarry Smith   PetscFunctionReturn(0);
2948efd51863SBarry Smith }
2949efd51863SBarry Smith 
2950fa19ca70SBarry Smith /*@
2951fa19ca70SBarry Smith    SNESGetGridSequence - gets the number of steps of grid sequencing that SNES does
2952fa19ca70SBarry Smith 
2953fa19ca70SBarry Smith    Logically Collective on SNES
2954fa19ca70SBarry Smith 
2955fa19ca70SBarry Smith    Input Parameter:
2956fa19ca70SBarry Smith .  snes - the SNES context
2957fa19ca70SBarry Smith 
2958fa19ca70SBarry Smith    Output Parameter:
2959fa19ca70SBarry Smith .  steps - the number of refinements to do, defaults to 0
2960fa19ca70SBarry Smith 
2961fa19ca70SBarry Smith    Options Database Keys:
2962fa19ca70SBarry Smith .    -snes_grid_sequence <steps>
2963fa19ca70SBarry Smith 
2964fa19ca70SBarry Smith    Level: intermediate
2965fa19ca70SBarry Smith 
2966fa19ca70SBarry Smith    Notes:
2967fa19ca70SBarry Smith    Use SNESGetSolution() to extract the fine grid solution after grid sequencing.
2968fa19ca70SBarry Smith 
2969fa19ca70SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2970fa19ca70SBarry Smith 
2971fa19ca70SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESSetGridSequence()
2972fa19ca70SBarry Smith 
2973fa19ca70SBarry Smith @*/
2974fa19ca70SBarry Smith PetscErrorCode  SNESGetGridSequence(SNES snes,PetscInt *steps)
2975fa19ca70SBarry Smith {
2976fa19ca70SBarry Smith   PetscFunctionBegin;
2977fa19ca70SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2978fa19ca70SBarry Smith   *steps = snes->gridsequence;
2979fa19ca70SBarry Smith   PetscFunctionReturn(0);
2980fa19ca70SBarry Smith }
2981fa19ca70SBarry Smith 
2982a8054027SBarry Smith /*@
2983a8054027SBarry Smith    SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt
2984a8054027SBarry Smith 
29853f9fe445SBarry Smith    Not Collective
2986a8054027SBarry Smith 
2987a8054027SBarry Smith    Input Parameter:
2988a8054027SBarry Smith .  snes - the SNES context
2989a8054027SBarry Smith 
2990a8054027SBarry Smith    Output Parameter:
2991a8054027SBarry 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
29923b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2993a8054027SBarry Smith 
2994a8054027SBarry Smith    Options Database Keys:
2995a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2996a8054027SBarry Smith 
2997a8054027SBarry Smith    Notes:
2998a8054027SBarry Smith    The default is 1
2999a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
3000a8054027SBarry Smith 
3001a8054027SBarry Smith    Level: intermediate
3002a8054027SBarry Smith 
3003a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
3004a8054027SBarry Smith 
3005a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner()
3006a8054027SBarry Smith 
3007a8054027SBarry Smith @*/
30087087cfbeSBarry Smith PetscErrorCode  SNESGetLagPreconditioner(SNES snes,PetscInt *lag)
3009a8054027SBarry Smith {
3010a8054027SBarry Smith   PetscFunctionBegin;
30110700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3012a8054027SBarry Smith   *lag = snes->lagpreconditioner;
3013a8054027SBarry Smith   PetscFunctionReturn(0);
3014a8054027SBarry Smith }
3015a8054027SBarry Smith 
3016e35cf81dSBarry Smith /*@
3017e35cf81dSBarry Smith    SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how
3018e35cf81dSBarry Smith      often the preconditioner is rebuilt.
3019e35cf81dSBarry Smith 
30203f9fe445SBarry Smith    Logically Collective on SNES
3021e35cf81dSBarry Smith 
3022e35cf81dSBarry Smith    Input Parameters:
3023e35cf81dSBarry Smith +  snes - the SNES context
3024e35cf81dSBarry 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
3025fe3ffe1eSBarry Smith          the Jacobian is built etc. -2 means rebuild at next chance but then never again
3026e35cf81dSBarry Smith 
3027e35cf81dSBarry Smith    Options Database Keys:
3028e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
3029e35cf81dSBarry Smith 
3030e35cf81dSBarry Smith    Notes:
3031e35cf81dSBarry Smith    The default is 1
3032e35cf81dSBarry Smith    The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
3033fe3ffe1eSBarry 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
3034fe3ffe1eSBarry Smith    at the next Newton step but never again (unless it is reset to another value)
3035e35cf81dSBarry Smith 
3036e35cf81dSBarry Smith    Level: intermediate
3037e35cf81dSBarry Smith 
3038e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
3039e35cf81dSBarry Smith 
3040e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian()
3041e35cf81dSBarry Smith 
3042e35cf81dSBarry Smith @*/
30437087cfbeSBarry Smith PetscErrorCode  SNESSetLagJacobian(SNES snes,PetscInt lag)
3044e35cf81dSBarry Smith {
3045e35cf81dSBarry Smith   PetscFunctionBegin;
30460700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3047e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
3048e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
3049c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
3050e35cf81dSBarry Smith   snes->lagjacobian = lag;
3051e35cf81dSBarry Smith   PetscFunctionReturn(0);
3052e35cf81dSBarry Smith }
3053e35cf81dSBarry Smith 
3054e35cf81dSBarry Smith /*@
3055e35cf81dSBarry Smith    SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt
3056e35cf81dSBarry Smith 
30573f9fe445SBarry Smith    Not Collective
3058e35cf81dSBarry Smith 
3059e35cf81dSBarry Smith    Input Parameter:
3060e35cf81dSBarry Smith .  snes - the SNES context
3061e35cf81dSBarry Smith 
3062e35cf81dSBarry Smith    Output Parameter:
3063e35cf81dSBarry 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
3064e35cf81dSBarry Smith          the Jacobian is built etc.
3065e35cf81dSBarry Smith 
3066e35cf81dSBarry Smith    Options Database Keys:
3067e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
3068e35cf81dSBarry Smith 
3069e35cf81dSBarry Smith    Notes:
3070e35cf81dSBarry Smith    The default is 1
3071e35cf81dSBarry Smith    The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
3072e35cf81dSBarry Smith 
3073e35cf81dSBarry Smith    Level: intermediate
3074e35cf81dSBarry Smith 
3075e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
3076e35cf81dSBarry Smith 
3077e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner()
3078e35cf81dSBarry Smith 
3079e35cf81dSBarry Smith @*/
30807087cfbeSBarry Smith PetscErrorCode  SNESGetLagJacobian(SNES snes,PetscInt *lag)
3081e35cf81dSBarry Smith {
3082e35cf81dSBarry Smith   PetscFunctionBegin;
30830700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3084e35cf81dSBarry Smith   *lag = snes->lagjacobian;
3085e35cf81dSBarry Smith   PetscFunctionReturn(0);
3086e35cf81dSBarry Smith }
3087e35cf81dSBarry Smith 
308837ec4e1aSPeter Brune /*@
308937ec4e1aSPeter Brune    SNESSetLagJacobianPersists - Set whether or not the Jacobian lagging persists through multiple solves
309037ec4e1aSPeter Brune 
309137ec4e1aSPeter Brune    Logically collective on SNES
309237ec4e1aSPeter Brune 
309337ec4e1aSPeter Brune    Input Parameter:
309437ec4e1aSPeter Brune +  snes - the SNES context
30959d7e2deaSPeter Brune -   flg - jacobian lagging persists if true
309637ec4e1aSPeter Brune 
309737ec4e1aSPeter Brune    Options Database Keys:
309837ec4e1aSPeter Brune .    -snes_lag_jacobian_persists <flg>
309937ec4e1aSPeter Brune 
310037ec4e1aSPeter Brune    Notes: This is useful both for nonlinear preconditioning, where it's appropriate to have the Jacobian be stale by
310137ec4e1aSPeter Brune    several solves, and for implicit time-stepping, where Jacobian lagging in the inner nonlinear solve over several
310237ec4e1aSPeter Brune    timesteps may present huge efficiency gains.
310337ec4e1aSPeter Brune 
310437ec4e1aSPeter Brune    Level: developer
310537ec4e1aSPeter Brune 
3106be95d8f1SBarry Smith .keywords: SNES, nonlinear, lag
310737ec4e1aSPeter Brune 
3108be95d8f1SBarry Smith .seealso: SNESSetLagPreconditionerPersists(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetNPC()
310937ec4e1aSPeter Brune 
311037ec4e1aSPeter Brune @*/
311137ec4e1aSPeter Brune PetscErrorCode  SNESSetLagJacobianPersists(SNES snes,PetscBool flg)
311237ec4e1aSPeter Brune {
311337ec4e1aSPeter Brune   PetscFunctionBegin;
311437ec4e1aSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
311537ec4e1aSPeter Brune   PetscValidLogicalCollectiveBool(snes,flg,2);
311637ec4e1aSPeter Brune   snes->lagjac_persist = flg;
311737ec4e1aSPeter Brune   PetscFunctionReturn(0);
311837ec4e1aSPeter Brune }
311937ec4e1aSPeter Brune 
312037ec4e1aSPeter Brune /*@
312137ec4e1aSPeter Brune    SNESSetLagPreconditionerPersists - Set whether or not the preconditioner lagging persists through multiple solves
312237ec4e1aSPeter Brune 
312337ec4e1aSPeter Brune    Logically Collective on SNES
312437ec4e1aSPeter Brune 
312537ec4e1aSPeter Brune    Input Parameter:
312637ec4e1aSPeter Brune +  snes - the SNES context
31279d7e2deaSPeter Brune -   flg - preconditioner lagging persists if true
312837ec4e1aSPeter Brune 
312937ec4e1aSPeter Brune    Options Database Keys:
313037ec4e1aSPeter Brune .    -snes_lag_jacobian_persists <flg>
313137ec4e1aSPeter Brune 
313237ec4e1aSPeter Brune    Notes: This is useful both for nonlinear preconditioning, where it's appropriate to have the preconditioner be stale
313337ec4e1aSPeter Brune    by several solves, and for implicit time-stepping, where preconditioner lagging in the inner nonlinear solve over
313437ec4e1aSPeter Brune    several timesteps may present huge efficiency gains.
313537ec4e1aSPeter Brune 
313637ec4e1aSPeter Brune    Level: developer
313737ec4e1aSPeter Brune 
3138be95d8f1SBarry Smith .keywords: SNES, nonlinear, lag
313937ec4e1aSPeter Brune 
3140be95d8f1SBarry Smith .seealso: SNESSetLagJacobianPersists(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetNPC()
314137ec4e1aSPeter Brune 
314237ec4e1aSPeter Brune @*/
314337ec4e1aSPeter Brune PetscErrorCode  SNESSetLagPreconditionerPersists(SNES snes,PetscBool flg)
314437ec4e1aSPeter Brune {
314537ec4e1aSPeter Brune   PetscFunctionBegin;
314637ec4e1aSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
314737ec4e1aSPeter Brune   PetscValidLogicalCollectiveBool(snes,flg,2);
314837ec4e1aSPeter Brune   snes->lagpre_persist = flg;
314937ec4e1aSPeter Brune   PetscFunctionReturn(0);
315037ec4e1aSPeter Brune }
315137ec4e1aSPeter Brune 
31529b94acceSBarry Smith /*@
3153d7a720efSLois Curfman McInnes    SNESSetTolerances - Sets various parameters used in convergence tests.
31549b94acceSBarry Smith 
31553f9fe445SBarry Smith    Logically Collective on SNES
3156c7afd0dbSLois Curfman McInnes 
31579b94acceSBarry Smith    Input Parameters:
3158c7afd0dbSLois Curfman McInnes +  snes - the SNES context
315970441072SBarry Smith .  abstol - absolute convergence tolerance
316033174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
31615358d0d4SBarry Smith .  stol -  convergence tolerance in terms of the norm of the change in the solution between steps,  || delta x || < stol*|| x ||
316233174efeSLois Curfman McInnes .  maxit - maximum number of iterations
3163c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
3164fee21e36SBarry Smith 
316533174efeSLois Curfman McInnes    Options Database Keys:
316670441072SBarry Smith +    -snes_atol <abstol> - Sets abstol
3167c7afd0dbSLois Curfman McInnes .    -snes_rtol <rtol> - Sets rtol
3168c7afd0dbSLois Curfman McInnes .    -snes_stol <stol> - Sets stol
3169c7afd0dbSLois Curfman McInnes .    -snes_max_it <maxit> - Sets maxit
3170c7afd0dbSLois Curfman McInnes -    -snes_max_funcs <maxf> - Sets maxf
31719b94acceSBarry Smith 
3172d7a720efSLois Curfman McInnes    Notes:
31739b94acceSBarry Smith    The default maximum number of iterations is 50.
31749b94acceSBarry Smith    The default maximum number of function evaluations is 1000.
31759b94acceSBarry Smith 
317636851e7fSLois Curfman McInnes    Level: intermediate
317736851e7fSLois Curfman McInnes 
317833174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances
31799b94acceSBarry Smith 
3180e4d06f11SPatrick Farrell .seealso: SNESSetTrustRegionTolerance(), SNESSetDivergenceTolerance()
31819b94acceSBarry Smith @*/
31827087cfbeSBarry Smith PetscErrorCode  SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
31839b94acceSBarry Smith {
31843a40ed3dSBarry Smith   PetscFunctionBegin;
31850700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3186c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,abstol,2);
3187c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol,3);
3188c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,stol,4);
3189c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxit,5);
3190c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxf,6);
3191c5eb9154SBarry Smith 
3192ab54825eSJed Brown   if (abstol != PETSC_DEFAULT) {
319357622a8eSBarry Smith     if (abstol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %g must be non-negative",(double)abstol);
3194ab54825eSJed Brown     snes->abstol = abstol;
3195ab54825eSJed Brown   }
3196ab54825eSJed Brown   if (rtol != PETSC_DEFAULT) {
319757622a8eSBarry 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);
3198ab54825eSJed Brown     snes->rtol = rtol;
3199ab54825eSJed Brown   }
3200ab54825eSJed Brown   if (stol != PETSC_DEFAULT) {
320157622a8eSBarry Smith     if (stol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %g must be non-negative",(double)stol);
3202c60f73f4SPeter Brune     snes->stol = stol;
3203ab54825eSJed Brown   }
3204ab54825eSJed Brown   if (maxit != PETSC_DEFAULT) {
3205ce94432eSBarry Smith     if (maxit < 0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit);
3206ab54825eSJed Brown     snes->max_its = maxit;
3207ab54825eSJed Brown   }
3208ab54825eSJed Brown   if (maxf != PETSC_DEFAULT) {
3209ce94432eSBarry Smith     if (maxf < 0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf);
3210ab54825eSJed Brown     snes->max_funcs = maxf;
3211ab54825eSJed Brown   }
321288976e71SPeter Brune   snes->tolerancesset = PETSC_TRUE;
32133a40ed3dSBarry Smith   PetscFunctionReturn(0);
32149b94acceSBarry Smith }
32159b94acceSBarry Smith 
3216e4d06f11SPatrick Farrell /*@
3217e4d06f11SPatrick Farrell    SNESSetDivergenceTolerance - Sets the divergence tolerance used for the SNES divergence test.
3218e4d06f11SPatrick Farrell 
3219e4d06f11SPatrick Farrell    Logically Collective on SNES
3220e4d06f11SPatrick Farrell 
3221e4d06f11SPatrick Farrell    Input Parameters:
3222e4d06f11SPatrick Farrell +  snes - the SNES context
3223e4d06f11SPatrick Farrell -  divtol - the divergence tolerance. Use -1 to deactivate the test.
3224e4d06f11SPatrick Farrell 
3225e4d06f11SPatrick Farrell    Options Database Keys:
3226e4d06f11SPatrick Farrell +    -snes_divergence_tolerance <divtol> - Sets divtol
3227e4d06f11SPatrick Farrell 
3228e4d06f11SPatrick Farrell    Notes:
3229e4d06f11SPatrick Farrell    The default divergence tolerance is 1e4.
3230e4d06f11SPatrick Farrell 
3231e4d06f11SPatrick Farrell    Level: intermediate
3232e4d06f11SPatrick Farrell 
3233e4d06f11SPatrick Farrell .keywords: SNES, nonlinear, set, divergence, tolerance
3234e4d06f11SPatrick Farrell 
3235e4d06f11SPatrick Farrell .seealso: SNESSetTolerances(), SNESGetDivergenceTolerance
3236e4d06f11SPatrick Farrell @*/
3237e4d06f11SPatrick Farrell PetscErrorCode  SNESSetDivergenceTolerance(SNES snes,PetscReal divtol)
3238e4d06f11SPatrick Farrell {
3239e4d06f11SPatrick Farrell   PetscFunctionBegin;
3240e4d06f11SPatrick Farrell   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3241e4d06f11SPatrick Farrell   PetscValidLogicalCollectiveReal(snes,divtol,2);
3242e4d06f11SPatrick Farrell 
3243e4d06f11SPatrick Farrell   if (divtol != PETSC_DEFAULT) {
3244e4d06f11SPatrick Farrell     snes->divtol = divtol;
3245e4d06f11SPatrick Farrell   }
3246e4d06f11SPatrick Farrell   else {
3247e4d06f11SPatrick Farrell     snes->divtol = 1.0e4;
3248e4d06f11SPatrick Farrell   }
3249e4d06f11SPatrick Farrell   PetscFunctionReturn(0);
3250e4d06f11SPatrick Farrell }
3251e4d06f11SPatrick Farrell 
32529b94acceSBarry Smith /*@
325333174efeSLois Curfman McInnes    SNESGetTolerances - Gets various parameters used in convergence tests.
325433174efeSLois Curfman McInnes 
3255c7afd0dbSLois Curfman McInnes    Not Collective
3256c7afd0dbSLois Curfman McInnes 
325733174efeSLois Curfman McInnes    Input Parameters:
3258c7afd0dbSLois Curfman McInnes +  snes - the SNES context
325985385478SLisandro Dalcin .  atol - absolute convergence tolerance
326033174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
326133174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
326233174efeSLois Curfman McInnes            of the change in the solution between steps
326333174efeSLois Curfman McInnes .  maxit - maximum number of iterations
3264c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
3265fee21e36SBarry Smith 
326633174efeSLois Curfman McInnes    Notes:
32670298fd71SBarry Smith    The user can specify NULL for any parameter that is not needed.
326833174efeSLois Curfman McInnes 
326936851e7fSLois Curfman McInnes    Level: intermediate
327036851e7fSLois Curfman McInnes 
327133174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances
327233174efeSLois Curfman McInnes 
327333174efeSLois Curfman McInnes .seealso: SNESSetTolerances()
327433174efeSLois Curfman McInnes @*/
32757087cfbeSBarry Smith PetscErrorCode  SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
327633174efeSLois Curfman McInnes {
32773a40ed3dSBarry Smith   PetscFunctionBegin;
32780700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
327985385478SLisandro Dalcin   if (atol)  *atol  = snes->abstol;
328033174efeSLois Curfman McInnes   if (rtol)  *rtol  = snes->rtol;
3281c60f73f4SPeter Brune   if (stol)  *stol  = snes->stol;
328233174efeSLois Curfman McInnes   if (maxit) *maxit = snes->max_its;
328333174efeSLois Curfman McInnes   if (maxf)  *maxf  = snes->max_funcs;
32843a40ed3dSBarry Smith   PetscFunctionReturn(0);
328533174efeSLois Curfman McInnes }
328633174efeSLois Curfman McInnes 
3287e4d06f11SPatrick Farrell /*@
3288e4d06f11SPatrick Farrell    SNESGetDivergenceTolerance - Gets divergence tolerance used in divergence test.
3289e4d06f11SPatrick Farrell 
3290e4d06f11SPatrick Farrell    Not Collective
3291e4d06f11SPatrick Farrell 
3292e4d06f11SPatrick Farrell    Input Parameters:
3293e4d06f11SPatrick Farrell +  snes - the SNES context
3294e4d06f11SPatrick Farrell -  divtol - divergence tolerance
3295e4d06f11SPatrick Farrell 
3296e4d06f11SPatrick Farrell    Level: intermediate
3297e4d06f11SPatrick Farrell 
3298e4d06f11SPatrick Farrell .keywords: SNES, nonlinear, get, divergence, tolerance
3299e4d06f11SPatrick Farrell 
3300e4d06f11SPatrick Farrell .seealso: SNESSetDivergenceTolerance()
3301e4d06f11SPatrick Farrell @*/
3302e4d06f11SPatrick Farrell PetscErrorCode  SNESGetDivergenceTolerance(SNES snes,PetscReal *divtol)
3303e4d06f11SPatrick Farrell {
3304e4d06f11SPatrick Farrell   PetscFunctionBegin;
3305e4d06f11SPatrick Farrell   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3306e4d06f11SPatrick Farrell   if (divtol) *divtol = snes->divtol;
3307e4d06f11SPatrick Farrell   PetscFunctionReturn(0);
3308e4d06f11SPatrick Farrell }
3309e4d06f11SPatrick Farrell 
331033174efeSLois Curfman McInnes /*@
33119b94acceSBarry Smith    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
33129b94acceSBarry Smith 
33133f9fe445SBarry Smith    Logically Collective on SNES
3314fee21e36SBarry Smith 
3315c7afd0dbSLois Curfman McInnes    Input Parameters:
3316c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3317c7afd0dbSLois Curfman McInnes -  tol - tolerance
3318c7afd0dbSLois Curfman McInnes 
33199b94acceSBarry Smith    Options Database Key:
3320c7afd0dbSLois Curfman McInnes .  -snes_trtol <tol> - Sets tol
33219b94acceSBarry Smith 
332236851e7fSLois Curfman McInnes    Level: intermediate
332336851e7fSLois Curfman McInnes 
33249b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance
33259b94acceSBarry Smith 
33262492ecdbSBarry Smith .seealso: SNESSetTolerances()
33279b94acceSBarry Smith @*/
33287087cfbeSBarry Smith PetscErrorCode  SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
33299b94acceSBarry Smith {
33303a40ed3dSBarry Smith   PetscFunctionBegin;
33310700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3332c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,tol,2);
33339b94acceSBarry Smith   snes->deltatol = tol;
33343a40ed3dSBarry Smith   PetscFunctionReturn(0);
33359b94acceSBarry Smith }
33369b94acceSBarry Smith 
3337df9fa365SBarry Smith /*
3338df9fa365SBarry Smith    Duplicate the lg monitors for SNES from KSP; for some reason with
3339df9fa365SBarry Smith    dynamic libraries things don't work under Sun4 if we just use
3340df9fa365SBarry Smith    macros instead of functions
3341df9fa365SBarry Smith */
3342d96771aaSLisandro Dalcin PetscErrorCode  SNESMonitorLGResidualNorm(SNES snes,PetscInt it,PetscReal norm,void *ctx)
3343ce1608b8SBarry Smith {
3344dfbe8321SBarry Smith   PetscErrorCode ierr;
3345ce1608b8SBarry Smith 
3346ce1608b8SBarry Smith   PetscFunctionBegin;
33470700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3348d96771aaSLisandro Dalcin   ierr = KSPMonitorLGResidualNorm((KSP)snes,it,norm,ctx);CHKERRQ(ierr);
3349ce1608b8SBarry Smith   PetscFunctionReturn(0);
3350ce1608b8SBarry Smith }
3351ce1608b8SBarry Smith 
3352d96771aaSLisandro Dalcin PetscErrorCode  SNESMonitorLGCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *lgctx)
3353df9fa365SBarry Smith {
3354dfbe8321SBarry Smith   PetscErrorCode ierr;
3355df9fa365SBarry Smith 
3356df9fa365SBarry Smith   PetscFunctionBegin;
3357d96771aaSLisandro Dalcin   ierr = KSPMonitorLGResidualNormCreate(comm,host,label,x,y,m,n,lgctx);CHKERRQ(ierr);
3358df9fa365SBarry Smith   PetscFunctionReturn(0);
3359df9fa365SBarry Smith }
3360df9fa365SBarry Smith 
33616ba87a44SLisandro Dalcin PETSC_INTERN PetscErrorCode  SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
33626ba87a44SLisandro Dalcin 
33637087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx)
3364b271bb04SBarry Smith {
3365b271bb04SBarry Smith   PetscDrawLG      lg;
3366b271bb04SBarry Smith   PetscErrorCode   ierr;
3367b271bb04SBarry Smith   PetscReal        x,y,per;
3368b271bb04SBarry Smith   PetscViewer      v = (PetscViewer)monctx;
3369b271bb04SBarry Smith   static PetscReal prev; /* should be in the context */
3370b271bb04SBarry Smith   PetscDraw        draw;
3371b271bb04SBarry Smith 
3372459f5d12SBarry Smith   PetscFunctionBegin;
33734d4332d5SBarry Smith   PetscValidHeaderSpecific(v,PETSC_VIEWER_CLASSID,4);
3374b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr);
3375b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
3376b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
3377b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr);
3378b271bb04SBarry Smith   x    = (PetscReal)n;
337977b4d14cSPeter Brune   if (rnorm > 0.0) y = PetscLog10Real(rnorm);
338094c9c6d3SKarl Rupp   else y = -15.0;
3381b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
33826934998bSLisandro Dalcin   if (n < 20 || !(n % 5) || snes->reason) {
3383b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
33846934998bSLisandro Dalcin     ierr = PetscDrawLGSave(lg);CHKERRQ(ierr);
3385b271bb04SBarry Smith   }
3386b271bb04SBarry Smith 
3387b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr);
3388b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
3389b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
3390b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr);
3391b271bb04SBarry Smith   ierr =  SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr);
3392b271bb04SBarry Smith   x    = (PetscReal)n;
3393b271bb04SBarry Smith   y    = 100.0*per;
3394b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
33956934998bSLisandro Dalcin   if (n < 20 || !(n % 5) || snes->reason) {
3396b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
33976934998bSLisandro Dalcin     ierr = PetscDrawLGSave(lg);CHKERRQ(ierr);
3398b271bb04SBarry Smith   }
3399b271bb04SBarry Smith 
3400b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr);
3401b271bb04SBarry Smith   if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
3402b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
3403b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr);
3404b271bb04SBarry Smith   x    = (PetscReal)n;
3405b271bb04SBarry Smith   y    = (prev - rnorm)/prev;
3406b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
34076934998bSLisandro Dalcin   if (n < 20 || !(n % 5) || snes->reason) {
3408b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
34096934998bSLisandro Dalcin     ierr = PetscDrawLGSave(lg);CHKERRQ(ierr);
3410b271bb04SBarry Smith   }
3411b271bb04SBarry Smith 
3412b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr);
3413b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
3414b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
3415b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr);
3416b271bb04SBarry Smith   x    = (PetscReal)n;
3417b271bb04SBarry Smith   y    = (prev - rnorm)/(prev*per);
3418b271bb04SBarry Smith   if (n > 2) { /*skip initial crazy value */
3419b271bb04SBarry Smith     ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
3420b271bb04SBarry Smith   }
34216934998bSLisandro Dalcin   if (n < 20 || !(n % 5) || snes->reason) {
3422b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
34236934998bSLisandro Dalcin     ierr = PetscDrawLGSave(lg);CHKERRQ(ierr);
3424b271bb04SBarry Smith   }
3425b271bb04SBarry Smith   prev = rnorm;
3426b271bb04SBarry Smith   PetscFunctionReturn(0);
3427b271bb04SBarry Smith }
3428b271bb04SBarry Smith 
3429228d79bcSJed Brown /*@
3430228d79bcSJed Brown    SNESMonitor - runs the user provided monitor routines, if they exist
3431228d79bcSJed Brown 
3432228d79bcSJed Brown    Collective on SNES
3433228d79bcSJed Brown 
3434228d79bcSJed Brown    Input Parameters:
3435228d79bcSJed Brown +  snes - nonlinear solver context obtained from SNESCreate()
3436228d79bcSJed Brown .  iter - iteration number
3437228d79bcSJed Brown -  rnorm - relative norm of the residual
3438228d79bcSJed Brown 
3439228d79bcSJed Brown    Notes:
3440228d79bcSJed Brown    This routine is called by the SNES implementations.
3441228d79bcSJed Brown    It does not typically need to be called by the user.
3442228d79bcSJed Brown 
3443228d79bcSJed Brown    Level: developer
3444228d79bcSJed Brown 
3445228d79bcSJed Brown .seealso: SNESMonitorSet()
3446228d79bcSJed Brown @*/
34477a03ce2fSLisandro Dalcin PetscErrorCode  SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm)
34487a03ce2fSLisandro Dalcin {
34497a03ce2fSLisandro Dalcin   PetscErrorCode ierr;
34507a03ce2fSLisandro Dalcin   PetscInt       i,n = snes->numbermonitors;
34517a03ce2fSLisandro Dalcin 
34527a03ce2fSLisandro Dalcin   PetscFunctionBegin;
34535edff71fSBarry Smith   ierr = VecLockPush(snes->vec_sol);CHKERRQ(ierr);
34547a03ce2fSLisandro Dalcin   for (i=0; i<n; i++) {
34557a03ce2fSLisandro Dalcin     ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr);
34567a03ce2fSLisandro Dalcin   }
34575edff71fSBarry Smith   ierr = VecLockPop(snes->vec_sol);CHKERRQ(ierr);
34587a03ce2fSLisandro Dalcin   PetscFunctionReturn(0);
34597a03ce2fSLisandro Dalcin }
34607a03ce2fSLisandro Dalcin 
34619b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */
34629b94acceSBarry Smith 
3463bf388a1fSBarry Smith /*MC
3464bf388a1fSBarry Smith     SNESMonitorFunction - functional form passed to SNESMonitorSet() to monitor convergence of nonlinear solver
3465bf388a1fSBarry Smith 
3466bf388a1fSBarry Smith      Synopsis:
3467aaa7dc30SBarry Smith      #include <petscsnes.h>
3468bf388a1fSBarry Smith $    PetscErrorCode SNESMonitorFunction(SNES snes,PetscInt its, PetscReal norm,void *mctx)
3469bf388a1fSBarry Smith 
3470bf388a1fSBarry Smith +    snes - the SNES context
3471bf388a1fSBarry Smith .    its - iteration number
3472bf388a1fSBarry Smith .    norm - 2-norm function value (may be estimated)
3473bf388a1fSBarry Smith -    mctx - [optional] monitoring context
3474bf388a1fSBarry Smith 
3475878cb397SSatish Balay    Level: advanced
3476878cb397SSatish Balay 
3477bf388a1fSBarry Smith .seealso:   SNESMonitorSet(), SNESMonitorGet()
3478bf388a1fSBarry Smith M*/
3479bf388a1fSBarry Smith 
34809b94acceSBarry Smith /*@C
3481a6570f20SBarry Smith    SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
34829b94acceSBarry Smith    iteration of the nonlinear solver to display the iteration's
34839b94acceSBarry Smith    progress.
34849b94acceSBarry Smith 
34853f9fe445SBarry Smith    Logically Collective on SNES
3486fee21e36SBarry Smith 
3487c7afd0dbSLois Curfman McInnes    Input Parameters:
3488c7afd0dbSLois Curfman McInnes +  snes - the SNES context
34896e4dcb14SBarry Smith .  f - the monitor function, see SNESMonitorFunction for the calling sequence
3490b8a78c4aSBarry Smith .  mctx - [optional] user-defined context for private data for the
34910298fd71SBarry Smith           monitor routine (use NULL if no context is desired)
3492b3006f0bSLois Curfman McInnes -  monitordestroy - [optional] routine that frees monitor context
34930298fd71SBarry Smith           (may be NULL)
34949b94acceSBarry Smith 
34959665c990SLois Curfman McInnes    Options Database Keys:
3496a6570f20SBarry Smith +    -snes_monitor        - sets SNESMonitorDefault()
34974619e776SBarry Smith .    -snes_monitor_lg_residualnorm    - sets line graph monitor,
3498a6570f20SBarry Smith                             uses SNESMonitorLGCreate()
3499cca6129bSJed Brown -    -snes_monitor_cancel - cancels all monitors that have
3500c7afd0dbSLois Curfman McInnes                             been hardwired into a code by
3501a6570f20SBarry Smith                             calls to SNESMonitorSet(), but
3502c7afd0dbSLois Curfman McInnes                             does not cancel those set via
3503c7afd0dbSLois Curfman McInnes                             the options database.
35049665c990SLois Curfman McInnes 
3505639f9d9dSBarry Smith    Notes:
35066bc08f3fSLois Curfman McInnes    Several different monitoring routines may be set by calling
3507a6570f20SBarry Smith    SNESMonitorSet() multiple times; all will be called in the
35086bc08f3fSLois Curfman McInnes    order in which they were set.
3509639f9d9dSBarry Smith 
3510025f1a04SBarry Smith    Fortran notes: Only a single monitor function can be set for each SNES object
3511025f1a04SBarry Smith 
351236851e7fSLois Curfman McInnes    Level: intermediate
351336851e7fSLois Curfman McInnes 
35149b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor
35159b94acceSBarry Smith 
3516bf388a1fSBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel(), SNESMonitorFunction
35179b94acceSBarry Smith @*/
35186e4dcb14SBarry Smith PetscErrorCode  SNESMonitorSet(SNES snes,PetscErrorCode (*f)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
35199b94acceSBarry Smith {
3520b90d0a6eSBarry Smith   PetscInt       i;
3521649052a6SBarry Smith   PetscErrorCode ierr;
352278064530SBarry Smith   PetscBool      identical;
3523b90d0a6eSBarry Smith 
35243a40ed3dSBarry Smith   PetscFunctionBegin;
35250700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3526b90d0a6eSBarry Smith   for (i=0; i<snes->numbermonitors;i++) {
352778064530SBarry Smith     ierr = PetscMonitorCompare((PetscErrorCode (*)(void))f,mctx,monitordestroy,(PetscErrorCode (*)(void))snes->monitor[i],snes->monitorcontext[i],snes->monitordestroy[i],&identical);CHKERRQ(ierr);
352878064530SBarry Smith     if (identical) PetscFunctionReturn(0);
3529649052a6SBarry Smith   }
353078064530SBarry Smith   if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
35316e4dcb14SBarry Smith   snes->monitor[snes->numbermonitors]          = f;
3532b8a78c4aSBarry Smith   snes->monitordestroy[snes->numbermonitors]   = monitordestroy;
3533639f9d9dSBarry Smith   snes->monitorcontext[snes->numbermonitors++] = (void*)mctx;
35343a40ed3dSBarry Smith   PetscFunctionReturn(0);
35359b94acceSBarry Smith }
35369b94acceSBarry Smith 
3537a278d85bSSatish Balay /*@
3538a6570f20SBarry Smith    SNESMonitorCancel - Clears all the monitor functions for a SNES object.
35395cd90555SBarry Smith 
35403f9fe445SBarry Smith    Logically Collective on SNES
3541c7afd0dbSLois Curfman McInnes 
35425cd90555SBarry Smith    Input Parameters:
35435cd90555SBarry Smith .  snes - the SNES context
35445cd90555SBarry Smith 
35451a480d89SAdministrator    Options Database Key:
3546a6570f20SBarry Smith .  -snes_monitor_cancel - cancels all monitors that have been hardwired
3547a6570f20SBarry Smith     into a code by calls to SNESMonitorSet(), but does not cancel those
3548c7afd0dbSLois Curfman McInnes     set via the options database
35495cd90555SBarry Smith 
35505cd90555SBarry Smith    Notes:
35515cd90555SBarry Smith    There is no way to clear one specific monitor from a SNES object.
35525cd90555SBarry Smith 
355336851e7fSLois Curfman McInnes    Level: intermediate
355436851e7fSLois Curfman McInnes 
35555cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor
35565cd90555SBarry Smith 
3557a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet()
35585cd90555SBarry Smith @*/
35597087cfbeSBarry Smith PetscErrorCode  SNESMonitorCancel(SNES snes)
35605cd90555SBarry Smith {
3561d952e501SBarry Smith   PetscErrorCode ierr;
3562d952e501SBarry Smith   PetscInt       i;
3563d952e501SBarry Smith 
35645cd90555SBarry Smith   PetscFunctionBegin;
35650700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3566d952e501SBarry Smith   for (i=0; i<snes->numbermonitors; i++) {
3567d952e501SBarry Smith     if (snes->monitordestroy[i]) {
35683c4aec1bSBarry Smith       ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr);
3569d952e501SBarry Smith     }
3570d952e501SBarry Smith   }
35715cd90555SBarry Smith   snes->numbermonitors = 0;
35725cd90555SBarry Smith   PetscFunctionReturn(0);
35735cd90555SBarry Smith }
35745cd90555SBarry Smith 
3575bf388a1fSBarry Smith /*MC
3576bf388a1fSBarry Smith     SNESConvergenceTestFunction - functional form used for testing of convergence of nonlinear solver
3577bf388a1fSBarry Smith 
3578bf388a1fSBarry Smith      Synopsis:
3579aaa7dc30SBarry Smith      #include <petscsnes.h>
3580bf388a1fSBarry Smith $     PetscErrorCode SNESConvergenceTest(SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
3581bf388a1fSBarry Smith 
3582bf388a1fSBarry Smith +    snes - the SNES context
3583bf388a1fSBarry Smith .    it - current iteration (0 is the first and is before any Newton step)
3584bf388a1fSBarry Smith .    cctx - [optional] convergence context
3585bf388a1fSBarry Smith .    reason - reason for convergence/divergence
3586bf388a1fSBarry Smith .    xnorm - 2-norm of current iterate
3587bf388a1fSBarry Smith .    gnorm - 2-norm of current step
3588bf388a1fSBarry Smith -    f - 2-norm of function
3589bf388a1fSBarry Smith 
3590878cb397SSatish Balay    Level: intermediate
3591bf388a1fSBarry Smith 
3592bf388a1fSBarry Smith .seealso:   SNESSetConvergenceTest(), SNESGetConvergenceTest()
3593bf388a1fSBarry Smith M*/
3594bf388a1fSBarry Smith 
35959b94acceSBarry Smith /*@C
35969b94acceSBarry Smith    SNESSetConvergenceTest - Sets the function that is to be used
35979b94acceSBarry Smith    to test for convergence of the nonlinear iterative solution.
35989b94acceSBarry Smith 
35993f9fe445SBarry Smith    Logically Collective on SNES
3600fee21e36SBarry Smith 
3601c7afd0dbSLois Curfman McInnes    Input Parameters:
3602c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3603bf388a1fSBarry Smith .  SNESConvergenceTestFunction - routine to test for convergence
36040298fd71SBarry Smith .  cctx - [optional] context for private data for the convergence routine  (may be NULL)
36050298fd71SBarry Smith -  destroy - [optional] destructor for the context (may be NULL; NULL_FUNCTION in Fortran)
36069b94acceSBarry Smith 
360736851e7fSLois Curfman McInnes    Level: advanced
360836851e7fSLois Curfman McInnes 
36099b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test
36109b94acceSBarry Smith 
3611e2a6519dSDmitry Karpeev .seealso: SNESConvergedDefault(), SNESConvergedSkip(), SNESConvergenceTestFunction
36129b94acceSBarry Smith @*/
3613bf388a1fSBarry Smith PetscErrorCode  SNESSetConvergenceTest(SNES snes,PetscErrorCode (*SNESConvergenceTestFunction)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
36149b94acceSBarry Smith {
36157f7931b9SBarry Smith   PetscErrorCode ierr;
36167f7931b9SBarry Smith 
36173a40ed3dSBarry Smith   PetscFunctionBegin;
36180700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3619e2a6519dSDmitry Karpeev   if (!SNESConvergenceTestFunction) SNESConvergenceTestFunction = SNESConvergedSkip;
36207f7931b9SBarry Smith   if (snes->ops->convergeddestroy) {
36217f7931b9SBarry Smith     ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr);
36227f7931b9SBarry Smith   }
3623bf388a1fSBarry Smith   snes->ops->converged        = SNESConvergenceTestFunction;
36247f7931b9SBarry Smith   snes->ops->convergeddestroy = destroy;
362585385478SLisandro Dalcin   snes->cnvP                  = cctx;
36263a40ed3dSBarry Smith   PetscFunctionReturn(0);
36279b94acceSBarry Smith }
36289b94acceSBarry Smith 
362952baeb72SSatish Balay /*@
3630184914b5SBarry Smith    SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
3631184914b5SBarry Smith 
3632184914b5SBarry Smith    Not Collective
3633184914b5SBarry Smith 
3634184914b5SBarry Smith    Input Parameter:
3635184914b5SBarry Smith .  snes - the SNES context
3636184914b5SBarry Smith 
3637184914b5SBarry Smith    Output Parameter:
36384d0a8057SBarry Smith .  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
3639184914b5SBarry Smith             manual pages for the individual convergence tests for complete lists
3640184914b5SBarry Smith 
36416a4d7782SBarry Smith    Options Database:
36426a4d7782SBarry Smith .   -snes_converged_reason - prints the reason to standard out
36436a4d7782SBarry Smith 
3644184914b5SBarry Smith    Level: intermediate
3645184914b5SBarry Smith 
36466a4d7782SBarry Smith    Notes: Should only be called after the call the SNESSolve() is complete, if it is called earlier it returns the value SNES__CONVERGED_ITERATING.
3647184914b5SBarry Smith 
3648184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test
3649184914b5SBarry Smith 
365033866048SMatthew G. Knepley .seealso: SNESSetConvergenceTest(), SNESSetConvergedReason(), SNESConvergedReason
3651184914b5SBarry Smith @*/
36527087cfbeSBarry Smith PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
3653184914b5SBarry Smith {
3654184914b5SBarry Smith   PetscFunctionBegin;
36550700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
36564482741eSBarry Smith   PetscValidPointer(reason,2);
3657184914b5SBarry Smith   *reason = snes->reason;
3658184914b5SBarry Smith   PetscFunctionReturn(0);
3659184914b5SBarry Smith }
3660184914b5SBarry Smith 
366133866048SMatthew G. Knepley /*@
366233866048SMatthew G. Knepley    SNESSetConvergedReason - Sets the reason the SNES iteration was stopped.
366333866048SMatthew G. Knepley 
366433866048SMatthew G. Knepley    Not Collective
366533866048SMatthew G. Knepley 
366633866048SMatthew G. Knepley    Input Parameters:
366733866048SMatthew G. Knepley +  snes - the SNES context
366833866048SMatthew G. Knepley -  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
366933866048SMatthew G. Knepley             manual pages for the individual convergence tests for complete lists
367033866048SMatthew G. Knepley 
367133866048SMatthew G. Knepley    Level: intermediate
367233866048SMatthew G. Knepley 
367333866048SMatthew G. Knepley .keywords: SNES, nonlinear, set, convergence, test
367433866048SMatthew G. Knepley .seealso: SNESGetConvergedReason(), SNESSetConvergenceTest(), SNESConvergedReason
367533866048SMatthew G. Knepley @*/
367633866048SMatthew G. Knepley PetscErrorCode SNESSetConvergedReason(SNES snes,SNESConvergedReason reason)
367733866048SMatthew G. Knepley {
367833866048SMatthew G. Knepley   PetscFunctionBegin;
367933866048SMatthew G. Knepley   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
368033866048SMatthew G. Knepley   snes->reason = reason;
368133866048SMatthew G. Knepley   PetscFunctionReturn(0);
368233866048SMatthew G. Knepley }
368333866048SMatthew G. Knepley 
3684c9005455SLois Curfman McInnes /*@
3685c9005455SLois Curfman McInnes    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
3686c9005455SLois Curfman McInnes 
36873f9fe445SBarry Smith    Logically Collective on SNES
3688fee21e36SBarry Smith 
3689c7afd0dbSLois Curfman McInnes    Input Parameters:
3690c7afd0dbSLois Curfman McInnes +  snes - iterative context obtained from SNESCreate()
36918c7482ecSBarry Smith .  a   - array to hold history, this array will contain the function norms computed at each step
3692cd5578b5SBarry Smith .  its - integer array holds the number of linear iterations for each solve.
3693758f92a0SBarry Smith .  na  - size of a and its
369464731454SLois Curfman McInnes -  reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
3695758f92a0SBarry Smith            else it continues storing new values for new nonlinear solves after the old ones
3696c7afd0dbSLois Curfman McInnes 
3697308dcc3eSBarry Smith    Notes:
36980298fd71SBarry Smith    If 'a' and 'its' are NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a
3699308dcc3eSBarry Smith    default array of length 10000 is allocated.
3700308dcc3eSBarry Smith 
3701c9005455SLois Curfman McInnes    This routine is useful, e.g., when running a code for purposes
3702c9005455SLois Curfman McInnes    of accurate performance monitoring, when no I/O should be done
3703c9005455SLois Curfman McInnes    during the section of code that is being timed.
3704c9005455SLois Curfman McInnes 
370536851e7fSLois Curfman McInnes    Level: intermediate
370636851e7fSLois Curfman McInnes 
3707c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history
3708758f92a0SBarry Smith 
370908405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory()
3710758f92a0SBarry Smith 
3711c9005455SLois Curfman McInnes @*/
37127087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset)
3713c9005455SLois Curfman McInnes {
3714308dcc3eSBarry Smith   PetscErrorCode ierr;
3715308dcc3eSBarry Smith 
37163a40ed3dSBarry Smith   PetscFunctionBegin;
37170700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
37187a1ec6d4SBarry Smith   if (a) PetscValidScalarPointer(a,2);
3719a562a398SLisandro Dalcin   if (its) PetscValidIntPointer(its,3);
37207a1ec6d4SBarry Smith   if (!a) {
3721308dcc3eSBarry Smith     if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
37227fdeb8b9SBarry Smith     ierr = PetscCalloc1(na,&a);CHKERRQ(ierr);
37237fdeb8b9SBarry Smith     ierr = PetscCalloc1(na,&its);CHKERRQ(ierr);
3724f5af7f23SKarl Rupp 
3725308dcc3eSBarry Smith     snes->conv_malloc = PETSC_TRUE;
3726308dcc3eSBarry Smith   }
3727c9005455SLois Curfman McInnes   snes->conv_hist       = a;
3728758f92a0SBarry Smith   snes->conv_hist_its   = its;
3729758f92a0SBarry Smith   snes->conv_hist_max   = na;
3730a12bc48fSLisandro Dalcin   snes->conv_hist_len   = 0;
3731758f92a0SBarry Smith   snes->conv_hist_reset = reset;
3732758f92a0SBarry Smith   PetscFunctionReturn(0);
3733758f92a0SBarry Smith }
3734758f92a0SBarry Smith 
3735308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3736c6db04a5SJed Brown #include <engine.h>   /* MATLAB include file */
3737c6db04a5SJed Brown #include <mex.h>      /* MATLAB include file */
373899e0435eSBarry Smith 
37398cc058d9SJed Brown PETSC_EXTERN mxArray *SNESGetConvergenceHistoryMatlab(SNES snes)
3740308dcc3eSBarry Smith {
3741308dcc3eSBarry Smith   mxArray   *mat;
3742308dcc3eSBarry Smith   PetscInt  i;
3743308dcc3eSBarry Smith   PetscReal *ar;
3744308dcc3eSBarry Smith 
3745308dcc3eSBarry Smith   PetscFunctionBegin;
3746308dcc3eSBarry Smith   mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL);
3747308dcc3eSBarry Smith   ar  = (PetscReal*) mxGetData(mat);
3748f5af7f23SKarl Rupp   for (i=0; i<snes->conv_hist_len; i++) ar[i] = snes->conv_hist[i];
3749308dcc3eSBarry Smith   PetscFunctionReturn(mat);
3750308dcc3eSBarry Smith }
3751308dcc3eSBarry Smith #endif
3752308dcc3eSBarry Smith 
37530c4c9dddSBarry Smith /*@C
3754758f92a0SBarry Smith    SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
3755758f92a0SBarry Smith 
37563f9fe445SBarry Smith    Not Collective
3757758f92a0SBarry Smith 
3758758f92a0SBarry Smith    Input Parameter:
3759758f92a0SBarry Smith .  snes - iterative context obtained from SNESCreate()
3760758f92a0SBarry Smith 
3761758f92a0SBarry Smith    Output Parameters:
3762758f92a0SBarry Smith .  a   - array to hold history
3763758f92a0SBarry Smith .  its - integer array holds the number of linear iterations (or
3764758f92a0SBarry Smith          negative if not converged) for each solve.
3765758f92a0SBarry Smith -  na  - size of a and its
3766758f92a0SBarry Smith 
3767758f92a0SBarry Smith    Notes:
3768758f92a0SBarry Smith     The calling sequence for this routine in Fortran is
3769758f92a0SBarry Smith $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
3770758f92a0SBarry Smith 
3771758f92a0SBarry Smith    This routine is useful, e.g., when running a code for purposes
3772758f92a0SBarry Smith    of accurate performance monitoring, when no I/O should be done
3773758f92a0SBarry Smith    during the section of code that is being timed.
3774758f92a0SBarry Smith 
3775758f92a0SBarry Smith    Level: intermediate
3776758f92a0SBarry Smith 
3777758f92a0SBarry Smith .keywords: SNES, get, convergence, history
3778758f92a0SBarry Smith 
3779758f92a0SBarry Smith .seealso: SNESSetConvergencHistory()
3780758f92a0SBarry Smith 
3781758f92a0SBarry Smith @*/
37827087cfbeSBarry Smith PetscErrorCode  SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
3783758f92a0SBarry Smith {
3784758f92a0SBarry Smith   PetscFunctionBegin;
37850700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3786758f92a0SBarry Smith   if (a)   *a   = snes->conv_hist;
3787758f92a0SBarry Smith   if (its) *its = snes->conv_hist_its;
3788758f92a0SBarry Smith   if (na)  *na  = snes->conv_hist_len;
37893a40ed3dSBarry Smith   PetscFunctionReturn(0);
3790c9005455SLois Curfman McInnes }
3791c9005455SLois Curfman McInnes 
3792ac226902SBarry Smith /*@C
379376b2cf59SMatthew Knepley   SNESSetUpdate - Sets the general-purpose update function called
3794eec8f646SJed Brown   at the beginning of every iteration of the nonlinear solve. Specifically
37957e4bb74cSBarry Smith   it is called just before the Jacobian is "evaluated".
379676b2cf59SMatthew Knepley 
37973f9fe445SBarry Smith   Logically Collective on SNES
379876b2cf59SMatthew Knepley 
379976b2cf59SMatthew Knepley   Input Parameters:
380076b2cf59SMatthew Knepley . snes - The nonlinear solver context
380176b2cf59SMatthew Knepley . func - The function
380276b2cf59SMatthew Knepley 
380376b2cf59SMatthew Knepley   Calling sequence of func:
3804b5d30489SBarry Smith . func (SNES snes, PetscInt step);
380576b2cf59SMatthew Knepley 
380676b2cf59SMatthew Knepley . step - The current step of the iteration
380776b2cf59SMatthew Knepley 
3808fe97e370SBarry Smith   Level: advanced
3809fe97e370SBarry Smith 
3810fe97e370SBarry 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()
3811fe97e370SBarry Smith         This is not used by most users.
381276b2cf59SMatthew Knepley 
381376b2cf59SMatthew Knepley .keywords: SNES, update
3814b5d30489SBarry Smith 
38158d359177SBarry Smith .seealso SNESSetJacobian(), SNESSolve()
381676b2cf59SMatthew Knepley @*/
38177087cfbeSBarry Smith PetscErrorCode  SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
381876b2cf59SMatthew Knepley {
381976b2cf59SMatthew Knepley   PetscFunctionBegin;
38200700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID,1);
3821e7788613SBarry Smith   snes->ops->update = func;
382276b2cf59SMatthew Knepley   PetscFunctionReturn(0);
382376b2cf59SMatthew Knepley }
382476b2cf59SMatthew Knepley 
38259b94acceSBarry Smith /*
38269b94acceSBarry Smith    SNESScaleStep_Private - Scales a step so that its length is less than the
38279b94acceSBarry Smith    positive parameter delta.
38289b94acceSBarry Smith 
38299b94acceSBarry Smith     Input Parameters:
3830c7afd0dbSLois Curfman McInnes +   snes - the SNES context
38319b94acceSBarry Smith .   y - approximate solution of linear system
38329b94acceSBarry Smith .   fnorm - 2-norm of current function
3833c7afd0dbSLois Curfman McInnes -   delta - trust region size
38349b94acceSBarry Smith 
38359b94acceSBarry Smith     Output Parameters:
3836c7afd0dbSLois Curfman McInnes +   gpnorm - predicted function norm at the new point, assuming local
38379b94acceSBarry Smith     linearization.  The value is zero if the step lies within the trust
38389b94acceSBarry Smith     region, and exceeds zero otherwise.
3839c7afd0dbSLois Curfman McInnes -   ynorm - 2-norm of the step
38409b94acceSBarry Smith 
38419b94acceSBarry Smith     Note:
384204d7464bSBarry Smith     For non-trust region methods such as SNESNEWTONLS, the parameter delta
38439b94acceSBarry Smith     is set to be the maximum allowable step size.
38449b94acceSBarry Smith 
38459b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step
38469b94acceSBarry Smith */
3847dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
38489b94acceSBarry Smith {
3849064f8208SBarry Smith   PetscReal      nrm;
3850ea709b57SSatish Balay   PetscScalar    cnorm;
3851dfbe8321SBarry Smith   PetscErrorCode ierr;
38523a40ed3dSBarry Smith 
38533a40ed3dSBarry Smith   PetscFunctionBegin;
38540700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
38550700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3856c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,2);
3857184914b5SBarry Smith 
3858064f8208SBarry Smith   ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr);
3859064f8208SBarry Smith   if (nrm > *delta) {
3860064f8208SBarry Smith     nrm     = *delta/nrm;
3861064f8208SBarry Smith     *gpnorm = (1.0 - nrm)*(*fnorm);
3862064f8208SBarry Smith     cnorm   = nrm;
38632dcb1b2aSMatthew Knepley     ierr    = VecScale(y,cnorm);CHKERRQ(ierr);
38649b94acceSBarry Smith     *ynorm  = *delta;
38659b94acceSBarry Smith   } else {
38669b94acceSBarry Smith     *gpnorm = 0.0;
3867064f8208SBarry Smith     *ynorm  = nrm;
38689b94acceSBarry Smith   }
38693a40ed3dSBarry Smith   PetscFunctionReturn(0);
38709b94acceSBarry Smith }
38719b94acceSBarry Smith 
38722a359c20SBarry Smith /*@
38732a359c20SBarry Smith    SNESReasonView - Displays the reason a SNES solve converged or diverged to a viewer
38742a359c20SBarry Smith 
38752a359c20SBarry Smith    Collective on SNES
38762a359c20SBarry Smith 
38772a359c20SBarry Smith    Parameter:
38782a359c20SBarry Smith +  snes - iterative context obtained from SNESCreate()
38792a359c20SBarry Smith -  viewer - the viewer to display the reason
38802a359c20SBarry Smith 
38812a359c20SBarry Smith 
38822a359c20SBarry Smith    Options Database Keys:
38832a359c20SBarry Smith .  -snes_converged_reason - print reason for converged or diverged, also prints number of iterations
38842a359c20SBarry Smith 
38852a359c20SBarry Smith    Level: beginner
38862a359c20SBarry Smith 
38872a359c20SBarry Smith .keywords: SNES, solve, linear system
38882a359c20SBarry Smith 
38892a359c20SBarry Smith .seealso: SNESCreate(), SNESSetUp(), SNESDestroy(), SNESSetTolerances(), SNESConvergedDefault()
38902a359c20SBarry Smith 
38912a359c20SBarry Smith @*/
38922a359c20SBarry Smith PetscErrorCode  SNESReasonView(SNES snes,PetscViewer viewer)
38932a359c20SBarry Smith {
38942a359c20SBarry Smith   PetscErrorCode ierr;
38952a359c20SBarry Smith   PetscBool      isAscii;
38962a359c20SBarry Smith 
38972a359c20SBarry Smith   PetscFunctionBegin;
38982a359c20SBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isAscii);CHKERRQ(ierr);
38992a359c20SBarry Smith   if (isAscii) {
39002a359c20SBarry Smith     ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
39012a359c20SBarry Smith     if (snes->reason > 0) {
39022a359c20SBarry Smith       if (((PetscObject) snes)->prefix) {
39032a359c20SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear %s solve converged due to %s iterations %D\n",((PetscObject) snes)->prefix,SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr);
39042a359c20SBarry Smith       } else {
39052a359c20SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear solve converged due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr);
39062a359c20SBarry Smith       }
39072a359c20SBarry Smith     } else {
39082a359c20SBarry Smith       if (((PetscObject) snes)->prefix) {
39092a359c20SBarry 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);
39102a359c20SBarry Smith       } else {
39112a359c20SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear solve did not converge due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr);
39122a359c20SBarry Smith       }
39132a359c20SBarry Smith     }
39142a359c20SBarry Smith     ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
39152a359c20SBarry Smith   }
39162a359c20SBarry Smith   PetscFunctionReturn(0);
39172a359c20SBarry Smith }
39182a359c20SBarry Smith 
39192a359c20SBarry Smith /*@C
39202a359c20SBarry Smith   SNESReasonViewFromOptions - Processes command line options to determine if/how a SNESReason is to be viewed.
39212a359c20SBarry Smith 
39222a359c20SBarry Smith   Collective on SNES
39232a359c20SBarry Smith 
39242a359c20SBarry Smith   Input Parameters:
39252a359c20SBarry Smith . snes   - the SNES object
39262a359c20SBarry Smith 
39272a359c20SBarry Smith   Level: intermediate
39282a359c20SBarry Smith 
39292a359c20SBarry Smith @*/
39302a359c20SBarry Smith PetscErrorCode SNESReasonViewFromOptions(SNES snes)
39312a359c20SBarry Smith {
39322a359c20SBarry Smith   PetscErrorCode    ierr;
39332a359c20SBarry Smith   PetscViewer       viewer;
39342a359c20SBarry Smith   PetscBool         flg;
39352a359c20SBarry Smith   static PetscBool  incall = PETSC_FALSE;
39362a359c20SBarry Smith   PetscViewerFormat format;
39372a359c20SBarry Smith 
39382a359c20SBarry Smith   PetscFunctionBegin;
39392a359c20SBarry Smith   if (incall) PetscFunctionReturn(0);
39402a359c20SBarry Smith   incall = PETSC_TRUE;
39412a359c20SBarry Smith   ierr   = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_converged_reason",&viewer,&format,&flg);CHKERRQ(ierr);
39422a359c20SBarry Smith   if (flg) {
39432a359c20SBarry Smith     ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr);
39442a359c20SBarry Smith     ierr = SNESReasonView(snes,viewer);CHKERRQ(ierr);
39452a359c20SBarry Smith     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
39462a359c20SBarry Smith     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
39472a359c20SBarry Smith   }
39482a359c20SBarry Smith   incall = PETSC_FALSE;
39492a359c20SBarry Smith   PetscFunctionReturn(0);
39502a359c20SBarry Smith }
39512a359c20SBarry Smith 
39526ce558aeSBarry Smith /*@C
3953f69a0ea3SMatthew Knepley    SNESSolve - Solves a nonlinear system F(x) = b.
3954f69a0ea3SMatthew Knepley    Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
39559b94acceSBarry Smith 
3956c7afd0dbSLois Curfman McInnes    Collective on SNES
3957c7afd0dbSLois Curfman McInnes 
3958b2002411SLois Curfman McInnes    Input Parameters:
3959c7afd0dbSLois Curfman McInnes +  snes - the SNES context
39600298fd71SBarry Smith .  b - the constant part of the equation F(x) = b, or NULL to use zero.
396185385478SLisandro Dalcin -  x - the solution vector.
39629b94acceSBarry Smith 
3963b2002411SLois Curfman McInnes    Notes:
39648ddd3da0SLois Curfman McInnes    The user should initialize the vector,x, with the initial guess
39658ddd3da0SLois Curfman McInnes    for the nonlinear solve prior to calling SNESSolve.  In particular,
39668ddd3da0SLois Curfman McInnes    to employ an initial guess of zero, the user should explicitly set
39678ddd3da0SLois Curfman McInnes    this vector to zero by calling VecSet().
39688ddd3da0SLois Curfman McInnes 
396936851e7fSLois Curfman McInnes    Level: beginner
397036851e7fSLois Curfman McInnes 
39719b94acceSBarry Smith .keywords: SNES, nonlinear, solve
39729b94acceSBarry Smith 
3973c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution()
39749b94acceSBarry Smith @*/
39757087cfbeSBarry Smith PetscErrorCode  SNESSolve(SNES snes,Vec b,Vec x)
39769b94acceSBarry Smith {
3977dfbe8321SBarry Smith   PetscErrorCode    ierr;
3978ace3abfcSBarry Smith   PetscBool         flg;
3979efd51863SBarry Smith   PetscInt          grid;
39800298fd71SBarry Smith   Vec               xcreated = NULL;
3981caa4e7f2SJed Brown   DM                dm;
3982052efed2SBarry Smith 
39833a40ed3dSBarry Smith   PetscFunctionBegin;
39840700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3985a69afd8bSBarry Smith   if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3986a69afd8bSBarry Smith   if (x) PetscCheckSameComm(snes,1,x,3);
39870700a824SBarry Smith   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2);
398885385478SLisandro Dalcin   if (b) PetscCheckSameComm(snes,1,b,2);
398985385478SLisandro Dalcin 
3990caa4e7f2SJed Brown   if (!x) {
3991caa4e7f2SJed Brown     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3992caa4e7f2SJed Brown     ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr);
3993a69afd8bSBarry Smith     x    = xcreated;
3994a69afd8bSBarry Smith   }
3995ce1779c8SBarry Smith   ierr = SNESViewFromOptions(snes,NULL,"-snes_view_pre");CHKERRQ(ierr);
3996f05ece33SBarry Smith 
3997ce94432eSBarry Smith   for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)));CHKERRQ(ierr);}
3998efd51863SBarry Smith   for (grid=0; grid<snes->gridsequence+1; grid++) {
3999efd51863SBarry Smith 
400085385478SLisandro Dalcin     /* set solution vector */
4001efd51863SBarry Smith     if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);}
40026bf464f9SBarry Smith     ierr          = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
400385385478SLisandro Dalcin     snes->vec_sol = x;
4004caa4e7f2SJed Brown     ierr          = SNESGetDM(snes,&dm);CHKERRQ(ierr);
4005caa4e7f2SJed Brown 
4006caa4e7f2SJed Brown     /* set affine vector if provided */
400785385478SLisandro Dalcin     if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); }
40086bf464f9SBarry Smith     ierr          = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
400985385478SLisandro Dalcin     snes->vec_rhs = b;
401085385478SLisandro Dalcin 
4011154060b5SMatthew G. Knepley     if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
4012154060b5SMatthew 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");
4013154060b5SMatthew G. Knepley     if (!snes->vec_sol_update /* && snes->vec_sol */) {
4014154060b5SMatthew G. Knepley       ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr);
4015154060b5SMatthew G. Knepley       ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->vec_sol_update);CHKERRQ(ierr);
4016154060b5SMatthew G. Knepley     }
4017154060b5SMatthew G. Knepley     ierr = DMShellSetGlobalVector(dm,snes->vec_sol);CHKERRQ(ierr);
401870e92668SMatthew Knepley     ierr = SNESSetUp(snes);CHKERRQ(ierr);
40193f149594SLisandro Dalcin 
40207eee914bSBarry Smith     if (!grid) {
40217eee914bSBarry Smith       if (snes->ops->computeinitialguess) {
4022d25893d9SBarry Smith         ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr);
4023d25893d9SBarry Smith       }
4024dd568438SSatish Balay     }
4025d25893d9SBarry Smith 
4026abc0a331SBarry Smith     if (snes->conv_hist_reset) snes->conv_hist_len = 0;
4027971e163fSPeter Brune     if (snes->counters_reset) {snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;}
4028d5e45103SBarry Smith 
40293f149594SLisandro Dalcin     ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
40304936397dSBarry Smith     ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr);
403185385478SLisandro Dalcin     ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
403217186662SBarry Smith     if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
4033422a814eSBarry Smith     snes->domainerror = PETSC_FALSE; /* clear the flag if it has been set */
40343f149594SLisandro Dalcin 
403537ec4e1aSPeter Brune     if (snes->lagjac_persist) snes->jac_iter += snes->iter;
403637ec4e1aSPeter Brune     if (snes->lagpre_persist) snes->pre_iter += snes->iter;
403737ec4e1aSPeter Brune 
403827b0f280SBarry Smith     ierr   = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_test_local_min",NULL,NULL,&flg);CHKERRQ(ierr);
4039da9b6338SBarry Smith     if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); }
40402a359c20SBarry Smith     ierr = SNESReasonViewFromOptions(snes);CHKERRQ(ierr);
40415968eb51SBarry Smith 
4042ce94432eSBarry Smith     if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged");
40439c8e83a9SBarry Smith     if (snes->reason < 0) break;
4044efd51863SBarry Smith     if (grid <  snes->gridsequence) {
4045efd51863SBarry Smith       DM  fine;
4046efd51863SBarry Smith       Vec xnew;
4047efd51863SBarry Smith       Mat interp;
4048efd51863SBarry Smith 
4049ce94432eSBarry Smith       ierr = DMRefine(snes->dm,PetscObjectComm((PetscObject)snes),&fine);CHKERRQ(ierr);
4050ce94432eSBarry Smith       if (!fine) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing");
40510298fd71SBarry Smith       ierr = DMCreateInterpolation(snes->dm,fine,&interp,NULL);CHKERRQ(ierr);
4052efd51863SBarry Smith       ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr);
4053efd51863SBarry Smith       ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr);
4054c833c3b5SJed Brown       ierr = DMInterpolate(snes->dm,interp,fine);CHKERRQ(ierr);
4055efd51863SBarry Smith       ierr = MatDestroy(&interp);CHKERRQ(ierr);
4056efd51863SBarry Smith       x    = xnew;
4057efd51863SBarry Smith 
4058efd51863SBarry Smith       ierr = SNESReset(snes);CHKERRQ(ierr);
4059efd51863SBarry Smith       ierr = SNESSetDM(snes,fine);CHKERRQ(ierr);
4060efd51863SBarry Smith       ierr = DMDestroy(&fine);CHKERRQ(ierr);
4061ce94432eSBarry Smith       ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)));CHKERRQ(ierr);
4062efd51863SBarry Smith     }
4063efd51863SBarry Smith   }
4064ce1779c8SBarry Smith   ierr = SNESViewFromOptions(snes,NULL,"-snes_view");CHKERRQ(ierr);
4065685405a1SBarry Smith   ierr = VecViewFromOptions(snes->vec_sol,(PetscObject)snes,"-snes_view_solution");CHKERRQ(ierr);
40663f7e2da0SPeter Brune 
4067a69afd8bSBarry Smith   ierr = VecDestroy(&xcreated);CHKERRQ(ierr);
4068e04113cfSBarry Smith   ierr = PetscObjectSAWsBlock((PetscObject)snes);CHKERRQ(ierr);
40693a40ed3dSBarry Smith   PetscFunctionReturn(0);
40709b94acceSBarry Smith }
40719b94acceSBarry Smith 
40729b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */
40739b94acceSBarry Smith 
407482bf6240SBarry Smith /*@C
40754b0e389bSBarry Smith    SNESSetType - Sets the method for the nonlinear solver.
40769b94acceSBarry Smith 
4077fee21e36SBarry Smith    Collective on SNES
4078fee21e36SBarry Smith 
4079c7afd0dbSLois Curfman McInnes    Input Parameters:
4080c7afd0dbSLois Curfman McInnes +  snes - the SNES context
4081454a90a3SBarry Smith -  type - a known method
4082c7afd0dbSLois Curfman McInnes 
4083c7afd0dbSLois Curfman McInnes    Options Database Key:
4084454a90a3SBarry Smith .  -snes_type <type> - Sets the method; use -help for a list
408504d7464bSBarry Smith    of available methods (for instance, newtonls or newtontr)
4086ae12b187SLois Curfman McInnes 
40879b94acceSBarry Smith    Notes:
4088e090d566SSatish Balay    See "petsc/include/petscsnes.h" for available methods (for instance)
408904d7464bSBarry Smith +    SNESNEWTONLS - Newton's method with line search
4090c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
409104d7464bSBarry Smith .    SNESNEWTONTR - Newton's method with trust region
4092c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
40939b94acceSBarry Smith 
4094ae12b187SLois Curfman McInnes   Normally, it is best to use the SNESSetFromOptions() command and then
4095ae12b187SLois Curfman McInnes   set the SNES solver type from the options database rather than by using
4096ae12b187SLois Curfman McInnes   this routine.  Using the options database provides the user with
4097ae12b187SLois Curfman McInnes   maximum flexibility in evaluating the many nonlinear solvers.
4098ae12b187SLois Curfman McInnes   The SNESSetType() routine is provided for those situations where it
4099ae12b187SLois Curfman McInnes   is necessary to set the nonlinear solver independently of the command
4100ae12b187SLois Curfman McInnes   line or options database.  This might be the case, for example, when
4101ae12b187SLois Curfman McInnes   the choice of solver changes during the execution of the program,
4102ae12b187SLois Curfman McInnes   and the user's application is taking responsibility for choosing the
4103b0a32e0cSBarry Smith   appropriate method.
410436851e7fSLois Curfman McInnes 
41058f6c3df8SBarry Smith     Developer Notes: SNESRegister() adds a constructor for a new SNESType to SNESList, SNESSetType() locates
41068f6c3df8SBarry Smith     the constructor in that list and calls it to create the spexific object.
41078f6c3df8SBarry Smith 
410836851e7fSLois Curfman McInnes   Level: intermediate
4109a703fe33SLois Curfman McInnes 
4110454a90a3SBarry Smith .keywords: SNES, set, type
4111435da068SBarry Smith 
41128f6c3df8SBarry Smith .seealso: SNESType, SNESCreate(), SNESDestroy(), SNESGetType(), SNESSetFromOptions()
4113435da068SBarry Smith 
41149b94acceSBarry Smith @*/
411519fd82e9SBarry Smith PetscErrorCode  SNESSetType(SNES snes,SNESType type)
41169b94acceSBarry Smith {
4117dfbe8321SBarry Smith   PetscErrorCode ierr,(*r)(SNES);
4118ace3abfcSBarry Smith   PetscBool      match;
41193a40ed3dSBarry Smith 
41203a40ed3dSBarry Smith   PetscFunctionBegin;
41210700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
41224482741eSBarry Smith   PetscValidCharPointer(type,2);
412382bf6240SBarry Smith 
4124251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr);
41250f5bd95cSBarry Smith   if (match) PetscFunctionReturn(0);
412692ff6ae8SBarry Smith 
41271c9cd337SJed Brown   ierr =  PetscFunctionListFind(SNESList,type,&r);CHKERRQ(ierr);
4128e32f2f54SBarry Smith   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
412975396ef9SLisandro Dalcin   /* Destroy the previous private SNES context */
4130b5c23020SJed Brown   if (snes->ops->destroy) {
4131b5c23020SJed Brown     ierr               = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr);
41320298fd71SBarry Smith     snes->ops->destroy = NULL;
4133b5c23020SJed Brown   }
413475396ef9SLisandro Dalcin   /* Reinitialize function pointers in SNESOps structure */
413575396ef9SLisandro Dalcin   snes->ops->setup          = 0;
413675396ef9SLisandro Dalcin   snes->ops->solve          = 0;
413775396ef9SLisandro Dalcin   snes->ops->view           = 0;
413875396ef9SLisandro Dalcin   snes->ops->setfromoptions = 0;
413975396ef9SLisandro Dalcin   snes->ops->destroy        = 0;
414075396ef9SLisandro Dalcin   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
414175396ef9SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
4142f5af7f23SKarl Rupp 
4143454a90a3SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr);
414403bfa161SLisandro Dalcin   ierr = (*r)(snes);CHKERRQ(ierr);
41453a40ed3dSBarry Smith   PetscFunctionReturn(0);
41469b94acceSBarry Smith }
41479b94acceSBarry Smith 
41489b94acceSBarry Smith /*@C
41499a28b0a6SLois Curfman McInnes    SNESGetType - Gets the SNES method type and name (as a string).
41509b94acceSBarry Smith 
4151c7afd0dbSLois Curfman McInnes    Not Collective
4152c7afd0dbSLois Curfman McInnes 
41539b94acceSBarry Smith    Input Parameter:
41544b0e389bSBarry Smith .  snes - nonlinear solver context
41559b94acceSBarry Smith 
41569b94acceSBarry Smith    Output Parameter:
41573a7fca6bSBarry Smith .  type - SNES method (a character string)
41589b94acceSBarry Smith 
415936851e7fSLois Curfman McInnes    Level: intermediate
416036851e7fSLois Curfman McInnes 
4161454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name
41629b94acceSBarry Smith @*/
416319fd82e9SBarry Smith PetscErrorCode  SNESGetType(SNES snes,SNESType *type)
41649b94acceSBarry Smith {
41653a40ed3dSBarry Smith   PetscFunctionBegin;
41660700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
41674482741eSBarry Smith   PetscValidPointer(type,2);
41687adad957SLisandro Dalcin   *type = ((PetscObject)snes)->type_name;
41693a40ed3dSBarry Smith   PetscFunctionReturn(0);
41709b94acceSBarry Smith }
41719b94acceSBarry Smith 
41723cd8a7caSMatthew G. Knepley /*@
41733cd8a7caSMatthew G. Knepley   SNESSetSolution - Sets the solution vector for use by the SNES routines.
41743cd8a7caSMatthew G. Knepley 
41753cd8a7caSMatthew G. Knepley   Logically Collective on SNES and Vec
41763cd8a7caSMatthew G. Knepley 
41773cd8a7caSMatthew G. Knepley   Input Parameters:
41783cd8a7caSMatthew G. Knepley + snes - the SNES context obtained from SNESCreate()
41793cd8a7caSMatthew G. Knepley - u    - the solution vector
41803cd8a7caSMatthew G. Knepley 
41813cd8a7caSMatthew G. Knepley   Level: beginner
41823cd8a7caSMatthew G. Knepley 
41833cd8a7caSMatthew G. Knepley .keywords: SNES, set, solution
41843cd8a7caSMatthew G. Knepley @*/
41853cd8a7caSMatthew G. Knepley PetscErrorCode SNESSetSolution(SNES snes, Vec u)
41863cd8a7caSMatthew G. Knepley {
41873cd8a7caSMatthew G. Knepley   DM             dm;
41883cd8a7caSMatthew G. Knepley   PetscErrorCode ierr;
41893cd8a7caSMatthew G. Knepley 
41903cd8a7caSMatthew G. Knepley   PetscFunctionBegin;
41913cd8a7caSMatthew G. Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
41923cd8a7caSMatthew G. Knepley   PetscValidHeaderSpecific(u, VEC_CLASSID, 2);
41933cd8a7caSMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) u);CHKERRQ(ierr);
41943cd8a7caSMatthew G. Knepley   ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
41953cd8a7caSMatthew G. Knepley 
41963cd8a7caSMatthew G. Knepley   snes->vec_sol = u;
41973cd8a7caSMatthew G. Knepley 
41983cd8a7caSMatthew G. Knepley   ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr);
41993cd8a7caSMatthew G. Knepley   ierr = DMShellSetGlobalVector(dm, u);CHKERRQ(ierr);
42003cd8a7caSMatthew G. Knepley   PetscFunctionReturn(0);
42013cd8a7caSMatthew G. Knepley }
42023cd8a7caSMatthew G. Knepley 
420352baeb72SSatish Balay /*@
42049b94acceSBarry Smith    SNESGetSolution - Returns the vector where the approximate solution is
4205c0df2a02SJed Brown    stored. This is the fine grid solution when using SNESSetGridSequence().
42069b94acceSBarry Smith 
4207c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
4208c7afd0dbSLois Curfman McInnes 
42099b94acceSBarry Smith    Input Parameter:
42109b94acceSBarry Smith .  snes - the SNES context
42119b94acceSBarry Smith 
42129b94acceSBarry Smith    Output Parameter:
42139b94acceSBarry Smith .  x - the solution
42149b94acceSBarry Smith 
421570e92668SMatthew Knepley    Level: intermediate
421636851e7fSLois Curfman McInnes 
42179b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution
42189b94acceSBarry Smith 
421985385478SLisandro Dalcin .seealso:  SNESGetSolutionUpdate(), SNESGetFunction()
42209b94acceSBarry Smith @*/
42217087cfbeSBarry Smith PetscErrorCode  SNESGetSolution(SNES snes,Vec *x)
42229b94acceSBarry Smith {
42233a40ed3dSBarry Smith   PetscFunctionBegin;
42240700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
42254482741eSBarry Smith   PetscValidPointer(x,2);
422685385478SLisandro Dalcin   *x = snes->vec_sol;
422770e92668SMatthew Knepley   PetscFunctionReturn(0);
422870e92668SMatthew Knepley }
422970e92668SMatthew Knepley 
423052baeb72SSatish Balay /*@
42319b94acceSBarry Smith    SNESGetSolutionUpdate - Returns the vector where the solution update is
42329b94acceSBarry Smith    stored.
42339b94acceSBarry Smith 
4234c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
4235c7afd0dbSLois Curfman McInnes 
42369b94acceSBarry Smith    Input Parameter:
42379b94acceSBarry Smith .  snes - the SNES context
42389b94acceSBarry Smith 
42399b94acceSBarry Smith    Output Parameter:
42409b94acceSBarry Smith .  x - the solution update
42419b94acceSBarry Smith 
424236851e7fSLois Curfman McInnes    Level: advanced
424336851e7fSLois Curfman McInnes 
42449b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update
42459b94acceSBarry Smith 
424685385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction()
42479b94acceSBarry Smith @*/
42487087cfbeSBarry Smith PetscErrorCode  SNESGetSolutionUpdate(SNES snes,Vec *x)
42499b94acceSBarry Smith {
42503a40ed3dSBarry Smith   PetscFunctionBegin;
42510700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
42524482741eSBarry Smith   PetscValidPointer(x,2);
425385385478SLisandro Dalcin   *x = snes->vec_sol_update;
42543a40ed3dSBarry Smith   PetscFunctionReturn(0);
42559b94acceSBarry Smith }
42569b94acceSBarry Smith 
42579b94acceSBarry Smith /*@C
42583638b69dSLois Curfman McInnes    SNESGetFunction - Returns the vector where the function is stored.
42599b94acceSBarry Smith 
4260a63bb30eSJed Brown    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
4261c7afd0dbSLois Curfman McInnes 
42629b94acceSBarry Smith    Input Parameter:
42639b94acceSBarry Smith .  snes - the SNES context
42649b94acceSBarry Smith 
42659b94acceSBarry Smith    Output Parameter:
42660298fd71SBarry Smith +  r - the vector that is used to store residuals (or NULL if you don't want it)
4267f8b49ee9SBarry Smith .  f - the function (or NULL if you don't want it); see SNESFunction for calling sequence details
42680298fd71SBarry Smith -  ctx - the function context (or NULL if you don't want it)
42699b94acceSBarry Smith 
427036851e7fSLois Curfman McInnes    Level: advanced
427136851e7fSLois Curfman McInnes 
4272a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function
42739b94acceSBarry Smith 
4274bf388a1fSBarry Smith .seealso: SNESSetFunction(), SNESGetSolution(), SNESFunction
42759b94acceSBarry Smith @*/
4276f8b49ee9SBarry Smith PetscErrorCode  SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**f)(SNES,Vec,Vec,void*),void **ctx)
42779b94acceSBarry Smith {
4278a63bb30eSJed Brown   PetscErrorCode ierr;
42796cab3a1bSJed Brown   DM             dm;
4280a63bb30eSJed Brown 
42813a40ed3dSBarry Smith   PetscFunctionBegin;
42820700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4283a63bb30eSJed Brown   if (r) {
4284a63bb30eSJed Brown     if (!snes->vec_func) {
4285a63bb30eSJed Brown       if (snes->vec_rhs) {
4286a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr);
4287a63bb30eSJed Brown       } else if (snes->vec_sol) {
4288a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr);
4289a63bb30eSJed Brown       } else if (snes->dm) {
4290a63bb30eSJed Brown         ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr);
4291a63bb30eSJed Brown       }
4292a63bb30eSJed Brown     }
4293a63bb30eSJed Brown     *r = snes->vec_func;
4294a63bb30eSJed Brown   }
42956cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
4296f8b49ee9SBarry Smith   ierr = DMSNESGetFunction(dm,f,ctx);CHKERRQ(ierr);
42973a40ed3dSBarry Smith   PetscFunctionReturn(0);
42989b94acceSBarry Smith }
42999b94acceSBarry Smith 
4300c79ef259SPeter Brune /*@C
4301be95d8f1SBarry Smith    SNESGetNGS - Returns the NGS function and context.
4302c79ef259SPeter Brune 
4303c79ef259SPeter Brune    Input Parameter:
4304c79ef259SPeter Brune .  snes - the SNES context
4305c79ef259SPeter Brune 
4306c79ef259SPeter Brune    Output Parameter:
4307be95d8f1SBarry Smith +  f - the function (or NULL) see SNESNGSFunction for details
43080298fd71SBarry Smith -  ctx    - the function context (or NULL)
4309c79ef259SPeter Brune 
4310c79ef259SPeter Brune    Level: advanced
4311c79ef259SPeter Brune 
4312c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function
4313c79ef259SPeter Brune 
4314be95d8f1SBarry Smith .seealso: SNESSetNGS(), SNESGetFunction()
4315c79ef259SPeter Brune @*/
4316c79ef259SPeter Brune 
4317be95d8f1SBarry Smith PetscErrorCode SNESGetNGS (SNES snes, PetscErrorCode (**f)(SNES, Vec, Vec, void*), void ** ctx)
4318646217ecSPeter Brune {
43196cab3a1bSJed Brown   PetscErrorCode ierr;
43206cab3a1bSJed Brown   DM             dm;
43216cab3a1bSJed Brown 
4322646217ecSPeter Brune   PetscFunctionBegin;
4323646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
43246cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
4325be95d8f1SBarry Smith   ierr = DMSNESGetNGS(dm,f,ctx);CHKERRQ(ierr);
4326646217ecSPeter Brune   PetscFunctionReturn(0);
4327646217ecSPeter Brune }
4328646217ecSPeter Brune 
43293c7409f5SSatish Balay /*@C
43303c7409f5SSatish Balay    SNESSetOptionsPrefix - Sets the prefix used for searching for all
4331d850072dSLois Curfman McInnes    SNES options in the database.
43323c7409f5SSatish Balay 
43333f9fe445SBarry Smith    Logically Collective on SNES
4334fee21e36SBarry Smith 
4335c7afd0dbSLois Curfman McInnes    Input Parameter:
4336c7afd0dbSLois Curfman McInnes +  snes - the SNES context
4337c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
4338c7afd0dbSLois Curfman McInnes 
4339d850072dSLois Curfman McInnes    Notes:
4340a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
4341c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
4342d850072dSLois Curfman McInnes 
434336851e7fSLois Curfman McInnes    Level: advanced
434436851e7fSLois Curfman McInnes 
43453c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database
4346a86d99e1SLois Curfman McInnes 
4347a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions()
43483c7409f5SSatish Balay @*/
43497087cfbeSBarry Smith PetscErrorCode  SNESSetOptionsPrefix(SNES snes,const char prefix[])
43503c7409f5SSatish Balay {
4351dfbe8321SBarry Smith   PetscErrorCode ierr;
43523c7409f5SSatish Balay 
43533a40ed3dSBarry Smith   PetscFunctionBegin;
43540700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4355639f9d9dSBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
43561cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
435735f5d045SPeter Brune   if (snes->linesearch) {
43587601faf0SJed Brown     ierr = SNESGetLineSearch(snes,&snes->linesearch);CHKERRQ(ierr);
435908b6c495SPeter Brune     ierr = PetscObjectSetOptionsPrefix((PetscObject)snes->linesearch,prefix);CHKERRQ(ierr);
436035f5d045SPeter Brune   }
436135f5d045SPeter Brune   ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
43623a40ed3dSBarry Smith   PetscFunctionReturn(0);
43633c7409f5SSatish Balay }
43643c7409f5SSatish Balay 
43653c7409f5SSatish Balay /*@C
4366f525115eSLois Curfman McInnes    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
4367d850072dSLois Curfman McInnes    SNES options in the database.
43683c7409f5SSatish Balay 
43693f9fe445SBarry Smith    Logically Collective on SNES
4370fee21e36SBarry Smith 
4371c7afd0dbSLois Curfman McInnes    Input Parameters:
4372c7afd0dbSLois Curfman McInnes +  snes - the SNES context
4373c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
4374c7afd0dbSLois Curfman McInnes 
4375d850072dSLois Curfman McInnes    Notes:
4376a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
4377c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
4378d850072dSLois Curfman McInnes 
437936851e7fSLois Curfman McInnes    Level: advanced
438036851e7fSLois Curfman McInnes 
43813c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database
4382a86d99e1SLois Curfman McInnes 
4383a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix()
43843c7409f5SSatish Balay @*/
43857087cfbeSBarry Smith PetscErrorCode  SNESAppendOptionsPrefix(SNES snes,const char prefix[])
43863c7409f5SSatish Balay {
4387dfbe8321SBarry Smith   PetscErrorCode ierr;
43883c7409f5SSatish Balay 
43893a40ed3dSBarry Smith   PetscFunctionBegin;
43900700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4391639f9d9dSBarry Smith   ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
43921cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
439335f5d045SPeter Brune   if (snes->linesearch) {
43947601faf0SJed Brown     ierr = SNESGetLineSearch(snes,&snes->linesearch);CHKERRQ(ierr);
439508b6c495SPeter Brune     ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes->linesearch,prefix);CHKERRQ(ierr);
439635f5d045SPeter Brune   }
439735f5d045SPeter Brune   ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
43983a40ed3dSBarry Smith   PetscFunctionReturn(0);
43993c7409f5SSatish Balay }
44003c7409f5SSatish Balay 
44019ab63eb5SSatish Balay /*@C
44023c7409f5SSatish Balay    SNESGetOptionsPrefix - Sets the prefix used for searching for all
44033c7409f5SSatish Balay    SNES options in the database.
44043c7409f5SSatish Balay 
4405c7afd0dbSLois Curfman McInnes    Not Collective
4406c7afd0dbSLois Curfman McInnes 
44073c7409f5SSatish Balay    Input Parameter:
44083c7409f5SSatish Balay .  snes - the SNES context
44093c7409f5SSatish Balay 
44103c7409f5SSatish Balay    Output Parameter:
44113c7409f5SSatish Balay .  prefix - pointer to the prefix string used
44123c7409f5SSatish Balay 
44134ef407dbSRichard Tran Mills    Notes: On the fortran side, the user should pass in a string 'prefix' of
44149ab63eb5SSatish Balay    sufficient length to hold the prefix.
44159ab63eb5SSatish Balay 
441636851e7fSLois Curfman McInnes    Level: advanced
441736851e7fSLois Curfman McInnes 
44183c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database
4419a86d99e1SLois Curfman McInnes 
4420a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix()
44213c7409f5SSatish Balay @*/
44227087cfbeSBarry Smith PetscErrorCode  SNESGetOptionsPrefix(SNES snes,const char *prefix[])
44233c7409f5SSatish Balay {
4424dfbe8321SBarry Smith   PetscErrorCode ierr;
44253c7409f5SSatish Balay 
44263a40ed3dSBarry Smith   PetscFunctionBegin;
44270700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4428639f9d9dSBarry Smith   ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
44293a40ed3dSBarry Smith   PetscFunctionReturn(0);
44303c7409f5SSatish Balay }
44313c7409f5SSatish Balay 
4432b2002411SLois Curfman McInnes 
44333cea93caSBarry Smith /*@C
44341c84c290SBarry Smith   SNESRegister - Adds a method to the nonlinear solver package.
44351c84c290SBarry Smith 
44361c84c290SBarry Smith    Not collective
44371c84c290SBarry Smith 
44381c84c290SBarry Smith    Input Parameters:
44391c84c290SBarry Smith +  name_solver - name of a new user-defined solver
44401c84c290SBarry Smith -  routine_create - routine to create method context
44411c84c290SBarry Smith 
44421c84c290SBarry Smith    Notes:
44431c84c290SBarry Smith    SNESRegister() may be called multiple times to add several user-defined solvers.
44441c84c290SBarry Smith 
44451c84c290SBarry Smith    Sample usage:
44461c84c290SBarry Smith .vb
4447bdf89e91SBarry Smith    SNESRegister("my_solver",MySolverCreate);
44481c84c290SBarry Smith .ve
44491c84c290SBarry Smith 
44501c84c290SBarry Smith    Then, your solver can be chosen with the procedural interface via
44511c84c290SBarry Smith $     SNESSetType(snes,"my_solver")
44521c84c290SBarry Smith    or at runtime via the option
44531c84c290SBarry Smith $     -snes_type my_solver
44541c84c290SBarry Smith 
44551c84c290SBarry Smith    Level: advanced
44561c84c290SBarry Smith 
44571c84c290SBarry Smith     Note: If your function is not being put into a shared library then use SNESRegister() instead
44581c84c290SBarry Smith 
44591c84c290SBarry Smith .keywords: SNES, nonlinear, register
44601c84c290SBarry Smith 
44611c84c290SBarry Smith .seealso: SNESRegisterAll(), SNESRegisterDestroy()
44623cea93caSBarry Smith 
44637f6c08e0SMatthew Knepley   Level: advanced
44643cea93caSBarry Smith @*/
4465bdf89e91SBarry Smith PetscErrorCode  SNESRegister(const char sname[],PetscErrorCode (*function)(SNES))
4466b2002411SLois Curfman McInnes {
4467dfbe8321SBarry Smith   PetscErrorCode ierr;
4468b2002411SLois Curfman McInnes 
4469b2002411SLois Curfman McInnes   PetscFunctionBegin;
4470a240a19fSJed Brown   ierr = PetscFunctionListAdd(&SNESList,sname,function);CHKERRQ(ierr);
4471b2002411SLois Curfman McInnes   PetscFunctionReturn(0);
4472b2002411SLois Curfman McInnes }
4473da9b6338SBarry Smith 
44747087cfbeSBarry Smith PetscErrorCode  SNESTestLocalMin(SNES snes)
4475da9b6338SBarry Smith {
4476dfbe8321SBarry Smith   PetscErrorCode ierr;
447777431f27SBarry Smith   PetscInt       N,i,j;
4478da9b6338SBarry Smith   Vec            u,uh,fh;
4479da9b6338SBarry Smith   PetscScalar    value;
4480da9b6338SBarry Smith   PetscReal      norm;
4481da9b6338SBarry Smith 
4482da9b6338SBarry Smith   PetscFunctionBegin;
4483da9b6338SBarry Smith   ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr);
4484da9b6338SBarry Smith   ierr = VecDuplicate(u,&uh);CHKERRQ(ierr);
4485da9b6338SBarry Smith   ierr = VecDuplicate(u,&fh);CHKERRQ(ierr);
4486da9b6338SBarry Smith 
4487da9b6338SBarry Smith   /* currently only works for sequential */
448822d28d08SBarry Smith   ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");CHKERRQ(ierr);
4489da9b6338SBarry Smith   ierr = VecGetSize(u,&N);CHKERRQ(ierr);
4490da9b6338SBarry Smith   for (i=0; i<N; i++) {
4491da9b6338SBarry Smith     ierr = VecCopy(u,uh);CHKERRQ(ierr);
449277431f27SBarry Smith     ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr);
4493da9b6338SBarry Smith     for (j=-10; j<11; j++) {
44948b49ba18SBarry Smith       value = PetscSign(j)*PetscExpReal(PetscAbs(j)-10.0);
4495da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
44963ab0aad5SBarry Smith       ierr  = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr);
4497da9b6338SBarry Smith       ierr  = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr);
449877431f27SBarry Smith       ierr  = PetscPrintf(PETSC_COMM_WORLD,"       j norm %D %18.16e\n",j,norm);CHKERRQ(ierr);
4499da9b6338SBarry Smith       value = -value;
4500da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
4501da9b6338SBarry Smith     }
4502da9b6338SBarry Smith   }
45036bf464f9SBarry Smith   ierr = VecDestroy(&uh);CHKERRQ(ierr);
45046bf464f9SBarry Smith   ierr = VecDestroy(&fh);CHKERRQ(ierr);
4505da9b6338SBarry Smith   PetscFunctionReturn(0);
4506da9b6338SBarry Smith }
450771f87433Sdalcinl 
450871f87433Sdalcinl /*@
4509fa9f3622SBarry Smith    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
451071f87433Sdalcinl    computing relative tolerance for linear solvers within an inexact
451171f87433Sdalcinl    Newton method.
451271f87433Sdalcinl 
45133f9fe445SBarry Smith    Logically Collective on SNES
451471f87433Sdalcinl 
451571f87433Sdalcinl    Input Parameters:
451671f87433Sdalcinl +  snes - SNES context
451771f87433Sdalcinl -  flag - PETSC_TRUE or PETSC_FALSE
451871f87433Sdalcinl 
451964ba62caSBarry Smith     Options Database:
452064ba62caSBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
452164ba62caSBarry Smith .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
452264ba62caSBarry Smith .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
452364ba62caSBarry Smith .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
452464ba62caSBarry Smith .  -snes_ksp_ew_gamma <gamma> - Sets gamma
452564ba62caSBarry Smith .  -snes_ksp_ew_alpha <alpha> - Sets alpha
452664ba62caSBarry Smith .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
452764ba62caSBarry Smith -  -snes_ksp_ew_threshold <threshold> - Sets threshold
452864ba62caSBarry Smith 
452971f87433Sdalcinl    Notes:
453071f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
453171f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
453271f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
453371f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
453471f87433Sdalcinl    solver.
453571f87433Sdalcinl 
453671f87433Sdalcinl    Level: advanced
453771f87433Sdalcinl 
453871f87433Sdalcinl    Reference:
453971f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
454071f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
454171f87433Sdalcinl 
454271f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
454371f87433Sdalcinl 
4544fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
454571f87433Sdalcinl @*/
45467087cfbeSBarry Smith PetscErrorCode  SNESKSPSetUseEW(SNES snes,PetscBool flag)
454771f87433Sdalcinl {
454871f87433Sdalcinl   PetscFunctionBegin;
45490700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4550acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flag,2);
455171f87433Sdalcinl   snes->ksp_ewconv = flag;
455271f87433Sdalcinl   PetscFunctionReturn(0);
455371f87433Sdalcinl }
455471f87433Sdalcinl 
455571f87433Sdalcinl /*@
4556fa9f3622SBarry Smith    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
455771f87433Sdalcinl    for computing relative tolerance for linear solvers within an
455871f87433Sdalcinl    inexact Newton method.
455971f87433Sdalcinl 
456071f87433Sdalcinl    Not Collective
456171f87433Sdalcinl 
456271f87433Sdalcinl    Input Parameter:
456371f87433Sdalcinl .  snes - SNES context
456471f87433Sdalcinl 
456571f87433Sdalcinl    Output Parameter:
456671f87433Sdalcinl .  flag - PETSC_TRUE or PETSC_FALSE
456771f87433Sdalcinl 
456871f87433Sdalcinl    Notes:
456971f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
457071f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
457171f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
457271f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
457371f87433Sdalcinl    solver.
457471f87433Sdalcinl 
457571f87433Sdalcinl    Level: advanced
457671f87433Sdalcinl 
457771f87433Sdalcinl    Reference:
457871f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
457971f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
458071f87433Sdalcinl 
458171f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
458271f87433Sdalcinl 
4583fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
458471f87433Sdalcinl @*/
45857087cfbeSBarry Smith PetscErrorCode  SNESKSPGetUseEW(SNES snes, PetscBool  *flag)
458671f87433Sdalcinl {
458771f87433Sdalcinl   PetscFunctionBegin;
45880700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
458971f87433Sdalcinl   PetscValidPointer(flag,2);
459071f87433Sdalcinl   *flag = snes->ksp_ewconv;
459171f87433Sdalcinl   PetscFunctionReturn(0);
459271f87433Sdalcinl }
459371f87433Sdalcinl 
459471f87433Sdalcinl /*@
4595fa9f3622SBarry Smith    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
459671f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
459771f87433Sdalcinl    Newton method.
459871f87433Sdalcinl 
45993f9fe445SBarry Smith    Logically Collective on SNES
460071f87433Sdalcinl 
460171f87433Sdalcinl    Input Parameters:
460271f87433Sdalcinl +    snes - SNES context
460371f87433Sdalcinl .    version - version 1, 2 (default is 2) or 3
460471f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
460571f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
460671f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
460771f87433Sdalcinl              (0 <= gamma2 <= 1)
460871f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
460971f87433Sdalcinl .    alpha2 - power for safeguard
461071f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
461171f87433Sdalcinl 
461271f87433Sdalcinl    Note:
461371f87433Sdalcinl    Version 3 was contributed by Luis Chacon, June 2006.
461471f87433Sdalcinl 
461571f87433Sdalcinl    Use PETSC_DEFAULT to retain the default for any of the parameters.
461671f87433Sdalcinl 
461771f87433Sdalcinl    Level: advanced
461871f87433Sdalcinl 
461971f87433Sdalcinl    Reference:
462071f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
462171f87433Sdalcinl    inexact Newton method", Utah State University Math. Stat. Dept. Res.
462271f87433Sdalcinl    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
462371f87433Sdalcinl 
462471f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
462571f87433Sdalcinl 
4626fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
462771f87433Sdalcinl @*/
4628f5af7f23SKarl Rupp PetscErrorCode  SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
462971f87433Sdalcinl {
4630fa9f3622SBarry Smith   SNESKSPEW *kctx;
46315fd66863SKarl Rupp 
463271f87433Sdalcinl   PetscFunctionBegin;
46330700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4634fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
4635e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
4636c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,version,2);
4637c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_0,3);
4638c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_max,4);
4639c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,gamma,5);
4640c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha,6);
4641c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha2,7);
4642c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,threshold,8);
464371f87433Sdalcinl 
464471f87433Sdalcinl   if (version != PETSC_DEFAULT)   kctx->version   = version;
464571f87433Sdalcinl   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
464671f87433Sdalcinl   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
464771f87433Sdalcinl   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
464871f87433Sdalcinl   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
464971f87433Sdalcinl   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
465071f87433Sdalcinl   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
465171f87433Sdalcinl 
4652f23aa3ddSBarry 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);
465357622a8eSBarry 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);
465457622a8eSBarry 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);
465557622a8eSBarry 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);
465657622a8eSBarry 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);
465757622a8eSBarry 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);
465871f87433Sdalcinl   PetscFunctionReturn(0);
465971f87433Sdalcinl }
466071f87433Sdalcinl 
466171f87433Sdalcinl /*@
4662fa9f3622SBarry Smith    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
466371f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
466471f87433Sdalcinl    Newton method.
466571f87433Sdalcinl 
466671f87433Sdalcinl    Not Collective
466771f87433Sdalcinl 
466871f87433Sdalcinl    Input Parameters:
466971f87433Sdalcinl      snes - SNES context
467071f87433Sdalcinl 
467171f87433Sdalcinl    Output Parameters:
467271f87433Sdalcinl +    version - version 1, 2 (default is 2) or 3
467371f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
467471f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
4675bf388a1fSBarry Smith .    gamma - multiplicative factor for version 2 rtol computation (0 <= gamma2 <= 1)
467671f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
467771f87433Sdalcinl .    alpha2 - power for safeguard
467871f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
467971f87433Sdalcinl 
468071f87433Sdalcinl    Level: advanced
468171f87433Sdalcinl 
468271f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters
468371f87433Sdalcinl 
4684fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
468571f87433Sdalcinl @*/
4686bf388a1fSBarry Smith PetscErrorCode  SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
468771f87433Sdalcinl {
4688fa9f3622SBarry Smith   SNESKSPEW *kctx;
46895fd66863SKarl Rupp 
469071f87433Sdalcinl   PetscFunctionBegin;
46910700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4692fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
4693e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
469471f87433Sdalcinl   if (version)   *version   = kctx->version;
469571f87433Sdalcinl   if (rtol_0)    *rtol_0    = kctx->rtol_0;
469671f87433Sdalcinl   if (rtol_max)  *rtol_max  = kctx->rtol_max;
469771f87433Sdalcinl   if (gamma)     *gamma     = kctx->gamma;
469871f87433Sdalcinl   if (alpha)     *alpha     = kctx->alpha;
469971f87433Sdalcinl   if (alpha2)    *alpha2    = kctx->alpha2;
470071f87433Sdalcinl   if (threshold) *threshold = kctx->threshold;
470171f87433Sdalcinl   PetscFunctionReturn(0);
470271f87433Sdalcinl }
470371f87433Sdalcinl 
4704d5378b5fSDmitry Karpeev  PetscErrorCode KSPPreSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes)
470571f87433Sdalcinl {
470671f87433Sdalcinl   PetscErrorCode ierr;
4707fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
470871f87433Sdalcinl   PetscReal      rtol  = PETSC_DEFAULT,stol;
470971f87433Sdalcinl 
471071f87433Sdalcinl   PetscFunctionBegin;
4711d4211eb9SBarry Smith   if (!snes->ksp_ewconv) PetscFunctionReturn(0);
471230058271SDmitry Karpeev   if (!snes->iter) {
471330058271SDmitry Karpeev     rtol = kctx->rtol_0; /* first time in, so use the original user rtol */
471430058271SDmitry Karpeev     ierr = VecNorm(snes->vec_func,NORM_2,&kctx->norm_first);CHKERRQ(ierr);
471530058271SDmitry Karpeev   }
4716f5af7f23SKarl Rupp   else {
471771f87433Sdalcinl     if (kctx->version == 1) {
471871f87433Sdalcinl       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
471971f87433Sdalcinl       if (rtol < 0.0) rtol = -rtol;
472085ec1a3cSBarry Smith       stol = PetscPowReal(kctx->rtol_last,kctx->alpha2);
472171f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
472271f87433Sdalcinl     } else if (kctx->version == 2) {
472385ec1a3cSBarry Smith       rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha);
472485ec1a3cSBarry Smith       stol = kctx->gamma * PetscPowReal(kctx->rtol_last,kctx->alpha);
472571f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
472671f87433Sdalcinl     } else if (kctx->version == 3) { /* contributed by Luis Chacon, June 2006. */
472785ec1a3cSBarry Smith       rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha);
472871f87433Sdalcinl       /* safeguard: avoid sharp decrease of rtol */
472985ec1a3cSBarry Smith       stol = kctx->gamma*PetscPowReal(kctx->rtol_last,kctx->alpha);
473071f87433Sdalcinl       stol = PetscMax(rtol,stol);
473171f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
473271f87433Sdalcinl       /* safeguard: avoid oversolving */
473330058271SDmitry Karpeev       stol = kctx->gamma*(kctx->norm_first*snes->rtol)/snes->norm;
473471f87433Sdalcinl       stol = PetscMax(rtol,stol);
473571f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
4736e32f2f54SBarry Smith     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
473771f87433Sdalcinl   }
473871f87433Sdalcinl   /* safeguard: avoid rtol greater than one */
473971f87433Sdalcinl   rtol = PetscMin(rtol,kctx->rtol_max);
474071f87433Sdalcinl   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
474157622a8eSBarry Smith   ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%g\n",snes->iter,kctx->version,(double)rtol);CHKERRQ(ierr);
474271f87433Sdalcinl   PetscFunctionReturn(0);
474371f87433Sdalcinl }
474471f87433Sdalcinl 
4745d5378b5fSDmitry Karpeev PetscErrorCode KSPPostSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes)
474671f87433Sdalcinl {
474771f87433Sdalcinl   PetscErrorCode ierr;
4748fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
474971f87433Sdalcinl   PCSide         pcside;
475071f87433Sdalcinl   Vec            lres;
475171f87433Sdalcinl 
475271f87433Sdalcinl   PetscFunctionBegin;
4753d4211eb9SBarry Smith   if (!snes->ksp_ewconv) PetscFunctionReturn(0);
475471f87433Sdalcinl   ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr);
475571dbe336SPeter Brune   kctx->norm_last = snes->norm;
475671f87433Sdalcinl   if (kctx->version == 1) {
47574f00ce20SMatthew G. Knepley     PC        pc;
47584f00ce20SMatthew G. Knepley     PetscBool isNone;
47594f00ce20SMatthew G. Knepley 
47604f00ce20SMatthew G. Knepley     ierr = KSPGetPC(ksp, &pc);CHKERRQ(ierr);
47614f00ce20SMatthew G. Knepley     ierr = PetscObjectTypeCompare((PetscObject) pc, PCNONE, &isNone);CHKERRQ(ierr);
4762b037da10SBarry Smith     ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr);
47634f00ce20SMatthew G. Knepley      if (pcside == PC_RIGHT || isNone) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
476471f87433Sdalcinl       /* KSP residual is true linear residual */
476571f87433Sdalcinl       ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr);
476671f87433Sdalcinl     } else {
476771f87433Sdalcinl       /* KSP residual is preconditioned residual */
476871f87433Sdalcinl       /* compute true linear residual norm */
476971f87433Sdalcinl       ierr = VecDuplicate(b,&lres);CHKERRQ(ierr);
477071f87433Sdalcinl       ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr);
477171f87433Sdalcinl       ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr);
477271f87433Sdalcinl       ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr);
47736bf464f9SBarry Smith       ierr = VecDestroy(&lres);CHKERRQ(ierr);
477471f87433Sdalcinl     }
477571f87433Sdalcinl   }
477671f87433Sdalcinl   PetscFunctionReturn(0);
477771f87433Sdalcinl }
477871f87433Sdalcinl 
4779d4211eb9SBarry Smith /*@
4780d4211eb9SBarry Smith    SNESGetKSP - Returns the KSP context for a SNES solver.
4781d4211eb9SBarry Smith 
4782d4211eb9SBarry Smith    Not Collective, but if SNES object is parallel, then KSP object is parallel
4783d4211eb9SBarry Smith 
4784d4211eb9SBarry Smith    Input Parameter:
4785d4211eb9SBarry Smith .  snes - the SNES context
4786d4211eb9SBarry Smith 
4787d4211eb9SBarry Smith    Output Parameter:
4788d4211eb9SBarry Smith .  ksp - the KSP context
4789d4211eb9SBarry Smith 
4790d4211eb9SBarry Smith    Notes:
4791d4211eb9SBarry Smith    The user can then directly manipulate the KSP context to set various
4792d4211eb9SBarry Smith    options, etc.  Likewise, the user can then extract and manipulate the
4793d4211eb9SBarry Smith    PC contexts as well.
4794d4211eb9SBarry Smith 
4795d4211eb9SBarry Smith    Level: beginner
4796d4211eb9SBarry Smith 
4797d4211eb9SBarry Smith .keywords: SNES, nonlinear, get, KSP, context
4798d4211eb9SBarry Smith 
4799d4211eb9SBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
4800d4211eb9SBarry Smith @*/
4801d4211eb9SBarry Smith PetscErrorCode  SNESGetKSP(SNES snes,KSP *ksp)
480271f87433Sdalcinl {
480371f87433Sdalcinl   PetscErrorCode ierr;
480471f87433Sdalcinl 
480571f87433Sdalcinl   PetscFunctionBegin;
4806d4211eb9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4807d4211eb9SBarry Smith   PetscValidPointer(ksp,2);
4808d4211eb9SBarry Smith 
4809d4211eb9SBarry Smith   if (!snes->ksp) {
4810a5c2985bSBarry Smith     PetscBool monitor = PETSC_FALSE;
4811a5c2985bSBarry Smith 
4812d4211eb9SBarry Smith     ierr = KSPCreate(PetscObjectComm((PetscObject)snes),&snes->ksp);CHKERRQ(ierr);
4813d4211eb9SBarry Smith     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr);
48143bb1ff40SBarry Smith     ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->ksp);CHKERRQ(ierr);
4815d4211eb9SBarry Smith 
4816d5378b5fSDmitry Karpeev     ierr = KSPSetPreSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPreSolve_SNESEW,snes);CHKERRQ(ierr);
4817d5378b5fSDmitry Karpeev     ierr = KSPSetPostSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPostSolve_SNESEW,snes);CHKERRQ(ierr);
4818a5c2985bSBarry Smith 
4819c5929fdfSBarry Smith     ierr = PetscOptionsGetBool(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-ksp_monitor_snes",&monitor,NULL);CHKERRQ(ierr);
4820a5c2985bSBarry Smith     if (monitor) {
4821a5c2985bSBarry Smith       ierr = KSPMonitorSet(snes->ksp,KSPMonitorSNES,snes,NULL);CHKERRQ(ierr);
4822a5c2985bSBarry Smith     }
4823e5f7ee39SBarry Smith     monitor = PETSC_FALSE;
4824c5929fdfSBarry Smith     ierr = PetscOptionsGetBool(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-ksp_monitor_snes_lg",&monitor,NULL);CHKERRQ(ierr);
4825e5f7ee39SBarry Smith     if (monitor) {
4826e5f7ee39SBarry Smith       PetscObject *objs;
48278b0b5a47SLisandro Dalcin       ierr = KSPMonitorSNESLGResidualNormCreate(PetscObjectComm((PetscObject)snes),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,600,600,&objs);CHKERRQ(ierr);
4828e5f7ee39SBarry Smith       objs[0] = (PetscObject) snes;
4829e5f7ee39SBarry Smith       ierr = KSPMonitorSet(snes->ksp,(PetscErrorCode (*)(KSP,PetscInt,PetscReal,void*))KSPMonitorSNESLGResidualNorm,objs,(PetscErrorCode (*)(void**))KSPMonitorSNESLGResidualNormDestroy);CHKERRQ(ierr);
4830e5f7ee39SBarry Smith     }
4831d4211eb9SBarry Smith   }
4832d4211eb9SBarry Smith   *ksp = snes->ksp;
483371f87433Sdalcinl   PetscFunctionReturn(0);
483471f87433Sdalcinl }
48356c699258SBarry Smith 
4836d4211eb9SBarry Smith 
4837af0996ceSBarry Smith #include <petsc/private/dmimpl.h>
48386c699258SBarry Smith /*@
48392a808120SBarry Smith    SNESSetDM - Sets the DM that may be used by some nonlinear solvers or their underlying preconditioners
48406c699258SBarry Smith 
48413f9fe445SBarry Smith    Logically Collective on SNES
48426c699258SBarry Smith 
48436c699258SBarry Smith    Input Parameters:
48442a808120SBarry Smith +  snes - the nonlinear solver context
48452a808120SBarry Smith -  dm - the dm, cannot be NULL
48466c699258SBarry Smith 
48476c699258SBarry Smith    Level: intermediate
48486c699258SBarry Smith 
48496c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM()
48506c699258SBarry Smith @*/
48517087cfbeSBarry Smith PetscErrorCode  SNESSetDM(SNES snes,DM dm)
48526c699258SBarry Smith {
48536c699258SBarry Smith   PetscErrorCode ierr;
4854345fed2cSBarry Smith   KSP            ksp;
4855942e3340SBarry Smith   DMSNES         sdm;
48566c699258SBarry Smith 
48576c699258SBarry Smith   PetscFunctionBegin;
48580700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
48592a808120SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,2);
48602a808120SBarry Smith   ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);
4861942e3340SBarry Smith   if (snes->dm) {               /* Move the DMSNES context over to the new DM unless the new DM already has one */
486251f4b3c7SToby Isaac     if (snes->dm->dmsnes && !dm->dmsnes) {
4863942e3340SBarry Smith       ierr = DMCopyDMSNES(snes->dm,dm);CHKERRQ(ierr);
4864942e3340SBarry Smith       ierr = DMGetDMSNES(snes->dm,&sdm);CHKERRQ(ierr);
4865f5af7f23SKarl Rupp       if (sdm->originaldm == snes->dm) sdm->originaldm = dm; /* Grant write privileges to the replacement DM */
48666cab3a1bSJed Brown     }
48676bf464f9SBarry Smith     ierr = DMDestroy(&snes->dm);CHKERRQ(ierr);
48686cab3a1bSJed Brown   }
48696c699258SBarry Smith   snes->dm     = dm;
4870116d1032SJed Brown   snes->dmAuto = PETSC_FALSE;
4871f5af7f23SKarl Rupp 
4872345fed2cSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
4873345fed2cSBarry Smith   ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr);
4874f22f69f0SBarry Smith   ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr);
48752c155ee1SBarry Smith   if (snes->pc) {
48762c155ee1SBarry Smith     ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr);
4877be95d8f1SBarry Smith     ierr = SNESSetNPCSide(snes,snes->pcside);CHKERRQ(ierr);
48782c155ee1SBarry Smith   }
48796c699258SBarry Smith   PetscFunctionReturn(0);
48806c699258SBarry Smith }
48816c699258SBarry Smith 
48826c699258SBarry Smith /*@
48836c699258SBarry Smith    SNESGetDM - Gets the DM that may be used by some preconditioners
48846c699258SBarry Smith 
48853f9fe445SBarry Smith    Not Collective but DM obtained is parallel on SNES
48866c699258SBarry Smith 
48876c699258SBarry Smith    Input Parameter:
48886c699258SBarry Smith . snes - the preconditioner context
48896c699258SBarry Smith 
48906c699258SBarry Smith    Output Parameter:
48916c699258SBarry Smith .  dm - the dm
48926c699258SBarry Smith 
48936c699258SBarry Smith    Level: intermediate
48946c699258SBarry Smith 
48956c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM()
48966c699258SBarry Smith @*/
48977087cfbeSBarry Smith PetscErrorCode  SNESGetDM(SNES snes,DM *dm)
48986c699258SBarry Smith {
48996cab3a1bSJed Brown   PetscErrorCode ierr;
49006cab3a1bSJed Brown 
49016c699258SBarry Smith   PetscFunctionBegin;
49020700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
49036cab3a1bSJed Brown   if (!snes->dm) {
4904ce94432eSBarry Smith     ierr         = DMShellCreate(PetscObjectComm((PetscObject)snes),&snes->dm);CHKERRQ(ierr);
4905116d1032SJed Brown     snes->dmAuto = PETSC_TRUE;
49066cab3a1bSJed Brown   }
49076c699258SBarry Smith   *dm = snes->dm;
49086c699258SBarry Smith   PetscFunctionReturn(0);
49096c699258SBarry Smith }
49100807856dSBarry Smith 
491131823bd8SMatthew G Knepley /*@
4912be95d8f1SBarry Smith   SNESSetNPC - Sets the nonlinear preconditioner to be used.
491331823bd8SMatthew G Knepley 
491431823bd8SMatthew G Knepley   Collective on SNES
491531823bd8SMatthew G Knepley 
491631823bd8SMatthew G Knepley   Input Parameters:
491731823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate()
491831823bd8SMatthew G Knepley - pc   - the preconditioner object
491931823bd8SMatthew G Knepley 
492031823bd8SMatthew G Knepley   Notes:
4921be95d8f1SBarry Smith   Use SNESGetNPC() to retrieve the preconditioner context (for example,
492231823bd8SMatthew G Knepley   to configure it using the API).
492331823bd8SMatthew G Knepley 
492431823bd8SMatthew G Knepley   Level: developer
492531823bd8SMatthew G Knepley 
492631823bd8SMatthew G Knepley .keywords: SNES, set, precondition
49273ad1a0b9SPatrick Farrell .seealso: SNESGetNPC(), SNESHasNPC()
492831823bd8SMatthew G Knepley @*/
4929be95d8f1SBarry Smith PetscErrorCode SNESSetNPC(SNES snes, SNES pc)
493031823bd8SMatthew G Knepley {
493131823bd8SMatthew G Knepley   PetscErrorCode ierr;
493231823bd8SMatthew G Knepley 
493331823bd8SMatthew G Knepley   PetscFunctionBegin;
493431823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
493531823bd8SMatthew G Knepley   PetscValidHeaderSpecific(pc, SNES_CLASSID, 2);
493631823bd8SMatthew G Knepley   PetscCheckSameComm(snes, 1, pc, 2);
493731823bd8SMatthew G Knepley   ierr     = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr);
4938bf11d3b6SBarry Smith   ierr     = SNESDestroy(&snes->pc);CHKERRQ(ierr);
493931823bd8SMatthew G Knepley   snes->pc = pc;
49403bb1ff40SBarry Smith   ierr     = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->pc);CHKERRQ(ierr);
494131823bd8SMatthew G Knepley   PetscFunctionReturn(0);
494231823bd8SMatthew G Knepley }
494331823bd8SMatthew G Knepley 
494431823bd8SMatthew G Knepley /*@
4945be95d8f1SBarry Smith   SNESGetNPC - Creates a nonlinear preconditioning solver (SNES) to be used to precondition the nonlinear solver.
494631823bd8SMatthew G Knepley 
494731823bd8SMatthew G Knepley   Not Collective
494831823bd8SMatthew G Knepley 
494931823bd8SMatthew G Knepley   Input Parameter:
495031823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate()
495131823bd8SMatthew G Knepley 
495231823bd8SMatthew G Knepley   Output Parameter:
495331823bd8SMatthew G Knepley . pc - preconditioner context
495431823bd8SMatthew G Knepley 
4955be95d8f1SBarry Smith   Notes: If a SNES was previously set with SNESSetNPC() then that SNES is returned.
4956be95d8f1SBarry Smith 
495731823bd8SMatthew G Knepley   Level: developer
495831823bd8SMatthew G Knepley 
495931823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner
49603ad1a0b9SPatrick Farrell .seealso: SNESSetNPC(), SNESHasNPC()
496131823bd8SMatthew G Knepley @*/
4962be95d8f1SBarry Smith PetscErrorCode SNESGetNPC(SNES snes, SNES *pc)
496331823bd8SMatthew G Knepley {
496431823bd8SMatthew G Knepley   PetscErrorCode ierr;
4965a64e098fSPeter Brune   const char     *optionsprefix;
496631823bd8SMatthew G Knepley 
496731823bd8SMatthew G Knepley   PetscFunctionBegin;
496831823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
496931823bd8SMatthew G Knepley   PetscValidPointer(pc, 2);
497031823bd8SMatthew G Knepley   if (!snes->pc) {
497182f516ccSBarry Smith     ierr = SNESCreate(PetscObjectComm((PetscObject)snes),&snes->pc);CHKERRQ(ierr);
49724a0c5b0cSMatthew G Knepley     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->pc,(PetscObject)snes,1);CHKERRQ(ierr);
49733bb1ff40SBarry Smith     ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->pc);CHKERRQ(ierr);
4974a64e098fSPeter Brune     ierr = SNESGetOptionsPrefix(snes,&optionsprefix);CHKERRQ(ierr);
4975a64e098fSPeter Brune     ierr = SNESSetOptionsPrefix(snes->pc,optionsprefix);CHKERRQ(ierr);
4976a64e098fSPeter Brune     ierr = SNESAppendOptionsPrefix(snes->pc,"npc_");CHKERRQ(ierr);
4977971e163fSPeter Brune     ierr = SNESSetCountersReset(snes->pc,PETSC_FALSE);CHKERRQ(ierr);
497831823bd8SMatthew G Knepley   }
497931823bd8SMatthew G Knepley   *pc = snes->pc;
498031823bd8SMatthew G Knepley   PetscFunctionReturn(0);
498131823bd8SMatthew G Knepley }
498231823bd8SMatthew G Knepley 
49833ad1a0b9SPatrick Farrell /*@
49843ad1a0b9SPatrick Farrell   SNESHasNPC - Returns whether a nonlinear preconditioner exists
49853ad1a0b9SPatrick Farrell 
49863ad1a0b9SPatrick Farrell   Not Collective
49873ad1a0b9SPatrick Farrell 
49883ad1a0b9SPatrick Farrell   Input Parameter:
49893ad1a0b9SPatrick Farrell . snes - iterative context obtained from SNESCreate()
49903ad1a0b9SPatrick Farrell 
49913ad1a0b9SPatrick Farrell   Output Parameter:
49923ad1a0b9SPatrick Farrell . has_npc - whether the SNES has an NPC or not
49933ad1a0b9SPatrick Farrell 
49943ad1a0b9SPatrick Farrell   Level: developer
49953ad1a0b9SPatrick Farrell 
49963ad1a0b9SPatrick Farrell .keywords: SNES, has, preconditioner
49973ad1a0b9SPatrick Farrell .seealso: SNESSetNPC(), SNESGetNPC()
49983ad1a0b9SPatrick Farrell @*/
49993ad1a0b9SPatrick Farrell PetscErrorCode SNESHasNPC(SNES snes, PetscBool *has_npc)
50003ad1a0b9SPatrick Farrell {
50013ad1a0b9SPatrick Farrell   PetscFunctionBegin;
50023ad1a0b9SPatrick Farrell   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
500360c7cefcSBarry Smith   *has_npc = (PetscBool) (snes->pc ? PETSC_TRUE : PETSC_FALSE);
50043ad1a0b9SPatrick Farrell   PetscFunctionReturn(0);
50053ad1a0b9SPatrick Farrell }
50063ad1a0b9SPatrick Farrell 
5007c40d0f55SPeter Brune /*@
5008be95d8f1SBarry Smith     SNESSetNPCSide - Sets the preconditioning side.
5009c40d0f55SPeter Brune 
5010c40d0f55SPeter Brune     Logically Collective on SNES
5011c40d0f55SPeter Brune 
5012c40d0f55SPeter Brune     Input Parameter:
5013c40d0f55SPeter Brune .   snes - iterative context obtained from SNESCreate()
5014c40d0f55SPeter Brune 
5015c40d0f55SPeter Brune     Output Parameter:
5016c40d0f55SPeter Brune .   side - the preconditioning side, where side is one of
5017c40d0f55SPeter Brune .vb
50182d547940SBarry Smith       PC_LEFT - left preconditioning
50192d547940SBarry Smith       PC_RIGHT - right preconditioning (default for most nonlinear solvers)
5020c40d0f55SPeter Brune .ve
5021c40d0f55SPeter Brune 
5022c40d0f55SPeter Brune     Options Database Keys:
5023c40d0f55SPeter Brune .   -snes_pc_side <right,left>
5024c40d0f55SPeter Brune 
50252d547940SBarry Smith     Notes: SNESNRICHARDSON and SNESNCG only support left preconditioning.
50262d547940SBarry Smith 
5027c40d0f55SPeter Brune     Level: intermediate
5028c40d0f55SPeter Brune 
5029c40d0f55SPeter Brune .keywords: SNES, set, right, left, side, preconditioner, flag
5030c40d0f55SPeter Brune 
5031be95d8f1SBarry Smith .seealso: SNESGetNPCSide(), KSPSetPCSide()
5032c40d0f55SPeter Brune @*/
5033be95d8f1SBarry Smith PetscErrorCode  SNESSetNPCSide(SNES snes,PCSide side)
5034c40d0f55SPeter Brune {
5035c40d0f55SPeter Brune   PetscFunctionBegin;
5036c40d0f55SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5037c40d0f55SPeter Brune   PetscValidLogicalCollectiveEnum(snes,side,2);
5038c40d0f55SPeter Brune   snes->pcside = side;
5039c40d0f55SPeter Brune   PetscFunctionReturn(0);
5040c40d0f55SPeter Brune }
5041c40d0f55SPeter Brune 
5042c40d0f55SPeter Brune /*@
5043be95d8f1SBarry Smith     SNESGetNPCSide - Gets the preconditioning side.
5044c40d0f55SPeter Brune 
5045c40d0f55SPeter Brune     Not Collective
5046c40d0f55SPeter Brune 
5047c40d0f55SPeter Brune     Input Parameter:
5048c40d0f55SPeter Brune .   snes - iterative context obtained from SNESCreate()
5049c40d0f55SPeter Brune 
5050c40d0f55SPeter Brune     Output Parameter:
5051c40d0f55SPeter Brune .   side - the preconditioning side, where side is one of
5052c40d0f55SPeter Brune .vb
50532d547940SBarry Smith       PC_LEFT - left preconditioning
50542d547940SBarry Smith       PC_RIGHT - right preconditioning (default for most nonlinear solvers)
5055c40d0f55SPeter Brune .ve
5056c40d0f55SPeter Brune 
5057c40d0f55SPeter Brune     Level: intermediate
5058c40d0f55SPeter Brune 
5059c40d0f55SPeter Brune .keywords: SNES, get, right, left, side, preconditioner, flag
5060c40d0f55SPeter Brune 
5061be95d8f1SBarry Smith .seealso: SNESSetNPCSide(), KSPGetPCSide()
5062c40d0f55SPeter Brune @*/
5063be95d8f1SBarry Smith PetscErrorCode  SNESGetNPCSide(SNES snes,PCSide *side)
5064c40d0f55SPeter Brune {
5065c40d0f55SPeter Brune   PetscFunctionBegin;
5066c40d0f55SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5067c40d0f55SPeter Brune   PetscValidPointer(side,2);
5068c40d0f55SPeter Brune   *side = snes->pcside;
5069c40d0f55SPeter Brune   PetscFunctionReturn(0);
5070c40d0f55SPeter Brune }
5071c40d0f55SPeter Brune 
50729e764e56SPeter Brune /*@
50737601faf0SJed Brown   SNESSetLineSearch - Sets the linesearch on the SNES instance.
50749e764e56SPeter Brune 
50759e764e56SPeter Brune   Collective on SNES
50769e764e56SPeter Brune 
50779e764e56SPeter Brune   Input Parameters:
50789e764e56SPeter Brune + snes - iterative context obtained from SNESCreate()
50799e764e56SPeter Brune - linesearch   - the linesearch object
50809e764e56SPeter Brune 
50819e764e56SPeter Brune   Notes:
50827601faf0SJed Brown   Use SNESGetLineSearch() to retrieve the preconditioner context (for example,
50839e764e56SPeter Brune   to configure it using the API).
50849e764e56SPeter Brune 
50859e764e56SPeter Brune   Level: developer
50869e764e56SPeter Brune 
50879e764e56SPeter Brune .keywords: SNES, set, linesearch
50887601faf0SJed Brown .seealso: SNESGetLineSearch()
50899e764e56SPeter Brune @*/
50907601faf0SJed Brown PetscErrorCode SNESSetLineSearch(SNES snes, SNESLineSearch linesearch)
50919e764e56SPeter Brune {
50929e764e56SPeter Brune   PetscErrorCode ierr;
50939e764e56SPeter Brune 
50949e764e56SPeter Brune   PetscFunctionBegin;
50959e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5096f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2);
50979e764e56SPeter Brune   PetscCheckSameComm(snes, 1, linesearch, 2);
50989e764e56SPeter Brune   ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr);
5099f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr);
5100f5af7f23SKarl Rupp 
51019e764e56SPeter Brune   snes->linesearch = linesearch;
5102f5af7f23SKarl Rupp 
51033bb1ff40SBarry Smith   ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch);CHKERRQ(ierr);
51049e764e56SPeter Brune   PetscFunctionReturn(0);
51059e764e56SPeter Brune }
51069e764e56SPeter Brune 
5107a34ceb2aSJed Brown /*@
51087601faf0SJed Brown   SNESGetLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch()
51098141a3b9SPeter Brune   or creates a default line search instance associated with the SNES and returns it.
51109e764e56SPeter Brune 
51119e764e56SPeter Brune   Not Collective
51129e764e56SPeter Brune 
51139e764e56SPeter Brune   Input Parameter:
51149e764e56SPeter Brune . snes - iterative context obtained from SNESCreate()
51159e764e56SPeter Brune 
51169e764e56SPeter Brune   Output Parameter:
51179e764e56SPeter Brune . linesearch - linesearch context
51189e764e56SPeter Brune 
5119162e0bf5SPeter Brune   Level: beginner
51209e764e56SPeter Brune 
51219e764e56SPeter Brune .keywords: SNES, get, linesearch
5122162e0bf5SPeter Brune .seealso: SNESSetLineSearch(), SNESLineSearchCreate()
51239e764e56SPeter Brune @*/
51247601faf0SJed Brown PetscErrorCode SNESGetLineSearch(SNES snes, SNESLineSearch *linesearch)
51259e764e56SPeter Brune {
51269e764e56SPeter Brune   PetscErrorCode ierr;
51279e764e56SPeter Brune   const char     *optionsprefix;
51289e764e56SPeter Brune 
51299e764e56SPeter Brune   PetscFunctionBegin;
51309e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
51319e764e56SPeter Brune   PetscValidPointer(linesearch, 2);
51329e764e56SPeter Brune   if (!snes->linesearch) {
51339e764e56SPeter Brune     ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
513482f516ccSBarry Smith     ierr = SNESLineSearchCreate(PetscObjectComm((PetscObject)snes), &snes->linesearch);CHKERRQ(ierr);
5135f1c6b773SPeter Brune     ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr);
5136b1dca40bSPeter Brune     ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr);
51379e764e56SPeter Brune     ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr);
51383bb1ff40SBarry Smith     ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch);CHKERRQ(ierr);
51399e764e56SPeter Brune   }
51409e764e56SPeter Brune   *linesearch = snes->linesearch;
51419e764e56SPeter Brune   PetscFunctionReturn(0);
51429e764e56SPeter Brune }
51439e764e56SPeter Brune 
514469b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
5145c6db04a5SJed Brown #include <mex.h>
514669b4f73cSBarry Smith 
51478f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext;
51488f6e6473SBarry Smith 
51490807856dSBarry Smith /*
5150bf388a1fSBarry Smith    SNESComputeFunction_Matlab - Calls the function that has been set with SNESSetFunctionMatlab().
51510807856dSBarry Smith 
51520807856dSBarry Smith    Collective on SNES
51530807856dSBarry Smith 
51540807856dSBarry Smith    Input Parameters:
51550807856dSBarry Smith +  snes - the SNES context
51560807856dSBarry Smith -  x - input vector
51570807856dSBarry Smith 
51580807856dSBarry Smith    Output Parameter:
51590807856dSBarry Smith .  y - function vector, as set by SNESSetFunction()
51600807856dSBarry Smith 
51610807856dSBarry Smith    Notes:
51620807856dSBarry Smith    SNESComputeFunction() is typically used within nonlinear solvers
51630807856dSBarry Smith    implementations, so most users would not generally call this routine
51640807856dSBarry Smith    themselves.
51650807856dSBarry Smith 
51660807856dSBarry Smith    Level: developer
51670807856dSBarry Smith 
51680807856dSBarry Smith .keywords: SNES, nonlinear, compute, function
51690807856dSBarry Smith 
51700807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
517161b2408cSBarry Smith */
51727087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx)
51730807856dSBarry Smith {
5174e650e774SBarry Smith   PetscErrorCode    ierr;
51758f6e6473SBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext*)ctx;
51768f6e6473SBarry Smith   int               nlhs  = 1,nrhs = 5;
51778f6e6473SBarry Smith   mxArray           *plhs[1],*prhs[5];
517891621f2eSBarry Smith   long long int     lx = 0,ly = 0,ls = 0;
5179e650e774SBarry Smith 
51800807856dSBarry Smith   PetscFunctionBegin;
51810807856dSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
51820807856dSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
51830807856dSBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
51840807856dSBarry Smith   PetscCheckSameComm(snes,1,x,2);
51850807856dSBarry Smith   PetscCheckSameComm(snes,1,y,3);
51860807856dSBarry Smith 
51870807856dSBarry Smith   /* call Matlab function in ctx with arguments x and y */
5188e650e774SBarry Smith 
518991621f2eSBarry Smith   ierr    = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
5190e650e774SBarry Smith   ierr    = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
5191e650e774SBarry Smith   ierr    = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr);
519291621f2eSBarry Smith   prhs[0] = mxCreateDoubleScalar((double)ls);
519391621f2eSBarry Smith   prhs[1] = mxCreateDoubleScalar((double)lx);
519491621f2eSBarry Smith   prhs[2] = mxCreateDoubleScalar((double)ly);
51958f6e6473SBarry Smith   prhs[3] = mxCreateString(sctx->funcname);
51968f6e6473SBarry Smith   prhs[4] = sctx->ctx;
5197b807a863SBarry Smith   ierr    = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr);
5198e650e774SBarry Smith   ierr    = mxGetScalar(plhs[0]);CHKERRQ(ierr);
5199e650e774SBarry Smith   mxDestroyArray(prhs[0]);
5200e650e774SBarry Smith   mxDestroyArray(prhs[1]);
5201e650e774SBarry Smith   mxDestroyArray(prhs[2]);
52028f6e6473SBarry Smith   mxDestroyArray(prhs[3]);
5203e650e774SBarry Smith   mxDestroyArray(plhs[0]);
52040807856dSBarry Smith   PetscFunctionReturn(0);
52050807856dSBarry Smith }
52060807856dSBarry Smith 
520761b2408cSBarry Smith /*
52080807856dSBarry Smith    SNESSetFunctionMatlab - Sets the function evaluation routine and function
52090807856dSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
5210e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
52110807856dSBarry Smith 
52120807856dSBarry Smith    Logically Collective on SNES
52130807856dSBarry Smith 
52140807856dSBarry Smith    Input Parameters:
52150807856dSBarry Smith +  snes - the SNES context
52160807856dSBarry Smith .  r - vector to store function value
5217f8b49ee9SBarry Smith -  f - function evaluation routine
52180807856dSBarry Smith 
52190807856dSBarry Smith    Notes:
52200807856dSBarry Smith    The Newton-like methods typically solve linear systems of the form
52210807856dSBarry Smith $      f'(x) x = -f(x),
52220807856dSBarry Smith    where f'(x) denotes the Jacobian matrix and f(x) is the function.
52230807856dSBarry Smith 
52240807856dSBarry Smith    Level: beginner
52250807856dSBarry Smith 
5226c5b75c40SBarry Smith    Developer Note:  This bleeds the allocated memory SNESMatlabContext *sctx;
5227c5b75c40SBarry Smith 
52280807856dSBarry Smith .keywords: SNES, nonlinear, set, function
52290807856dSBarry Smith 
52300807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
523161b2408cSBarry Smith */
5232f8b49ee9SBarry Smith PetscErrorCode  SNESSetFunctionMatlab(SNES snes,Vec r,const char *f,mxArray *ctx)
52330807856dSBarry Smith {
52340807856dSBarry Smith   PetscErrorCode    ierr;
52358f6e6473SBarry Smith   SNESMatlabContext *sctx;
52360807856dSBarry Smith 
52370807856dSBarry Smith   PetscFunctionBegin;
52388f6e6473SBarry Smith   /* currently sctx is memory bleed */
5239854ce69bSBarry Smith   ierr = PetscNew(&sctx);CHKERRQ(ierr);
5240f8b49ee9SBarry Smith   ierr = PetscStrallocpy(f,&sctx->funcname);CHKERRQ(ierr);
52418f6e6473SBarry Smith   /*
52428f6e6473SBarry Smith      This should work, but it doesn't
52438f6e6473SBarry Smith   sctx->ctx = ctx;
52448f6e6473SBarry Smith   mexMakeArrayPersistent(sctx->ctx);
52458f6e6473SBarry Smith   */
52468f6e6473SBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
52478f6e6473SBarry Smith   ierr      = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr);
52480807856dSBarry Smith   PetscFunctionReturn(0);
52490807856dSBarry Smith }
525069b4f73cSBarry Smith 
525161b2408cSBarry Smith /*
5252bf388a1fSBarry Smith    SNESComputeJacobian_Matlab - Calls the function that has been set with SNESSetJacobianMatlab().
525361b2408cSBarry Smith 
525461b2408cSBarry Smith    Collective on SNES
525561b2408cSBarry Smith 
525661b2408cSBarry Smith    Input Parameters:
525761b2408cSBarry Smith +  snes - the SNES context
525861b2408cSBarry Smith .  x - input vector
525961b2408cSBarry Smith .  A, B - the matrices
526061b2408cSBarry Smith -  ctx - user context
526161b2408cSBarry Smith 
526261b2408cSBarry Smith    Level: developer
526361b2408cSBarry Smith 
526461b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function
526561b2408cSBarry Smith 
526661b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
526761b2408cSBarry Smith @*/
5268f3229a78SSatish Balay PetscErrorCode  SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat A,Mat B,void *ctx)
526961b2408cSBarry Smith {
527061b2408cSBarry Smith   PetscErrorCode    ierr;
527161b2408cSBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext*)ctx;
527261b2408cSBarry Smith   int               nlhs  = 2,nrhs = 6;
527361b2408cSBarry Smith   mxArray           *plhs[2],*prhs[6];
527461b2408cSBarry Smith   long long int     lx = 0,lA = 0,ls = 0, lB = 0;
527561b2408cSBarry Smith 
527661b2408cSBarry Smith   PetscFunctionBegin;
527761b2408cSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
527861b2408cSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
527961b2408cSBarry Smith 
528061b2408cSBarry Smith   /* call Matlab function in ctx with arguments x and y */
528161b2408cSBarry Smith 
528261b2408cSBarry Smith   ierr    = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
528361b2408cSBarry Smith   ierr    = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
528461b2408cSBarry Smith   ierr    = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr);
528561b2408cSBarry Smith   ierr    = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr);
528661b2408cSBarry Smith   prhs[0] = mxCreateDoubleScalar((double)ls);
528761b2408cSBarry Smith   prhs[1] = mxCreateDoubleScalar((double)lx);
528861b2408cSBarry Smith   prhs[2] = mxCreateDoubleScalar((double)lA);
528961b2408cSBarry Smith   prhs[3] = mxCreateDoubleScalar((double)lB);
529061b2408cSBarry Smith   prhs[4] = mxCreateString(sctx->funcname);
529161b2408cSBarry Smith   prhs[5] = sctx->ctx;
5292b807a863SBarry Smith   ierr    = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr);
529361b2408cSBarry Smith   ierr    = mxGetScalar(plhs[0]);CHKERRQ(ierr);
529461b2408cSBarry Smith   mxDestroyArray(prhs[0]);
529561b2408cSBarry Smith   mxDestroyArray(prhs[1]);
529661b2408cSBarry Smith   mxDestroyArray(prhs[2]);
529761b2408cSBarry Smith   mxDestroyArray(prhs[3]);
529861b2408cSBarry Smith   mxDestroyArray(prhs[4]);
529961b2408cSBarry Smith   mxDestroyArray(plhs[0]);
530061b2408cSBarry Smith   mxDestroyArray(plhs[1]);
530161b2408cSBarry Smith   PetscFunctionReturn(0);
530261b2408cSBarry Smith }
530361b2408cSBarry Smith 
530461b2408cSBarry Smith /*
530561b2408cSBarry Smith    SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
530661b2408cSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
5307e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
530861b2408cSBarry Smith 
530961b2408cSBarry Smith    Logically Collective on SNES
531061b2408cSBarry Smith 
531161b2408cSBarry Smith    Input Parameters:
531261b2408cSBarry Smith +  snes - the SNES context
531361b2408cSBarry Smith .  A,B - Jacobian matrices
5314f8b49ee9SBarry Smith .  J - function evaluation routine
531561b2408cSBarry Smith -  ctx - user context
531661b2408cSBarry Smith 
531761b2408cSBarry Smith    Level: developer
531861b2408cSBarry Smith 
5319c5b75c40SBarry Smith    Developer Note:  This bleeds the allocated memory SNESMatlabContext *sctx;
5320c5b75c40SBarry Smith 
532161b2408cSBarry Smith .keywords: SNES, nonlinear, set, function
532261b2408cSBarry Smith 
5323f8b49ee9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction(), J
532461b2408cSBarry Smith */
5325f8b49ee9SBarry Smith PetscErrorCode  SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *J,mxArray *ctx)
532661b2408cSBarry Smith {
532761b2408cSBarry Smith   PetscErrorCode    ierr;
532861b2408cSBarry Smith   SNESMatlabContext *sctx;
532961b2408cSBarry Smith 
533061b2408cSBarry Smith   PetscFunctionBegin;
533161b2408cSBarry Smith   /* currently sctx is memory bleed */
5332854ce69bSBarry Smith   ierr = PetscNew(&sctx);CHKERRQ(ierr);
5333f8b49ee9SBarry Smith   ierr = PetscStrallocpy(J,&sctx->funcname);CHKERRQ(ierr);
533461b2408cSBarry Smith   /*
533561b2408cSBarry Smith      This should work, but it doesn't
533661b2408cSBarry Smith   sctx->ctx = ctx;
533761b2408cSBarry Smith   mexMakeArrayPersistent(sctx->ctx);
533861b2408cSBarry Smith   */
533961b2408cSBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
534061b2408cSBarry Smith   ierr      = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
534161b2408cSBarry Smith   PetscFunctionReturn(0);
534261b2408cSBarry Smith }
534369b4f73cSBarry Smith 
5344f9eb7ae2SShri Abhyankar /*
5345f9eb7ae2SShri Abhyankar    SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab().
5346f9eb7ae2SShri Abhyankar 
5347f9eb7ae2SShri Abhyankar    Collective on SNES
5348f9eb7ae2SShri Abhyankar 
5349f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction()
5350f9eb7ae2SShri Abhyankar @*/
53517087cfbeSBarry Smith PetscErrorCode  SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx)
5352f9eb7ae2SShri Abhyankar {
5353f9eb7ae2SShri Abhyankar   PetscErrorCode    ierr;
535448f37e70SShri Abhyankar   SNESMatlabContext *sctx = (SNESMatlabContext*)ctx;
5355f9eb7ae2SShri Abhyankar   int               nlhs  = 1,nrhs = 6;
5356f9eb7ae2SShri Abhyankar   mxArray           *plhs[1],*prhs[6];
5357f9eb7ae2SShri Abhyankar   long long int     lx = 0,ls = 0;
5358f9eb7ae2SShri Abhyankar   Vec               x  = snes->vec_sol;
5359f9eb7ae2SShri Abhyankar 
5360f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
5361f9eb7ae2SShri Abhyankar   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5362f9eb7ae2SShri Abhyankar 
5363f9eb7ae2SShri Abhyankar   ierr    = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
5364f9eb7ae2SShri Abhyankar   ierr    = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
5365f9eb7ae2SShri Abhyankar   prhs[0] = mxCreateDoubleScalar((double)ls);
5366f9eb7ae2SShri Abhyankar   prhs[1] = mxCreateDoubleScalar((double)it);
5367f9eb7ae2SShri Abhyankar   prhs[2] = mxCreateDoubleScalar((double)fnorm);
5368f9eb7ae2SShri Abhyankar   prhs[3] = mxCreateDoubleScalar((double)lx);
5369f9eb7ae2SShri Abhyankar   prhs[4] = mxCreateString(sctx->funcname);
5370f9eb7ae2SShri Abhyankar   prhs[5] = sctx->ctx;
5371f9eb7ae2SShri Abhyankar   ierr    = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr);
5372f9eb7ae2SShri Abhyankar   ierr    = mxGetScalar(plhs[0]);CHKERRQ(ierr);
5373f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[0]);
5374f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[1]);
5375f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[2]);
5376f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[3]);
5377f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[4]);
5378f9eb7ae2SShri Abhyankar   mxDestroyArray(plhs[0]);
5379f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
5380f9eb7ae2SShri Abhyankar }
5381f9eb7ae2SShri Abhyankar 
5382f9eb7ae2SShri Abhyankar /*
5383e3c5b3baSBarry Smith    SNESMonitorSetMatlab - Sets the monitor function from MATLAB
5384f9eb7ae2SShri Abhyankar 
5385f9eb7ae2SShri Abhyankar    Level: developer
5386f9eb7ae2SShri Abhyankar 
5387c5b75c40SBarry Smith    Developer Note:  This bleeds the allocated memory SNESMatlabContext *sctx;
5388c5b75c40SBarry Smith 
5389f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function
5390f9eb7ae2SShri Abhyankar 
5391f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
5392f9eb7ae2SShri Abhyankar */
53936e4dcb14SBarry Smith PetscErrorCode  SNESMonitorSetMatlab(SNES snes,const char *f,mxArray *ctx)
5394f9eb7ae2SShri Abhyankar {
5395f9eb7ae2SShri Abhyankar   PetscErrorCode    ierr;
5396f9eb7ae2SShri Abhyankar   SNESMatlabContext *sctx;
5397f9eb7ae2SShri Abhyankar 
5398f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
5399f9eb7ae2SShri Abhyankar   /* currently sctx is memory bleed */
5400854ce69bSBarry Smith   ierr = PetscNew(&sctx);CHKERRQ(ierr);
54016e4dcb14SBarry Smith   ierr = PetscStrallocpy(f,&sctx->funcname);CHKERRQ(ierr);
5402f9eb7ae2SShri Abhyankar   /*
5403f9eb7ae2SShri Abhyankar      This should work, but it doesn't
5404f9eb7ae2SShri Abhyankar   sctx->ctx = ctx;
5405f9eb7ae2SShri Abhyankar   mexMakeArrayPersistent(sctx->ctx);
5406f9eb7ae2SShri Abhyankar   */
5407f9eb7ae2SShri Abhyankar   sctx->ctx = mxDuplicateArray(ctx);
54080298fd71SBarry Smith   ierr      = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,NULL);CHKERRQ(ierr);
5409f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
5410f9eb7ae2SShri Abhyankar }
5411f9eb7ae2SShri Abhyankar 
541269b4f73cSBarry Smith #endif
5413