xref: /petsc/src/snes/interface/snes.c (revision efd4aadf157bf1ba2d80c2be092fcf4247860003)
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);
296*efd4aadfSBarry Smith     if (snes->usesksp) {
29777431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr);
298*efd4aadfSBarry Smith     }
29977431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr);
300dc0571f2SMatthew G. Knepley     ierr = SNESGetNormSchedule(snes, &normschedule);CHKERRQ(ierr);
301dc0571f2SMatthew G. Knepley     if (normschedule > 0) {ierr = PetscViewerASCIIPrintf(viewer,"  norm schedule %s\n",SNESNormSchedules[normschedule]);CHKERRQ(ierr);}
30217fe4bdfSPeter Brune     if (snes->gridsequence) {
30317fe4bdfSPeter Brune       ierr = PetscViewerASCIIPrintf(viewer,"  total number of grid sequence refinements=%D\n",snes->gridsequence);CHKERRQ(ierr);
30417fe4bdfSPeter Brune     }
3059b94acceSBarry Smith     if (snes->ksp_ewconv) {
306fa9f3622SBarry Smith       kctx = (SNESKSPEW*)snes->kspconvctx;
3079b94acceSBarry Smith       if (kctx) {
30877431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"  Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr);
30957622a8eSBarry 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);
31057622a8eSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    gamma=%g, alpha=%g, alpha2=%g\n",(double)kctx->gamma,(double)kctx->alpha,(double)kctx->alpha2);CHKERRQ(ierr);
3119b94acceSBarry Smith       }
3129b94acceSBarry Smith     }
313eb1f6c34SBarry Smith     if (snes->lagpreconditioner == -1) {
314eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is never rebuilt\n");CHKERRQ(ierr);
315eb1f6c34SBarry Smith     } else if (snes->lagpreconditioner > 1) {
316eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr);
317eb1f6c34SBarry Smith     }
318eb1f6c34SBarry Smith     if (snes->lagjacobian == -1) {
319eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is never rebuilt\n");CHKERRQ(ierr);
320eb1f6c34SBarry Smith     } else if (snes->lagjacobian > 1) {
32142f4f86dSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian);CHKERRQ(ierr);
322eb1f6c34SBarry Smith     }
3230f5bd95cSBarry Smith   } else if (isstring) {
324317d6ea6SBarry Smith     const char *type;
325454a90a3SBarry Smith     ierr = SNESGetType(snes,&type);CHKERRQ(ierr);
326b0a32e0cSBarry Smith     ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr);
32755849f57SBarry Smith   } else if (isbinary) {
32855849f57SBarry Smith     PetscInt    classid = SNES_FILE_CLASSID;
32955849f57SBarry Smith     MPI_Comm    comm;
33055849f57SBarry Smith     PetscMPIInt rank;
33155849f57SBarry Smith     char        type[256];
33255849f57SBarry Smith 
33355849f57SBarry Smith     ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
33455849f57SBarry Smith     ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
33555849f57SBarry Smith     if (!rank) {
33655849f57SBarry Smith       ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
33789d949e2SBarry Smith       ierr = PetscStrncpy(type,((PetscObject)snes)->type_name,sizeof(type));CHKERRQ(ierr);
33889d949e2SBarry Smith       ierr = PetscViewerBinaryWrite(viewer,type,sizeof(type),PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr);
33955849f57SBarry Smith     }
34055849f57SBarry Smith     if (snes->ops->view) {
34155849f57SBarry Smith       ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr);
34255849f57SBarry Smith     }
34372a02f06SBarry Smith   } else if (isdraw) {
34472a02f06SBarry Smith     PetscDraw draw;
34572a02f06SBarry Smith     char      str[36];
34689fd9fafSBarry Smith     PetscReal x,y,bottom,h;
34772a02f06SBarry Smith 
34872a02f06SBarry Smith     ierr   = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
34972a02f06SBarry Smith     ierr   = PetscDrawGetCurrentPoint(draw,&x,&y);CHKERRQ(ierr);
35072a02f06SBarry Smith     ierr   = PetscStrcpy(str,"SNES: ");CHKERRQ(ierr);
35172a02f06SBarry Smith     ierr   = PetscStrcat(str,((PetscObject)snes)->type_name);CHKERRQ(ierr);
35251fa3d41SBarry Smith     ierr   = PetscDrawStringBoxed(draw,x,y,PETSC_DRAW_BLUE,PETSC_DRAW_BLACK,str,NULL,&h);CHKERRQ(ierr);
35389fd9fafSBarry Smith     bottom = y - h;
35472a02f06SBarry Smith     ierr   = PetscDrawPushCurrentPoint(draw,x,bottom);CHKERRQ(ierr);
355c4646bacSPeter Brune     if (snes->ops->view) {
356c4646bacSPeter Brune       ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr);
357c4646bacSPeter Brune     }
358e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
359536b137fSBarry Smith   } else if (issaws) {
360d45a07a7SBarry Smith     PetscMPIInt rank;
3612657e9d9SBarry Smith     const char *name;
362d45a07a7SBarry Smith 
3632657e9d9SBarry Smith     ierr = PetscObjectGetName((PetscObject)snes,&name);CHKERRQ(ierr);
364d45a07a7SBarry Smith     ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
365d45a07a7SBarry Smith     if (!((PetscObject)snes)->amsmem && !rank) {
366d45a07a7SBarry Smith       char       dir[1024];
367d45a07a7SBarry Smith 
368e04113cfSBarry Smith       ierr = PetscObjectViewSAWs((PetscObject)snes,viewer);CHKERRQ(ierr);
3692657e9d9SBarry Smith       ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/its",name);CHKERRQ(ierr);
3702657e9d9SBarry Smith       PetscStackCallSAWs(SAWs_Register,(dir,&snes->iter,1,SAWs_READ,SAWs_INT));
371bfb97211SBarry Smith       if (!snes->conv_hist) {
372a0931e03SBarry Smith         ierr = SNESSetConvergenceHistory(snes,NULL,NULL,PETSC_DECIDE,PETSC_TRUE);CHKERRQ(ierr);
373bfb97211SBarry Smith       }
3742657e9d9SBarry Smith       ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/conv_hist",name);CHKERRQ(ierr);
3752657e9d9SBarry Smith       PetscStackCallSAWs(SAWs_Register,(dir,snes->conv_hist,10,SAWs_READ,SAWs_DOUBLE));
376f05ece33SBarry Smith     }
377bfb97211SBarry Smith #endif
37872a02f06SBarry Smith   }
37972a02f06SBarry Smith   if (snes->linesearch) {
38072a02f06SBarry Smith     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
3817601faf0SJed Brown     ierr = SNESGetLineSearch(snes, &linesearch);CHKERRQ(ierr);
38272a02f06SBarry Smith     ierr = SNESLineSearchView(linesearch, viewer);CHKERRQ(ierr);
38372a02f06SBarry Smith     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
38419bcc07fSBarry Smith   }
385*efd4aadfSBarry Smith   if (snes->npc && snes->usesnpc) {
3864a0c5b0cSMatthew G Knepley     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
387*efd4aadfSBarry Smith     ierr = SNESView(snes->npc, viewer);CHKERRQ(ierr);
3884a0c5b0cSMatthew G Knepley     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
3894a0c5b0cSMatthew G Knepley   }
3902d53ad75SBarry Smith   ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
3912d53ad75SBarry Smith   ierr = DMGetDMSNES(snes->dm,&dmsnes);CHKERRQ(ierr);
3922d53ad75SBarry Smith   ierr = DMSNESView(dmsnes, viewer);CHKERRQ(ierr);
3932d53ad75SBarry Smith   ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
3942c155ee1SBarry Smith   if (snes->usesksp) {
3952c155ee1SBarry Smith     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
396b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
39794b7f48cSBarry Smith     ierr = KSPView(ksp,viewer);CHKERRQ(ierr);
398b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
3992c155ee1SBarry Smith   }
40072a02f06SBarry Smith   if (isdraw) {
40172a02f06SBarry Smith     PetscDraw draw;
40272a02f06SBarry Smith     ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
40372a02f06SBarry Smith     ierr = PetscDrawPopCurrentPoint(draw);CHKERRQ(ierr);
4047f1410a3SPeter Brune   }
4053a40ed3dSBarry Smith   PetscFunctionReturn(0);
4069b94acceSBarry Smith }
4079b94acceSBarry Smith 
40876b2cf59SMatthew Knepley /*
40976b2cf59SMatthew Knepley   We retain a list of functions that also take SNES command
41076b2cf59SMatthew Knepley   line options. These are called at the end SNESSetFromOptions()
41176b2cf59SMatthew Knepley */
41276b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5
413a7cc72afSBarry Smith static PetscInt numberofsetfromoptions;
4146849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES);
41576b2cf59SMatthew Knepley 
416ac226902SBarry Smith /*@C
41776b2cf59SMatthew Knepley   SNESAddOptionsChecker - Adds an additional function to check for SNES options.
41876b2cf59SMatthew Knepley 
41976b2cf59SMatthew Knepley   Not Collective
42076b2cf59SMatthew Knepley 
42176b2cf59SMatthew Knepley   Input Parameter:
42276b2cf59SMatthew Knepley . snescheck - function that checks for options
42376b2cf59SMatthew Knepley 
42476b2cf59SMatthew Knepley   Level: developer
42576b2cf59SMatthew Knepley 
42676b2cf59SMatthew Knepley .seealso: SNESSetFromOptions()
42776b2cf59SMatthew Knepley @*/
4287087cfbeSBarry Smith PetscErrorCode  SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES))
42976b2cf59SMatthew Knepley {
43076b2cf59SMatthew Knepley   PetscFunctionBegin;
431f23aa3ddSBarry Smith   if (numberofsetfromoptions >= MAXSETFROMOPTIONS) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS);
43276b2cf59SMatthew Knepley   othersetfromoptions[numberofsetfromoptions++] = snescheck;
43376b2cf59SMatthew Knepley   PetscFunctionReturn(0);
43476b2cf59SMatthew Knepley }
43576b2cf59SMatthew Knepley 
4367087cfbeSBarry Smith extern PetscErrorCode  SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*);
437aa3661deSLisandro Dalcin 
438ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool hasOperator, PetscInt version)
439aa3661deSLisandro Dalcin {
440aa3661deSLisandro Dalcin   Mat            J;
441aa3661deSLisandro Dalcin   KSP            ksp;
442aa3661deSLisandro Dalcin   PC             pc;
443ace3abfcSBarry Smith   PetscBool      match;
444aa3661deSLisandro Dalcin   PetscErrorCode ierr;
445895c21f2SBarry Smith   MatNullSpace   nullsp;
446aa3661deSLisandro Dalcin 
447aa3661deSLisandro Dalcin   PetscFunctionBegin;
4480700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
449aa3661deSLisandro Dalcin 
45098613b67SLisandro Dalcin   if (!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) {
45198613b67SLisandro Dalcin     Mat A = snes->jacobian, B = snes->jacobian_pre;
4522a7a6963SBarry Smith     ierr = MatCreateVecs(A ? A : B, NULL,&snes->vec_func);CHKERRQ(ierr);
45398613b67SLisandro Dalcin   }
45498613b67SLisandro Dalcin 
455aa3661deSLisandro Dalcin   if (version == 1) {
456aa3661deSLisandro Dalcin     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
45798613b67SLisandro Dalcin     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
4589c6ac3b3SBarry Smith     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
459aa3661deSLisandro Dalcin   } else if (version == 2) {
460e32f2f54SBarry Smith     if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first");
461570b7f6dSBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) && !defined(PETSC_USE_REAL___FP16)
462aa3661deSLisandro Dalcin     ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr);
463aa3661deSLisandro Dalcin #else
464e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)");
465aa3661deSLisandro Dalcin #endif
466a8248277SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2");
467aa3661deSLisandro Dalcin 
468895c21f2SBarry Smith   /* attach any user provided null space that was on Amat to the newly created matrix free matrix */
469895c21f2SBarry Smith   if (snes->jacobian) {
470895c21f2SBarry Smith     ierr = MatGetNullSpace(snes->jacobian,&nullsp);CHKERRQ(ierr);
471895c21f2SBarry Smith     if (nullsp) {
472895c21f2SBarry Smith       ierr = MatSetNullSpace(J,nullsp);CHKERRQ(ierr);
473895c21f2SBarry Smith     }
474895c21f2SBarry Smith   }
475895c21f2SBarry Smith 
476aa3661deSLisandro Dalcin   ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr);
477d3462f78SMatthew Knepley   if (hasOperator) {
4783232da50SPeter Brune 
479aa3661deSLisandro Dalcin     /* This version replaces the user provided Jacobian matrix with a
480aa3661deSLisandro Dalcin        matrix-free version but still employs the user-provided preconditioner matrix. */
481aa3661deSLisandro Dalcin     ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr);
482aa3661deSLisandro Dalcin   } else {
483aa3661deSLisandro Dalcin     /* This version replaces both the user-provided Jacobian and the user-
4843232da50SPeter Brune      provided preconditioner Jacobian with the default matrix free version. */
485*efd4aadfSBarry Smith     if ((snes->npcside== PC_LEFT) && snes->npc) {
486d728fb7dSPeter Brune       if (!snes->jacobian){ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr);}
487172a4300SPeter Brune     } else {
48828a52e04SBarry Smith       ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,0);CHKERRQ(ierr);
489172a4300SPeter Brune     }
490aa3661deSLisandro Dalcin     /* Force no preconditioner */
491aa3661deSLisandro Dalcin     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
492aa3661deSLisandro Dalcin     ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr);
493251f4c67SDmitry Karpeev     ierr = PetscObjectTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr);
494aa3661deSLisandro Dalcin     if (!match) {
495aa3661deSLisandro Dalcin       ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr);
496aa3661deSLisandro Dalcin       ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr);
497aa3661deSLisandro Dalcin     }
498aa3661deSLisandro Dalcin   }
4996bf464f9SBarry Smith   ierr = MatDestroy(&J);CHKERRQ(ierr);
500aa3661deSLisandro Dalcin   PetscFunctionReturn(0);
501aa3661deSLisandro Dalcin }
502aa3661deSLisandro Dalcin 
503dfe15315SJed Brown static PetscErrorCode DMRestrictHook_SNESVecSol(DM dmfine,Mat Restrict,Vec Rscale,Mat Inject,DM dmcoarse,void *ctx)
504dfe15315SJed Brown {
505dfe15315SJed Brown   SNES           snes = (SNES)ctx;
506dfe15315SJed Brown   PetscErrorCode ierr;
5070298fd71SBarry Smith   Vec            Xfine,Xfine_named = NULL,Xcoarse;
508dfe15315SJed Brown 
509dfe15315SJed Brown   PetscFunctionBegin;
51016ebb321SJed Brown   if (PetscLogPrintInfo) {
51116ebb321SJed Brown     PetscInt finelevel,coarselevel,fineclevel,coarseclevel;
51216ebb321SJed Brown     ierr = DMGetRefineLevel(dmfine,&finelevel);CHKERRQ(ierr);
51316ebb321SJed Brown     ierr = DMGetCoarsenLevel(dmfine,&fineclevel);CHKERRQ(ierr);
51416ebb321SJed Brown     ierr = DMGetRefineLevel(dmcoarse,&coarselevel);CHKERRQ(ierr);
51516ebb321SJed Brown     ierr = DMGetCoarsenLevel(dmcoarse,&coarseclevel);CHKERRQ(ierr);
51616ebb321SJed Brown     ierr = PetscInfo4(dmfine,"Restricting SNES solution vector from level %D-%D to level %D-%D\n",finelevel,fineclevel,coarselevel,coarseclevel);CHKERRQ(ierr);
51716ebb321SJed Brown   }
518dfe15315SJed Brown   if (dmfine == snes->dm) Xfine = snes->vec_sol;
519dfe15315SJed Brown   else {
520dfe15315SJed Brown     ierr  = DMGetNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);
521dfe15315SJed Brown     Xfine = Xfine_named;
522dfe15315SJed Brown   }
523dfe15315SJed Brown   ierr = DMGetNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr);
524907f5c5aSLawrence Mitchell   if (Inject) {
525907f5c5aSLawrence Mitchell     ierr = MatRestrict(Inject,Xfine,Xcoarse);CHKERRQ(ierr);
526907f5c5aSLawrence Mitchell   } else {
527dfe15315SJed Brown     ierr = MatRestrict(Restrict,Xfine,Xcoarse);CHKERRQ(ierr);
528dfe15315SJed Brown     ierr = VecPointwiseMult(Xcoarse,Xcoarse,Rscale);CHKERRQ(ierr);
529907f5c5aSLawrence Mitchell   }
530dfe15315SJed Brown   ierr = DMRestoreNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr);
531dfe15315SJed Brown   if (Xfine_named) {ierr = DMRestoreNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);}
532dfe15315SJed Brown   PetscFunctionReturn(0);
533dfe15315SJed Brown }
534dfe15315SJed Brown 
53516ebb321SJed Brown static PetscErrorCode DMCoarsenHook_SNESVecSol(DM dm,DM dmc,void *ctx)
53616ebb321SJed Brown {
53716ebb321SJed Brown   PetscErrorCode ierr;
53816ebb321SJed Brown 
53916ebb321SJed Brown   PetscFunctionBegin;
54016ebb321SJed Brown   ierr = DMCoarsenHookAdd(dmc,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,ctx);CHKERRQ(ierr);
54116ebb321SJed Brown   PetscFunctionReturn(0);
54216ebb321SJed Brown }
54316ebb321SJed Brown 
544a6950cb2SJed Brown /* This may be called to rediscretize the operator on levels of linear multigrid. The DM shuffle is so the user can
545a6950cb2SJed Brown  * safely call SNESGetDM() in their residual evaluation routine. */
54623ee1639SBarry Smith static PetscErrorCode KSPComputeOperators_SNES(KSP ksp,Mat A,Mat B,void *ctx)
547caa4e7f2SJed Brown {
548caa4e7f2SJed Brown   SNES           snes = (SNES)ctx;
549caa4e7f2SJed Brown   PetscErrorCode ierr;
550caa4e7f2SJed Brown   Mat            Asave = A,Bsave = B;
5510298fd71SBarry Smith   Vec            X,Xnamed = NULL;
552dfe15315SJed Brown   DM             dmsave;
5534e269d77SPeter Brune   void           *ctxsave;
554d1e9a80fSBarry Smith   PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*);
555caa4e7f2SJed Brown 
556caa4e7f2SJed Brown   PetscFunctionBegin;
557dfe15315SJed Brown   dmsave = snes->dm;
558dfe15315SJed Brown   ierr   = KSPGetDM(ksp,&snes->dm);CHKERRQ(ierr);
559dfe15315SJed Brown   if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */
560dfe15315SJed Brown   else {                                     /* We are on a coarser level, this vec was initialized using a DM restrict hook */
561dfe15315SJed Brown     ierr = DMGetNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr);
562dfe15315SJed Brown     X    = Xnamed;
5630298fd71SBarry Smith     ierr = SNESGetJacobian(snes,NULL,NULL,&jac,&ctxsave);CHKERRQ(ierr);
5644e269d77SPeter Brune     /* If the DM's don't match up, the MatFDColoring context needed for the jacobian won't match up either -- fixit. */
5658d359177SBarry Smith     if (jac == SNESComputeJacobianDefaultColor) {
5668d359177SBarry Smith       ierr = SNESSetJacobian(snes,NULL,NULL,SNESComputeJacobianDefaultColor,0);CHKERRQ(ierr);
567dfe15315SJed Brown     }
5684e269d77SPeter Brune   }
5694e269d77SPeter Brune   /* put the previous context back */
5704e269d77SPeter Brune 
571d1e9a80fSBarry Smith   ierr = SNESComputeJacobian(snes,X,A,B);CHKERRQ(ierr);
5728d359177SBarry Smith   if (snes->dm != dmsave && jac == SNESComputeJacobianDefaultColor) {
5730298fd71SBarry Smith     ierr = SNESSetJacobian(snes,NULL,NULL,jac,ctxsave);CHKERRQ(ierr);
5744e269d77SPeter Brune   }
5754e269d77SPeter Brune 
576ce94432eSBarry Smith   if (A != Asave || B != Bsave) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"No support for changing matrices at this time");
577dfe15315SJed Brown   if (Xnamed) {
578dfe15315SJed Brown     ierr = DMRestoreNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr);
579dfe15315SJed Brown   }
580dfe15315SJed Brown   snes->dm = dmsave;
581caa4e7f2SJed Brown   PetscFunctionReturn(0);
582caa4e7f2SJed Brown }
583caa4e7f2SJed Brown 
5846cab3a1bSJed Brown /*@
5856cab3a1bSJed Brown    SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX()
5866cab3a1bSJed Brown 
5876cab3a1bSJed Brown    Collective
5886cab3a1bSJed Brown 
5896cab3a1bSJed Brown    Input Arguments:
5906cab3a1bSJed Brown .  snes - snes to configure
5916cab3a1bSJed Brown 
5926cab3a1bSJed Brown    Level: developer
5936cab3a1bSJed Brown 
5946cab3a1bSJed Brown .seealso: SNESSetUp()
5956cab3a1bSJed Brown @*/
5966cab3a1bSJed Brown PetscErrorCode SNESSetUpMatrices(SNES snes)
5976cab3a1bSJed Brown {
5986cab3a1bSJed Brown   PetscErrorCode ierr;
5996cab3a1bSJed Brown   DM             dm;
600942e3340SBarry Smith   DMSNES         sdm;
6016cab3a1bSJed Brown 
6026cab3a1bSJed Brown   PetscFunctionBegin;
6036cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
604942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
605ce94432eSBarry Smith   if (!sdm->ops->computejacobian) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_PLIB,"DMSNES not properly configured");
606f5af7f23SKarl Rupp   else if (!snes->jacobian && snes->mf) {
6076cab3a1bSJed Brown     Mat  J;
6086cab3a1bSJed Brown     void *functx;
6096cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
6106cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
6116cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
6120298fd71SBarry Smith     ierr = SNESGetFunction(snes,NULL,NULL,&functx);CHKERRQ(ierr);
6133232da50SPeter Brune     ierr = SNESSetJacobian(snes,J,J,0,0);CHKERRQ(ierr);
6146cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
615caa4e7f2SJed Brown   } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) {
6166cab3a1bSJed Brown     Mat J,B;
6176cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
6186cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
6196cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
620b412c318SBarry Smith     ierr = DMCreateMatrix(snes->dm,&B);CHKERRQ(ierr);
62106f20277SJed Brown     /* sdm->computejacobian was already set to reach here */
6220298fd71SBarry Smith     ierr = SNESSetJacobian(snes,J,B,NULL,NULL);CHKERRQ(ierr);
6236cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
6246cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
625caa4e7f2SJed Brown   } else if (!snes->jacobian_pre) {
6261ba9b98eSMatthew G. Knepley     PetscDS   prob;
6276cab3a1bSJed Brown     Mat       J, B;
6281ba9b98eSMatthew G. Knepley     PetscBool hasPrec = PETSC_FALSE;
6291ba9b98eSMatthew G. Knepley 
6306cab3a1bSJed Brown     J    = snes->jacobian;
6311ba9b98eSMatthew G. Knepley     ierr = DMGetDS(dm, &prob);CHKERRQ(ierr);
6321ba9b98eSMatthew G. Knepley     if (prob) {ierr = PetscDSHasJacobianPreconditioner(prob, &hasPrec);CHKERRQ(ierr);}
633ec9a985fSMatthew G. Knepley     if (J)            {ierr = PetscObjectReference((PetscObject) J);CHKERRQ(ierr);}
634ec9a985fSMatthew G. Knepley     else if (hasPrec) {ierr = DMCreateMatrix(snes->dm, &J);CHKERRQ(ierr);}
635b412c318SBarry Smith     ierr = DMCreateMatrix(snes->dm, &B);CHKERRQ(ierr);
6360298fd71SBarry Smith     ierr = SNESSetJacobian(snes, J ? J : B, B, NULL, NULL);CHKERRQ(ierr);
6371ba9b98eSMatthew G. Knepley     ierr = MatDestroy(&J);CHKERRQ(ierr);
6386cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
6396cab3a1bSJed Brown   }
640caa4e7f2SJed Brown   {
641caa4e7f2SJed Brown     KSP ksp;
642caa4e7f2SJed Brown     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
643caa4e7f2SJed Brown     ierr = KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes);CHKERRQ(ierr);
64416ebb321SJed Brown     ierr = DMCoarsenHookAdd(snes->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr);
645caa4e7f2SJed Brown   }
6466cab3a1bSJed Brown   PetscFunctionReturn(0);
6476cab3a1bSJed Brown }
6486cab3a1bSJed Brown 
649fde5950dSBarry Smith /*@C
650fde5950dSBarry Smith    SNESMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user
651fde5950dSBarry Smith 
652fde5950dSBarry Smith    Collective on SNES
653fde5950dSBarry Smith 
654fde5950dSBarry Smith    Input Parameters:
655fde5950dSBarry Smith +  snes - SNES object you wish to monitor
656fde5950dSBarry Smith .  name - the monitor type one is seeking
657fde5950dSBarry Smith .  help - message indicating what monitoring is done
658fde5950dSBarry Smith .  manual - manual page for the monitor
659fde5950dSBarry Smith .  monitor - the monitor function
660fde5950dSBarry 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
661fde5950dSBarry Smith 
662fde5950dSBarry Smith    Level: developer
663fde5950dSBarry Smith 
664fde5950dSBarry Smith .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
665fde5950dSBarry Smith           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
666fde5950dSBarry Smith           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
667fde5950dSBarry Smith           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
668fde5950dSBarry Smith           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
669fde5950dSBarry Smith           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
670fde5950dSBarry Smith           PetscOptionsFList(), PetscOptionsEList()
671fde5950dSBarry Smith @*/
672d43b4f6eSBarry Smith PetscErrorCode  SNESMonitorSetFromOptions(SNES snes,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(SNES,PetscViewerAndFormat*))
673fde5950dSBarry Smith {
674fde5950dSBarry Smith   PetscErrorCode    ierr;
675fde5950dSBarry Smith   PetscViewer       viewer;
676fde5950dSBarry Smith   PetscViewerFormat format;
677fde5950dSBarry Smith   PetscBool         flg;
678fde5950dSBarry Smith 
679fde5950dSBarry Smith   PetscFunctionBegin;
680fde5950dSBarry Smith   ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,name,&viewer,&format,&flg);CHKERRQ(ierr);
681fde5950dSBarry Smith   if (flg) {
682d43b4f6eSBarry Smith     PetscViewerAndFormat *vf;
683d43b4f6eSBarry Smith     ierr = PetscViewerAndFormatCreate(viewer,format,&vf);CHKERRQ(ierr);
684d43b4f6eSBarry Smith     ierr = PetscObjectDereference((PetscObject)viewer);CHKERRQ(ierr);
685fde5950dSBarry Smith     if (monitorsetup) {
686d43b4f6eSBarry Smith       ierr = (*monitorsetup)(snes,vf);CHKERRQ(ierr);
687fde5950dSBarry Smith     }
688d43b4f6eSBarry Smith     ierr = SNESMonitorSet(snes,(PetscErrorCode (*)(SNES,PetscInt,PetscReal,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy);CHKERRQ(ierr);
689fde5950dSBarry Smith   }
690fde5950dSBarry Smith   PetscFunctionReturn(0);
691fde5950dSBarry Smith }
692fde5950dSBarry Smith 
6939b94acceSBarry Smith /*@
69494b7f48cSBarry Smith    SNESSetFromOptions - Sets various SNES and KSP parameters from user options.
6959b94acceSBarry Smith 
696c7afd0dbSLois Curfman McInnes    Collective on SNES
697c7afd0dbSLois Curfman McInnes 
6989b94acceSBarry Smith    Input Parameter:
6999b94acceSBarry Smith .  snes - the SNES context
7009b94acceSBarry Smith 
70136851e7fSLois Curfman McInnes    Options Database Keys:
702722329fbSBarry Smith +  -snes_type <type> - newtonls, newtontr, ngmres, ncg, nrichardson, qn, vi, fas, SNESType for complete list
70382738288SBarry Smith .  -snes_stol - convergence tolerance in terms of the norm
70482738288SBarry Smith                 of the change in the solution between steps
70570441072SBarry Smith .  -snes_atol <abstol> - absolute tolerance of residual norm
706b39c3a46SLois Curfman McInnes .  -snes_rtol <rtol> - relative decrease in tolerance norm from initial
707e4d06f11SPatrick Farrell .  -snes_divergence_tolerance <divtol> - if the residual goes above divtol*rnorm0, exit with divergence
708b39c3a46SLois Curfman McInnes .  -snes_max_it <max_it> - maximum number of iterations
709b39c3a46SLois Curfman McInnes .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
7104839bfe8SBarry Smith .  -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none
711ddf469c8SBarry Smith .  -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops
712a8054027SBarry Smith .  -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild)
713e35cf81dSBarry Smith .  -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild)
714b39c3a46SLois Curfman McInnes .  -snes_trtol <trtol> - trust region tolerance
7152492ecdbSBarry Smith .  -snes_no_convergence_test - skip convergence test in nonlinear
71682738288SBarry Smith                                solver; hence iterations will continue until max_it
7171fbbfb26SLois Curfman McInnes                                or some other criterion is reached. Saves expense
71882738288SBarry Smith                                of convergence test
719fde5950dSBarry Smith .  -snes_monitor [ascii][:filename][:viewer format] - prints residual norm at each iteration. if no filename given prints to stdout
720fde5950dSBarry Smith .  -snes_monitor_solution [ascii binary draw][:filename][:viewer format] - plots solution at each iteration
721fde5950dSBarry Smith .  -snes_monitor_residual [ascii binary draw][:filename][:viewer format] - plots residual (not its norm) at each iteration
722fde5950dSBarry Smith .  -snes_monitor_solution_update [ascii binary draw][:filename][:viewer format] - plots update to solution at each iteration
7234619e776SBarry Smith .  -snes_monitor_lg_residualnorm - plots residual norm at each iteration
724459f5d12SBarry Smith .  -snes_monitor_lg_range - plots residual norm at each iteration
725e24b481bSBarry Smith .  -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
726e2e60de9SPeter Brune .  -snes_fd_color - use finite differences with coloring to compute Jacobian
7275968eb51SBarry Smith .  -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
728fee2055bSBarry Smith -  -snes_converged_reason - print the reason for convergence/divergence after each solve
72982738288SBarry Smith 
73082738288SBarry Smith     Options Database for Eisenstat-Walker method:
731fa9f3622SBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
7324b27c08aSLois Curfman McInnes .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
73336851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
73436851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
73536851e7fSLois Curfman McInnes .  -snes_ksp_ew_gamma <gamma> - Sets gamma
73636851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha <alpha> - Sets alpha
73736851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
73836851e7fSLois Curfman McInnes -  -snes_ksp_ew_threshold <threshold> - Sets threshold
73982738288SBarry Smith 
74011ca99fdSLois Curfman McInnes    Notes:
74111ca99fdSLois Curfman McInnes    To see all options, run your program with the -help option or consult
742a7f22e61SSatish Balay    Users-Manual: ch_snes
74383e2fdc7SBarry Smith 
74436851e7fSLois Curfman McInnes    Level: beginner
74536851e7fSLois Curfman McInnes 
7469b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database
7479b94acceSBarry Smith 
74869ed319cSSatish Balay .seealso: SNESSetOptionsPrefix()
7499b94acceSBarry Smith @*/
7507087cfbeSBarry Smith PetscErrorCode  SNESSetFromOptions(SNES snes)
7519b94acceSBarry Smith {
7528afaa268SBarry Smith   PetscBool      flg,pcset,persist,set;
753d8f46077SPeter Brune   PetscInt       i,indx,lag,grids;
75404d7464bSBarry Smith   const char     *deft        = SNESNEWTONLS;
75585385478SLisandro Dalcin   const char     *convtests[] = {"default","skip"};
75685385478SLisandro Dalcin   SNESKSPEW      *kctx        = NULL;
757e8105e01SRichard Katz   char           type[256], monfilename[PETSC_MAX_PATH_LEN];
75885385478SLisandro Dalcin   PetscErrorCode ierr;
759c40d0f55SPeter Brune   PCSide         pcside;
760a64e098fSPeter Brune   const char     *optionsprefix;
7619b94acceSBarry Smith 
7623a40ed3dSBarry Smith   PetscFunctionBegin;
7630700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
7640f51fdf8SToby Isaac   ierr = SNESRegisterAll();CHKERRQ(ierr);
7653194b578SJed Brown   ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr);
766639ff905SBarry Smith   if (((PetscObject)snes)->type_name) deft = ((PetscObject)snes)->type_name;
767a264d7a6SBarry Smith   ierr = PetscOptionsFList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr);
768d64ed03dSBarry Smith   if (flg) {
769186905e3SBarry Smith     ierr = SNESSetType(snes,type);CHKERRQ(ierr);
7707adad957SLisandro Dalcin   } else if (!((PetscObject)snes)->type_name) {
771186905e3SBarry Smith     ierr = SNESSetType(snes,deft);CHKERRQ(ierr);
772d64ed03dSBarry Smith   }
77394ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,NULL);CHKERRQ(ierr);
77494ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,NULL);CHKERRQ(ierr);
775186905e3SBarry Smith 
77694ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,NULL);CHKERRQ(ierr);
777e4d06f11SPatrick Farrell   ierr = PetscOptionsReal("-snes_divergence_tolerance","Stop if residual norm increases by this factor","SNESSetDivergenceTolerance",snes->divtol,&snes->divtol,NULL);CHKERRQ(ierr);
7780298fd71SBarry Smith   ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,NULL);CHKERRQ(ierr);
7790298fd71SBarry Smith   ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,NULL);CHKERRQ(ierr);
7800298fd71SBarry Smith   ierr = PetscOptionsInt("-snes_max_fail","Maximum nonlinear step failures","SNESSetMaxNonlinearStepFailures",snes->maxFailures,&snes->maxFailures,NULL);CHKERRQ(ierr);
7810298fd71SBarry Smith   ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,NULL);CHKERRQ(ierr);
7820298fd71SBarry Smith   ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,NULL);CHKERRQ(ierr);
78385385478SLisandro Dalcin 
784a8054027SBarry Smith   ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr);
785a8054027SBarry Smith   if (flg) {
786a8054027SBarry Smith     ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr);
787a8054027SBarry Smith   }
78837ec4e1aSPeter Brune   ierr = PetscOptionsBool("-snes_lag_preconditioner_persists","Preconditioner lagging through multiple solves","SNESSetLagPreconditionerPersists",snes->lagjac_persist,&persist,&flg);CHKERRQ(ierr);
78937ec4e1aSPeter Brune   if (flg) {
79037ec4e1aSPeter Brune     ierr = SNESSetLagPreconditionerPersists(snes,persist);CHKERRQ(ierr);
79137ec4e1aSPeter Brune   }
792e35cf81dSBarry Smith   ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr);
793e35cf81dSBarry Smith   if (flg) {
794e35cf81dSBarry Smith     ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr);
795e35cf81dSBarry Smith   }
79637ec4e1aSPeter Brune   ierr = PetscOptionsBool("-snes_lag_jacobian_persists","Jacobian lagging through multiple solves","SNESSetLagJacobianPersists",snes->lagjac_persist,&persist,&flg);CHKERRQ(ierr);
79737ec4e1aSPeter Brune   if (flg) {
79837ec4e1aSPeter Brune     ierr = SNESSetLagJacobianPersists(snes,persist);CHKERRQ(ierr);
79937ec4e1aSPeter Brune   }
80037ec4e1aSPeter Brune 
801efd51863SBarry Smith   ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr);
802efd51863SBarry Smith   if (flg) {
803efd51863SBarry Smith     ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr);
804efd51863SBarry Smith   }
805a8054027SBarry Smith 
80685385478SLisandro Dalcin   ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr);
80785385478SLisandro Dalcin   if (flg) {
80885385478SLisandro Dalcin     switch (indx) {
8098d359177SBarry Smith     case 0: ierr = SNESSetConvergenceTest(snes,SNESConvergedDefault,NULL,NULL);CHKERRQ(ierr); break;
810e2a6519dSDmitry Karpeev     case 1: ierr = SNESSetConvergenceTest(snes,SNESConvergedSkip,NULL,NULL);CHKERRQ(ierr);    break;
81185385478SLisandro Dalcin     }
81285385478SLisandro Dalcin   }
81385385478SLisandro Dalcin 
814365a6726SPeter Brune   ierr = PetscOptionsEList("-snes_norm_schedule","SNES Norm schedule","SNESSetNormSchedule",SNESNormSchedules,5,"function",&indx,&flg);CHKERRQ(ierr);
815365a6726SPeter Brune   if (flg) { ierr = SNESSetNormSchedule(snes,(SNESNormSchedule)indx);CHKERRQ(ierr); }
816fdacfa88SPeter Brune 
81747073ea2SPeter Brune   ierr = PetscOptionsEList("-snes_function_type","SNES Norm schedule","SNESSetFunctionType",SNESFunctionTypes,2,"unpreconditioned",&indx,&flg);CHKERRQ(ierr);
81847073ea2SPeter Brune   if (flg) { ierr = SNESSetFunctionType(snes,(SNESFunctionType)indx);CHKERRQ(ierr); }
819186905e3SBarry Smith 
82085385478SLisandro Dalcin   kctx = (SNESKSPEW*)snes->kspconvctx;
82185385478SLisandro Dalcin 
8220298fd71SBarry Smith   ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,NULL);CHKERRQ(ierr);
823186905e3SBarry Smith 
82494ae4db5SBarry Smith   ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,NULL);CHKERRQ(ierr);
82594ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,NULL);CHKERRQ(ierr);
82694ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,NULL);CHKERRQ(ierr);
82794ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,NULL);CHKERRQ(ierr);
82894ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,NULL);CHKERRQ(ierr);
82994ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,NULL);CHKERRQ(ierr);
83094ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,NULL);CHKERRQ(ierr);
831186905e3SBarry Smith 
83290d69ab7SBarry Smith   flg  = PETSC_FALSE;
8338afaa268SBarry Smith   ierr = PetscOptionsBool("-snes_check_jacobian","Check each Jacobian with a differenced one","SNESUpdateCheckJacobian",flg,&flg,&set);CHKERRQ(ierr);
8348afaa268SBarry Smith   if (set && flg) {
8355341784dSBarry Smith     ierr = SNESSetUpdate(snes,SNESUpdateCheckJacobian);CHKERRQ(ierr);
8365341784dSBarry Smith   }
8375341784dSBarry Smith 
8385341784dSBarry Smith   flg  = PETSC_FALSE;
8398afaa268SBarry Smith   ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,&set);CHKERRQ(ierr);
8408afaa268SBarry Smith   if (set && flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);}
841eabae89aSBarry Smith 
842fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor","Monitor norm of function","SNESMonitorDefault",SNESMonitorDefault,NULL);CHKERRQ(ierr);
843fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_short","Monitor norm of function with fewer digits","SNESMonitorDefaultShort",SNESMonitorDefaultShort,NULL);CHKERRQ(ierr);
844fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_range","Monitor range of elements of function","SNESMonitorRange",SNESMonitorRange,NULL);CHKERRQ(ierr);
845eabae89aSBarry Smith 
846fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_ratio","Monitor ratios of the norm of function for consecutive steps","SNESMonitorRatio",SNESMonitorRatio,SNESMonitorRatioSetUp);CHKERRQ(ierr);
847fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_field","Monitor norm of function (split into fields)","SNESMonitorDefaultField",SNESMonitorDefaultField,NULL);CHKERRQ(ierr);
848fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_solution","View solution at each iteration","SNESMonitorSolution",SNESMonitorSolution,NULL);CHKERRQ(ierr);
849fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_solution_update","View correction at each iteration","SNESMonitorSolutionUpdate",SNESMonitorSolutionUpdate,NULL);CHKERRQ(ierr);
850fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_residual","View residual at each iteration","SNESMonitorResidual",SNESMonitorResidual,NULL);CHKERRQ(ierr);
851fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_jacupdate_spectrum","Print the change in the spectrum of the Jacobian","SNESMonitorJacUpdateSpectrum",SNESMonitorJacUpdateSpectrum,NULL);CHKERRQ(ierr);
852fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_fields","Monitor norm of function per field","SNESMonitorSet",SNESMonitorFields,NULL);CHKERRQ(ierr);
8532db13446SMatthew G. Knepley 
8545180491cSLisandro Dalcin   ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
8555180491cSLisandro Dalcin   if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);}
8565180491cSLisandro Dalcin 
857fde5950dSBarry Smith 
85890d69ab7SBarry Smith   flg  = PETSC_FALSE;
8590298fd71SBarry Smith   ierr = PetscOptionsBool("-snes_monitor_lg_residualnorm","Plot function norm at each iteration","SNESMonitorLGResidualNorm",flg,&flg,NULL);CHKERRQ(ierr);
860459f5d12SBarry Smith   if (flg) {
861d96771aaSLisandro Dalcin     PetscDrawLG ctx;
862459f5d12SBarry Smith 
8636ba87a44SLisandro Dalcin     ierr = SNESMonitorLGCreate(PetscObjectComm((PetscObject)snes),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);CHKERRQ(ierr);
864d96771aaSLisandro Dalcin     ierr = SNESMonitorSet(snes,SNESMonitorLGResidualNorm,ctx,(PetscErrorCode (*)(void**))PetscDrawLGDestroy);CHKERRQ(ierr);
865459f5d12SBarry Smith   }
86690d69ab7SBarry Smith   flg  = PETSC_FALSE;
8670298fd71SBarry Smith   ierr = PetscOptionsBool("-snes_monitor_lg_range","Plot function range at each iteration","SNESMonitorLGRange",flg,&flg,NULL);CHKERRQ(ierr);
868459f5d12SBarry Smith   if (flg) {
869459f5d12SBarry Smith     PetscViewer ctx;
870e24b481bSBarry Smith 
8716ba87a44SLisandro Dalcin     ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);CHKERRQ(ierr);
872459f5d12SBarry Smith     ierr = SNESMonitorSet(snes,SNESMonitorLGRange,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
873459f5d12SBarry Smith   }
8742e7541e6SPeter Brune 
8752e7541e6SPeter Brune 
876cc0c4584SMatthew G. Knepley 
87790d69ab7SBarry Smith   flg  = PETSC_FALSE;
8788d359177SBarry Smith   ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESComputeJacobianDefault",flg,&flg,NULL);CHKERRQ(ierr);
8794b27c08aSLois Curfman McInnes   if (flg) {
8806cab3a1bSJed Brown     void *functx;
8810298fd71SBarry Smith     ierr = SNESGetFunction(snes,NULL,NULL,&functx);CHKERRQ(ierr);
8828d359177SBarry Smith     ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESComputeJacobianDefault,functx);CHKERRQ(ierr);
883ae15b995SBarry Smith     ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr);
8849b94acceSBarry Smith   }
885639f9d9dSBarry Smith 
88644848bc4SPeter Brune   flg  = PETSC_FALSE;
8878d359177SBarry Smith   ierr = PetscOptionsBool("-snes_fd_function","Use finite differences (slow) to compute function from user objective","SNESObjectiveComputeFunctionDefaultFD",flg,&flg,NULL);CHKERRQ(ierr);
88897584545SPeter Brune   if (flg) {
8898d359177SBarry Smith     ierr = SNESSetFunction(snes,NULL,SNESObjectiveComputeFunctionDefaultFD,NULL);CHKERRQ(ierr);
89097584545SPeter Brune   }
89197584545SPeter Brune 
89297584545SPeter Brune   flg  = PETSC_FALSE;
8938d359177SBarry Smith   ierr = PetscOptionsBool("-snes_fd_color","Use finite differences with coloring to compute Jacobian","SNESComputeJacobianDefaultColor",flg,&flg,NULL);CHKERRQ(ierr);
89444848bc4SPeter Brune   if (flg) {
895c52e227fSPeter Brune     DM             dm;
896c52e227fSPeter Brune     DMSNES         sdm;
897c52e227fSPeter Brune     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
898aace71b7SPeter Brune     ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
899aace71b7SPeter Brune     sdm->jacobianctx = NULL;
9008d359177SBarry Smith     ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESComputeJacobianDefaultColor,0);CHKERRQ(ierr);
90144848bc4SPeter Brune     ierr = PetscInfo(snes,"Setting default finite difference coloring Jacobian matrix\n");CHKERRQ(ierr);
90244848bc4SPeter Brune   }
90344848bc4SPeter Brune 
904aa3661deSLisandro Dalcin   flg  = PETSC_FALSE;
905d8f46077SPeter 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);
906d8f46077SPeter Brune   if (flg && snes->mf_operator) {
907a8248277SBarry Smith     snes->mf_operator = PETSC_TRUE;
908d8f46077SPeter Brune     snes->mf          = PETSC_TRUE;
909a8248277SBarry Smith   }
910aa3661deSLisandro Dalcin   flg  = PETSC_FALSE;
911d8f46077SPeter Brune   ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&snes->mf,&flg);CHKERRQ(ierr);
912d8f46077SPeter Brune   if (!flg && snes->mf_operator) snes->mf = PETSC_TRUE;
913d8f46077SPeter Brune   ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",snes->mf_version,&snes->mf_version,0);CHKERRQ(ierr);
914d28543b3SPeter Brune 
915c40d0f55SPeter Brune   flg  = PETSC_FALSE;
916be95d8f1SBarry Smith   ierr = SNESGetNPCSide(snes,&pcside);CHKERRQ(ierr);
917be95d8f1SBarry Smith   ierr = PetscOptionsEnum("-snes_npc_side","SNES nonlinear preconditioner side","SNESSetNPCSide",PCSides,(PetscEnum)pcside,(PetscEnum*)&pcside,&flg);CHKERRQ(ierr);
918be95d8f1SBarry Smith   if (flg) {ierr = SNESSetNPCSide(snes,pcside);CHKERRQ(ierr);}
919c40d0f55SPeter Brune 
920e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
9218a70d858SHong Zhang   /*
9228a70d858SHong Zhang     Publish convergence information using SAWs
9238a70d858SHong Zhang   */
9248a70d858SHong Zhang   flg  = PETSC_FALSE;
9258a70d858SHong Zhang   ierr = PetscOptionsBool("-snes_monitor_saws","Publish SNES progress using SAWs","SNESMonitorSet",flg,&flg,NULL);CHKERRQ(ierr);
9268a70d858SHong Zhang   if (flg) {
9278a70d858SHong Zhang     void *ctx;
9288a70d858SHong Zhang     ierr = SNESMonitorSAWsCreate(snes,&ctx);CHKERRQ(ierr);
9298a70d858SHong Zhang     ierr = SNESMonitorSet(snes,SNESMonitorSAWs,ctx,SNESMonitorSAWsDestroy);CHKERRQ(ierr);
9308a70d858SHong Zhang   }
9318a70d858SHong Zhang #endif
9328a70d858SHong Zhang #if defined(PETSC_HAVE_SAWS)
933b90c6cbeSBarry Smith   {
934b90c6cbeSBarry Smith   PetscBool set;
935b90c6cbeSBarry Smith   flg  = PETSC_FALSE;
9368a70d858SHong Zhang   ierr = PetscOptionsBool("-snes_saws_block","Block for SAWs at end of SNESSolve","PetscObjectSAWsBlock",((PetscObject)snes)->amspublishblock,&flg,&set);CHKERRQ(ierr);
937b90c6cbeSBarry Smith   if (set) {
938e04113cfSBarry Smith     ierr = PetscObjectSAWsSetBlock((PetscObject)snes,flg);CHKERRQ(ierr);
939b90c6cbeSBarry Smith   }
940b90c6cbeSBarry Smith   }
941b90c6cbeSBarry Smith #endif
942b90c6cbeSBarry Smith 
94376b2cf59SMatthew Knepley   for (i = 0; i < numberofsetfromoptions; i++) {
94476b2cf59SMatthew Knepley     ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr);
94576b2cf59SMatthew Knepley   }
94676b2cf59SMatthew Knepley 
947e7788613SBarry Smith   if (snes->ops->setfromoptions) {
948e55864a3SBarry Smith     ierr = (*snes->ops->setfromoptions)(PetscOptionsObject,snes);CHKERRQ(ierr);
949639f9d9dSBarry Smith   }
9505d973c19SBarry Smith 
9515d973c19SBarry Smith   /* process any options handlers added with PetscObjectAddOptionsHandler() */
9520633abcbSJed Brown   ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)snes);CHKERRQ(ierr);
953b0a32e0cSBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
9544bbc92c1SBarry Smith 
9559e764e56SPeter Brune   if (!snes->linesearch) {
9567601faf0SJed Brown     ierr = SNESGetLineSearch(snes, &snes->linesearch);CHKERRQ(ierr);
9579e764e56SPeter Brune   }
958f1c6b773SPeter Brune   ierr = SNESLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr);
9599e764e56SPeter Brune 
9606991f827SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
9616991f827SBarry Smith   ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre);CHKERRQ(ierr);
9626991f827SBarry Smith   ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr);
9636991f827SBarry Smith 
964be95d8f1SBarry Smith   /* if someone has set the SNES NPC type, create it. */
96551e86f29SPeter Brune   ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
966c5929fdfSBarry Smith   ierr = PetscOptionsHasName(((PetscObject)snes)->options,optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr);
967*efd4aadfSBarry Smith   if (pcset && (!snes->npc)) {
968*efd4aadfSBarry Smith     ierr = SNESGetNPC(snes, &snes->npc);CHKERRQ(ierr);
96951e86f29SPeter Brune   }
9703a40ed3dSBarry Smith   PetscFunctionReturn(0);
9719b94acceSBarry Smith }
9729b94acceSBarry Smith 
973bb9467b5SJed Brown /*@C
974d25893d9SBarry Smith    SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for
975d25893d9SBarry Smith    the nonlinear solvers.
976d25893d9SBarry Smith 
977d25893d9SBarry Smith    Logically Collective on SNES
978d25893d9SBarry Smith 
979d25893d9SBarry Smith    Input Parameters:
980d25893d9SBarry Smith +  snes - the SNES context
981d25893d9SBarry Smith .  compute - function to compute the context
982d25893d9SBarry Smith -  destroy - function to destroy the context
983d25893d9SBarry Smith 
984d25893d9SBarry Smith    Level: intermediate
985d25893d9SBarry Smith 
986bb9467b5SJed Brown    Notes:
987bb9467b5SJed Brown    This function is currently not available from Fortran.
988bb9467b5SJed Brown 
989d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context
990d25893d9SBarry Smith 
991d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext()
992d25893d9SBarry Smith @*/
993d25893d9SBarry Smith PetscErrorCode  SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**))
994d25893d9SBarry Smith {
995d25893d9SBarry Smith   PetscFunctionBegin;
996d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
997d25893d9SBarry Smith   snes->ops->usercompute = compute;
998d25893d9SBarry Smith   snes->ops->userdestroy = destroy;
999d25893d9SBarry Smith   PetscFunctionReturn(0);
1000d25893d9SBarry Smith }
1001a847f771SSatish Balay 
1002b07ff414SBarry Smith /*@
10039b94acceSBarry Smith    SNESSetApplicationContext - Sets the optional user-defined context for
10049b94acceSBarry Smith    the nonlinear solvers.
10059b94acceSBarry Smith 
10063f9fe445SBarry Smith    Logically Collective on SNES
1007fee21e36SBarry Smith 
1008c7afd0dbSLois Curfman McInnes    Input Parameters:
1009c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1010c7afd0dbSLois Curfman McInnes -  usrP - optional user context
1011c7afd0dbSLois Curfman McInnes 
101236851e7fSLois Curfman McInnes    Level: intermediate
101336851e7fSLois Curfman McInnes 
1014daf670e6SBarry Smith    Fortran Notes: To use this from Fortran you must write a Fortran interface definition for this
1015daf670e6SBarry Smith     function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument.
1016daf670e6SBarry Smith 
10179b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context
10189b94acceSBarry Smith 
1019ecaffddaSVictor Eijkhout .seealso: SNESGetApplicationContext()
10209b94acceSBarry Smith @*/
10217087cfbeSBarry Smith PetscErrorCode  SNESSetApplicationContext(SNES snes,void *usrP)
10229b94acceSBarry Smith {
10231b2093e4SBarry Smith   PetscErrorCode ierr;
1024b07ff414SBarry Smith   KSP            ksp;
10251b2093e4SBarry Smith 
10263a40ed3dSBarry Smith   PetscFunctionBegin;
10270700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1028b07ff414SBarry Smith   ierr       = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
1029b07ff414SBarry Smith   ierr       = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr);
10309b94acceSBarry Smith   snes->user = usrP;
10313a40ed3dSBarry Smith   PetscFunctionReturn(0);
10329b94acceSBarry Smith }
103374679c65SBarry Smith 
1034b07ff414SBarry Smith /*@
10359b94acceSBarry Smith    SNESGetApplicationContext - Gets the user-defined context for the
10369b94acceSBarry Smith    nonlinear solvers.
10379b94acceSBarry Smith 
1038c7afd0dbSLois Curfman McInnes    Not Collective
1039c7afd0dbSLois Curfman McInnes 
10409b94acceSBarry Smith    Input Parameter:
10419b94acceSBarry Smith .  snes - SNES context
10429b94acceSBarry Smith 
10439b94acceSBarry Smith    Output Parameter:
10449b94acceSBarry Smith .  usrP - user context
10459b94acceSBarry Smith 
1046daf670e6SBarry Smith    Fortran Notes: To use this from Fortran you must write a Fortran interface definition for this
1047daf670e6SBarry Smith     function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument.
1048daf670e6SBarry Smith 
104936851e7fSLois Curfman McInnes    Level: intermediate
105036851e7fSLois Curfman McInnes 
10519b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context
10529b94acceSBarry Smith 
10539b94acceSBarry Smith .seealso: SNESSetApplicationContext()
10549b94acceSBarry Smith @*/
1055e71120c6SJed Brown PetscErrorCode  SNESGetApplicationContext(SNES snes,void *usrP)
10569b94acceSBarry Smith {
10573a40ed3dSBarry Smith   PetscFunctionBegin;
10580700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1059e71120c6SJed Brown   *(void**)usrP = snes->user;
10603a40ed3dSBarry Smith   PetscFunctionReturn(0);
10619b94acceSBarry Smith }
106274679c65SBarry Smith 
10639b94acceSBarry Smith /*@
1064c8228a4eSBarry Smith    SNESGetIterationNumber - Gets the number of nonlinear iterations completed
1065c8228a4eSBarry Smith    at this time.
10669b94acceSBarry Smith 
1067c7afd0dbSLois Curfman McInnes    Not Collective
1068c7afd0dbSLois Curfman McInnes 
10699b94acceSBarry Smith    Input Parameter:
10709b94acceSBarry Smith .  snes - SNES context
10719b94acceSBarry Smith 
10729b94acceSBarry Smith    Output Parameter:
10739b94acceSBarry Smith .  iter - iteration number
10749b94acceSBarry Smith 
1075c8228a4eSBarry Smith    Notes:
1076c8228a4eSBarry Smith    For example, during the computation of iteration 2 this would return 1.
1077c8228a4eSBarry Smith 
1078c8228a4eSBarry Smith    This is useful for using lagged Jacobians (where one does not recompute the
107908405cd6SLois Curfman McInnes    Jacobian at each SNES iteration). For example, the code
108008405cd6SLois Curfman McInnes .vb
108108405cd6SLois Curfman McInnes       ierr = SNESGetIterationNumber(snes,&it);
108208405cd6SLois Curfman McInnes       if (!(it % 2)) {
108308405cd6SLois Curfman McInnes         [compute Jacobian here]
108408405cd6SLois Curfman McInnes       }
108508405cd6SLois Curfman McInnes .ve
1086c8228a4eSBarry Smith    can be used in your ComputeJacobian() function to cause the Jacobian to be
108708405cd6SLois Curfman McInnes    recomputed every second SNES iteration.
1088c8228a4eSBarry Smith 
108936851e7fSLois Curfman McInnes    Level: intermediate
109036851e7fSLois Curfman McInnes 
10912b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number,
10922b668275SBarry Smith 
109371dbe336SPeter Brune .seealso:   SNESGetLinearSolveIterations()
10949b94acceSBarry Smith @*/
10957087cfbeSBarry Smith PetscErrorCode  SNESGetIterationNumber(SNES snes,PetscInt *iter)
10969b94acceSBarry Smith {
10973a40ed3dSBarry Smith   PetscFunctionBegin;
10980700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10994482741eSBarry Smith   PetscValidIntPointer(iter,2);
11009b94acceSBarry Smith   *iter = snes->iter;
11013a40ed3dSBarry Smith   PetscFunctionReturn(0);
11029b94acceSBarry Smith }
110374679c65SBarry Smith 
1104360c497dSPeter Brune /*@
1105360c497dSPeter Brune    SNESSetIterationNumber - Sets the current iteration number.
1106360c497dSPeter Brune 
1107360c497dSPeter Brune    Not Collective
1108360c497dSPeter Brune 
1109360c497dSPeter Brune    Input Parameter:
1110360c497dSPeter Brune .  snes - SNES context
1111360c497dSPeter Brune .  iter - iteration number
1112360c497dSPeter Brune 
1113360c497dSPeter Brune    Level: developer
1114360c497dSPeter Brune 
1115360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number,
1116360c497dSPeter Brune 
111771dbe336SPeter Brune .seealso:   SNESGetLinearSolveIterations()
1118360c497dSPeter Brune @*/
1119360c497dSPeter Brune PetscErrorCode  SNESSetIterationNumber(SNES snes,PetscInt iter)
1120360c497dSPeter Brune {
1121360c497dSPeter Brune   PetscErrorCode ierr;
1122360c497dSPeter Brune 
1123360c497dSPeter Brune   PetscFunctionBegin;
1124360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1125e04113cfSBarry Smith   ierr       = PetscObjectSAWsTakeAccess((PetscObject)snes);CHKERRQ(ierr);
1126360c497dSPeter Brune   snes->iter = iter;
1127e04113cfSBarry Smith   ierr       = PetscObjectSAWsGrantAccess((PetscObject)snes);CHKERRQ(ierr);
1128360c497dSPeter Brune   PetscFunctionReturn(0);
1129360c497dSPeter Brune }
1130360c497dSPeter Brune 
11319b94acceSBarry Smith /*@
1132b850b91aSLisandro Dalcin    SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
11339b94acceSBarry Smith    attempted by the nonlinear solver.
11349b94acceSBarry Smith 
1135c7afd0dbSLois Curfman McInnes    Not Collective
1136c7afd0dbSLois Curfman McInnes 
11379b94acceSBarry Smith    Input Parameter:
11389b94acceSBarry Smith .  snes - SNES context
11399b94acceSBarry Smith 
11409b94acceSBarry Smith    Output Parameter:
11419b94acceSBarry Smith .  nfails - number of unsuccessful steps attempted
11429b94acceSBarry Smith 
1143c96a6f78SLois Curfman McInnes    Notes:
1144c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
1145c96a6f78SLois Curfman McInnes 
114636851e7fSLois Curfman McInnes    Level: intermediate
114736851e7fSLois Curfman McInnes 
11489b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
114958ebbce7SBarry Smith 
1150e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
115158ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures()
11529b94acceSBarry Smith @*/
11537087cfbeSBarry Smith PetscErrorCode  SNESGetNonlinearStepFailures(SNES snes,PetscInt *nfails)
11549b94acceSBarry Smith {
11553a40ed3dSBarry Smith   PetscFunctionBegin;
11560700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11574482741eSBarry Smith   PetscValidIntPointer(nfails,2);
115850ffb88aSMatthew Knepley   *nfails = snes->numFailures;
115950ffb88aSMatthew Knepley   PetscFunctionReturn(0);
116050ffb88aSMatthew Knepley }
116150ffb88aSMatthew Knepley 
116250ffb88aSMatthew Knepley /*@
1163b850b91aSLisandro Dalcin    SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
116450ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
116550ffb88aSMatthew Knepley 
116650ffb88aSMatthew Knepley    Not Collective
116750ffb88aSMatthew Knepley 
116850ffb88aSMatthew Knepley    Input Parameters:
116950ffb88aSMatthew Knepley +  snes     - SNES context
117050ffb88aSMatthew Knepley -  maxFails - maximum of unsuccessful steps
117150ffb88aSMatthew Knepley 
117250ffb88aSMatthew Knepley    Level: intermediate
117350ffb88aSMatthew Knepley 
117450ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
117558ebbce7SBarry Smith 
1176e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
117758ebbce7SBarry Smith           SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
117850ffb88aSMatthew Knepley @*/
11797087cfbeSBarry Smith PetscErrorCode  SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
118050ffb88aSMatthew Knepley {
118150ffb88aSMatthew Knepley   PetscFunctionBegin;
11820700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
118350ffb88aSMatthew Knepley   snes->maxFailures = maxFails;
118450ffb88aSMatthew Knepley   PetscFunctionReturn(0);
118550ffb88aSMatthew Knepley }
118650ffb88aSMatthew Knepley 
118750ffb88aSMatthew Knepley /*@
1188b850b91aSLisandro Dalcin    SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
118950ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
119050ffb88aSMatthew Knepley 
119150ffb88aSMatthew Knepley    Not Collective
119250ffb88aSMatthew Knepley 
119350ffb88aSMatthew Knepley    Input Parameter:
119450ffb88aSMatthew Knepley .  snes     - SNES context
119550ffb88aSMatthew Knepley 
119650ffb88aSMatthew Knepley    Output Parameter:
119750ffb88aSMatthew Knepley .  maxFails - maximum of unsuccessful steps
119850ffb88aSMatthew Knepley 
119950ffb88aSMatthew Knepley    Level: intermediate
120050ffb88aSMatthew Knepley 
120150ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
120258ebbce7SBarry Smith 
1203e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
120458ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
120558ebbce7SBarry Smith 
120650ffb88aSMatthew Knepley @*/
12077087cfbeSBarry Smith PetscErrorCode  SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
120850ffb88aSMatthew Knepley {
120950ffb88aSMatthew Knepley   PetscFunctionBegin;
12100700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
12114482741eSBarry Smith   PetscValidIntPointer(maxFails,2);
121250ffb88aSMatthew Knepley   *maxFails = snes->maxFailures;
12133a40ed3dSBarry Smith   PetscFunctionReturn(0);
12149b94acceSBarry Smith }
1215a847f771SSatish Balay 
12162541af92SBarry Smith /*@
12172541af92SBarry Smith    SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations
12182541af92SBarry Smith      done by SNES.
12192541af92SBarry Smith 
12202541af92SBarry Smith    Not Collective
12212541af92SBarry Smith 
12222541af92SBarry Smith    Input Parameter:
12232541af92SBarry Smith .  snes     - SNES context
12242541af92SBarry Smith 
12252541af92SBarry Smith    Output Parameter:
12262541af92SBarry Smith .  nfuncs - number of evaluations
12272541af92SBarry Smith 
12282541af92SBarry Smith    Level: intermediate
12292541af92SBarry Smith 
1230971e163fSPeter Brune    Notes: Reset every time SNESSolve is called unless SNESSetCountersReset() is used.
1231971e163fSPeter Brune 
12322541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
123358ebbce7SBarry Smith 
1234971e163fSPeter Brune .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), SNESSetCountersReset()
12352541af92SBarry Smith @*/
12367087cfbeSBarry Smith PetscErrorCode  SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs)
12372541af92SBarry Smith {
12382541af92SBarry Smith   PetscFunctionBegin;
12390700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
12402541af92SBarry Smith   PetscValidIntPointer(nfuncs,2);
12412541af92SBarry Smith   *nfuncs = snes->nfuncs;
12422541af92SBarry Smith   PetscFunctionReturn(0);
12432541af92SBarry Smith }
12442541af92SBarry Smith 
12453d4c4710SBarry Smith /*@
12463d4c4710SBarry Smith    SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
12473d4c4710SBarry Smith    linear solvers.
12483d4c4710SBarry Smith 
12493d4c4710SBarry Smith    Not Collective
12503d4c4710SBarry Smith 
12513d4c4710SBarry Smith    Input Parameter:
12523d4c4710SBarry Smith .  snes - SNES context
12533d4c4710SBarry Smith 
12543d4c4710SBarry Smith    Output Parameter:
12553d4c4710SBarry Smith .  nfails - number of failed solves
12563d4c4710SBarry Smith 
12579d85da0cSMatthew G. Knepley    Level: intermediate
12589d85da0cSMatthew G. Knepley 
12599d85da0cSMatthew G. Knepley    Options Database Keys:
12609d85da0cSMatthew G. Knepley . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated
12619d85da0cSMatthew G. Knepley 
12623d4c4710SBarry Smith    Notes:
12633d4c4710SBarry Smith    This counter is reset to zero for each successive call to SNESSolve().
12643d4c4710SBarry Smith 
12653d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
126658ebbce7SBarry Smith 
1267e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures()
12683d4c4710SBarry Smith @*/
12697087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveFailures(SNES snes,PetscInt *nfails)
12703d4c4710SBarry Smith {
12713d4c4710SBarry Smith   PetscFunctionBegin;
12720700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
12733d4c4710SBarry Smith   PetscValidIntPointer(nfails,2);
12743d4c4710SBarry Smith   *nfails = snes->numLinearSolveFailures;
12753d4c4710SBarry Smith   PetscFunctionReturn(0);
12763d4c4710SBarry Smith }
12773d4c4710SBarry Smith 
12783d4c4710SBarry Smith /*@
12793d4c4710SBarry Smith    SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
12803d4c4710SBarry Smith    allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE
12813d4c4710SBarry Smith 
12823f9fe445SBarry Smith    Logically Collective on SNES
12833d4c4710SBarry Smith 
12843d4c4710SBarry Smith    Input Parameters:
12853d4c4710SBarry Smith +  snes     - SNES context
12863d4c4710SBarry Smith -  maxFails - maximum allowed linear solve failures
12873d4c4710SBarry Smith 
12883d4c4710SBarry Smith    Level: intermediate
12893d4c4710SBarry Smith 
12909d85da0cSMatthew G. Knepley    Options Database Keys:
12919d85da0cSMatthew G. Knepley . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated
12929d85da0cSMatthew G. Knepley 
1293a6796414SBarry Smith    Notes: By default this is 0; that is SNES returns on the first failed linear solve
12943d4c4710SBarry Smith 
12953d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
12963d4c4710SBarry Smith 
129758ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations()
12983d4c4710SBarry Smith @*/
12997087cfbeSBarry Smith PetscErrorCode  SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
13003d4c4710SBarry Smith {
13013d4c4710SBarry Smith   PetscFunctionBegin;
13020700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1303c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxFails,2);
13043d4c4710SBarry Smith   snes->maxLinearSolveFailures = maxFails;
13053d4c4710SBarry Smith   PetscFunctionReturn(0);
13063d4c4710SBarry Smith }
13073d4c4710SBarry Smith 
13083d4c4710SBarry Smith /*@
13093d4c4710SBarry Smith    SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
13103d4c4710SBarry Smith      are allowed before SNES terminates
13113d4c4710SBarry Smith 
13123d4c4710SBarry Smith    Not Collective
13133d4c4710SBarry Smith 
13143d4c4710SBarry Smith    Input Parameter:
13153d4c4710SBarry Smith .  snes     - SNES context
13163d4c4710SBarry Smith 
13173d4c4710SBarry Smith    Output Parameter:
13183d4c4710SBarry Smith .  maxFails - maximum of unsuccessful solves allowed
13193d4c4710SBarry Smith 
13203d4c4710SBarry Smith    Level: intermediate
13213d4c4710SBarry Smith 
13223d4c4710SBarry Smith    Notes: By default this is 1; that is SNES returns on the first failed linear solve
13233d4c4710SBarry Smith 
13243d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
13253d4c4710SBarry Smith 
1326e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(),
13273d4c4710SBarry Smith @*/
13287087cfbeSBarry Smith PetscErrorCode  SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
13293d4c4710SBarry Smith {
13303d4c4710SBarry Smith   PetscFunctionBegin;
13310700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
13323d4c4710SBarry Smith   PetscValidIntPointer(maxFails,2);
13333d4c4710SBarry Smith   *maxFails = snes->maxLinearSolveFailures;
13343d4c4710SBarry Smith   PetscFunctionReturn(0);
13353d4c4710SBarry Smith }
13363d4c4710SBarry Smith 
1337c96a6f78SLois Curfman McInnes /*@
1338b850b91aSLisandro Dalcin    SNESGetLinearSolveIterations - Gets the total number of linear iterations
1339c96a6f78SLois Curfman McInnes    used by the nonlinear solver.
1340c96a6f78SLois Curfman McInnes 
1341c7afd0dbSLois Curfman McInnes    Not Collective
1342c7afd0dbSLois Curfman McInnes 
1343c96a6f78SLois Curfman McInnes    Input Parameter:
1344c96a6f78SLois Curfman McInnes .  snes - SNES context
1345c96a6f78SLois Curfman McInnes 
1346c96a6f78SLois Curfman McInnes    Output Parameter:
1347c96a6f78SLois Curfman McInnes .  lits - number of linear iterations
1348c96a6f78SLois Curfman McInnes 
1349c96a6f78SLois Curfman McInnes    Notes:
1350971e163fSPeter Brune    This counter is reset to zero for each successive call to SNESSolve() unless SNESSetCountersReset() is used.
1351c96a6f78SLois Curfman McInnes 
1352010be392SBarry 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
1353010be392SBarry Smith    then call KSPGetIterationNumber() after the failed solve.
1354010be392SBarry Smith 
135536851e7fSLois Curfman McInnes    Level: intermediate
135636851e7fSLois Curfman McInnes 
1357c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations
13582b668275SBarry Smith 
135971dbe336SPeter Brune .seealso:  SNESGetIterationNumber(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESSetCountersReset()
1360c96a6f78SLois Curfman McInnes @*/
13617087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveIterations(SNES snes,PetscInt *lits)
1362c96a6f78SLois Curfman McInnes {
13633a40ed3dSBarry Smith   PetscFunctionBegin;
13640700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
13654482741eSBarry Smith   PetscValidIntPointer(lits,2);
1366c96a6f78SLois Curfman McInnes   *lits = snes->linear_its;
13673a40ed3dSBarry Smith   PetscFunctionReturn(0);
1368c96a6f78SLois Curfman McInnes }
1369c96a6f78SLois Curfman McInnes 
1370971e163fSPeter Brune /*@
1371971e163fSPeter Brune    SNESSetCountersReset - Sets whether or not the counters for linear iterations and function evaluations
1372971e163fSPeter Brune    are reset every time SNESSolve() is called.
1373971e163fSPeter Brune 
1374971e163fSPeter Brune    Logically Collective on SNES
1375971e163fSPeter Brune 
1376971e163fSPeter Brune    Input Parameter:
1377971e163fSPeter Brune +  snes - SNES context
1378971e163fSPeter Brune -  reset - whether to reset the counters or not
1379971e163fSPeter Brune 
1380971e163fSPeter Brune    Notes:
1381fa19ca70SBarry Smith    This defaults to PETSC_TRUE
1382971e163fSPeter Brune 
1383971e163fSPeter Brune    Level: developer
1384971e163fSPeter Brune 
1385971e163fSPeter Brune .keywords: SNES, nonlinear, set, reset, number, linear, iterations
1386971e163fSPeter Brune 
1387734794cfSBarry Smith .seealso:  SNESGetNumberFunctionEvals(), SNESGetLinearSolveIterations(), SNESGetNPC()
1388971e163fSPeter Brune @*/
1389971e163fSPeter Brune PetscErrorCode  SNESSetCountersReset(SNES snes,PetscBool reset)
1390971e163fSPeter Brune {
1391971e163fSPeter Brune   PetscFunctionBegin;
1392971e163fSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1393971e163fSPeter Brune   PetscValidLogicalCollectiveBool(snes,reset,2);
1394971e163fSPeter Brune   snes->counters_reset = reset;
1395971e163fSPeter Brune   PetscFunctionReturn(0);
1396971e163fSPeter Brune }
1397971e163fSPeter Brune 
139882bf6240SBarry Smith 
13992999313aSBarry Smith /*@
14002999313aSBarry Smith    SNESSetKSP - Sets a KSP context for the SNES object to use
14012999313aSBarry Smith 
14022999313aSBarry Smith    Not Collective, but the SNES and KSP objects must live on the same MPI_Comm
14032999313aSBarry Smith 
14042999313aSBarry Smith    Input Parameters:
14052999313aSBarry Smith +  snes - the SNES context
14062999313aSBarry Smith -  ksp - the KSP context
14072999313aSBarry Smith 
14082999313aSBarry Smith    Notes:
14092999313aSBarry Smith    The SNES object already has its KSP object, you can obtain with SNESGetKSP()
14102999313aSBarry Smith    so this routine is rarely needed.
14112999313aSBarry Smith 
14122999313aSBarry Smith    The KSP object that is already in the SNES object has its reference count
14132999313aSBarry Smith    decreased by one.
14142999313aSBarry Smith 
14152999313aSBarry Smith    Level: developer
14162999313aSBarry Smith 
14172999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
14182999313aSBarry Smith 
14192999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
14202999313aSBarry Smith @*/
14217087cfbeSBarry Smith PetscErrorCode  SNESSetKSP(SNES snes,KSP ksp)
14222999313aSBarry Smith {
14232999313aSBarry Smith   PetscErrorCode ierr;
14242999313aSBarry Smith 
14252999313aSBarry Smith   PetscFunctionBegin;
14260700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
14270700a824SBarry Smith   PetscValidHeaderSpecific(ksp,KSP_CLASSID,2);
14282999313aSBarry Smith   PetscCheckSameComm(snes,1,ksp,2);
14297dcf0eaaSdalcinl   ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr);
1430906ed7ccSBarry Smith   if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);}
14312999313aSBarry Smith   snes->ksp = ksp;
14322999313aSBarry Smith   PetscFunctionReturn(0);
14332999313aSBarry Smith }
14342999313aSBarry Smith 
14359b94acceSBarry Smith /* -----------------------------------------------------------*/
143652baeb72SSatish Balay /*@
14379b94acceSBarry Smith    SNESCreate - Creates a nonlinear solver context.
14389b94acceSBarry Smith 
1439c7afd0dbSLois Curfman McInnes    Collective on MPI_Comm
1440c7afd0dbSLois Curfman McInnes 
1441c7afd0dbSLois Curfman McInnes    Input Parameters:
1442906ed7ccSBarry Smith .  comm - MPI communicator
14439b94acceSBarry Smith 
14449b94acceSBarry Smith    Output Parameter:
14459b94acceSBarry Smith .  outsnes - the new SNES context
14469b94acceSBarry Smith 
1447c7afd0dbSLois Curfman McInnes    Options Database Keys:
1448c7afd0dbSLois Curfman McInnes +   -snes_mf - Activates default matrix-free Jacobian-vector products,
1449c7afd0dbSLois Curfman McInnes                and no preconditioning matrix
1450c7afd0dbSLois Curfman McInnes .   -snes_mf_operator - Activates default matrix-free Jacobian-vector
1451c7afd0dbSLois Curfman McInnes                products, and a user-provided preconditioning matrix
1452c7afd0dbSLois Curfman McInnes                as set by SNESSetJacobian()
1453c7afd0dbSLois Curfman McInnes -   -snes_fd - Uses (slow!) finite differences to compute Jacobian
1454c1f60f51SBarry Smith 
145536851e7fSLois Curfman McInnes    Level: beginner
145636851e7fSLois Curfman McInnes 
1457*efd4aadfSBarry Smith    Developer Notes: SNES always creates a KSP object even though many SNES methods do not use it. This is
1458*efd4aadfSBarry Smith                     unfortunate and should be fixed at some point. The flag snes->usesksp indicates if the
1459*efd4aadfSBarry Smith                     particular method does use KSP and regulates if the information about the KSP is printed
1460*efd4aadfSBarry Smith                     in SNESView(). TSSetFromOptions() does call SNESSetFromOptions() which can lead to users being confused
1461*efd4aadfSBarry Smith                     by help messages about meaningless SNES options.
1462*efd4aadfSBarry Smith 
1463*efd4aadfSBarry Smith                     SNES always creates the snes->kspconvctx even though it is used by only one type. This should
1464*efd4aadfSBarry Smith                     be fixed.
1465*efd4aadfSBarry Smith 
14669b94acceSBarry Smith .keywords: SNES, nonlinear, create, context
14679b94acceSBarry Smith 
1468a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner()
1469a8054027SBarry Smith 
14709b94acceSBarry Smith @*/
14717087cfbeSBarry Smith PetscErrorCode  SNESCreate(MPI_Comm comm,SNES *outsnes)
14729b94acceSBarry Smith {
1473dfbe8321SBarry Smith   PetscErrorCode ierr;
14749b94acceSBarry Smith   SNES           snes;
1475fa9f3622SBarry Smith   SNESKSPEW      *kctx;
147637fcc0dbSBarry Smith 
14773a40ed3dSBarry Smith   PetscFunctionBegin;
1478ed1caa07SMatthew Knepley   PetscValidPointer(outsnes,2);
14790298fd71SBarry Smith   *outsnes = NULL;
1480607a6623SBarry Smith   ierr = SNESInitializePackage();CHKERRQ(ierr);
14818ba1e511SMatthew Knepley 
148273107ff1SLisandro Dalcin   ierr = PetscHeaderCreate(snes,SNES_CLASSID,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr);
14837adad957SLisandro Dalcin 
14848d359177SBarry Smith   snes->ops->converged    = SNESConvergedDefault;
14852c155ee1SBarry Smith   snes->usesksp           = PETSC_TRUE;
148688976e71SPeter Brune   snes->tolerancesset     = PETSC_FALSE;
14879b94acceSBarry Smith   snes->max_its           = 50;
14889750a799SBarry Smith   snes->max_funcs         = 10000;
14899b94acceSBarry Smith   snes->norm              = 0.0;
1490365a6726SPeter Brune   snes->normschedule      = SNES_NORM_ALWAYS;
14916c67d002SPeter Brune   snes->functype          = SNES_FUNCTION_DEFAULT;
14923a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE)
14933a2046daSBarry Smith   snes->rtol              = 1.e-5;
14943a2046daSBarry Smith #else
1495b4874afaSBarry Smith   snes->rtol              = 1.e-8;
14963a2046daSBarry Smith #endif
1497b4874afaSBarry Smith   snes->ttol              = 0.0;
14983a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE)
14993a2046daSBarry Smith   snes->abstol            = 1.e-25;
15003a2046daSBarry Smith #else
150170441072SBarry Smith   snes->abstol            = 1.e-50;
15023a2046daSBarry Smith #endif
15037cd0ae37SLisandro Dalcin #if defined(PETSC_USE_REAL_SINGLE)
15047cd0ae37SLisandro Dalcin   snes->stol              = 1.e-5;
15057cd0ae37SLisandro Dalcin #else
1506c60f73f4SPeter Brune   snes->stol              = 1.e-8;
15077cd0ae37SLisandro Dalcin #endif
15083a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE)
15093a2046daSBarry Smith   snes->deltatol          = 1.e-6;
15103a2046daSBarry Smith #else
15114b27c08aSLois Curfman McInnes   snes->deltatol          = 1.e-12;
15123a2046daSBarry Smith #endif
1513e37c518bSBarry Smith   snes->divtol            = 1.e4;
1514e37c518bSBarry Smith   snes->rnorm0            = 0;
15159b94acceSBarry Smith   snes->nfuncs            = 0;
151650ffb88aSMatthew Knepley   snes->numFailures       = 0;
151750ffb88aSMatthew Knepley   snes->maxFailures       = 1;
15187a00f4a9SLois Curfman McInnes   snes->linear_its        = 0;
1519e35cf81dSBarry Smith   snes->lagjacobian       = 1;
152037ec4e1aSPeter Brune   snes->jac_iter          = 0;
152137ec4e1aSPeter Brune   snes->lagjac_persist    = PETSC_FALSE;
1522a8054027SBarry Smith   snes->lagpreconditioner = 1;
152337ec4e1aSPeter Brune   snes->pre_iter          = 0;
152437ec4e1aSPeter Brune   snes->lagpre_persist    = PETSC_FALSE;
1525639f9d9dSBarry Smith   snes->numbermonitors    = 0;
15269b94acceSBarry Smith   snes->data              = 0;
15274dc4c822SBarry Smith   snes->setupcalled       = PETSC_FALSE;
1528186905e3SBarry Smith   snes->ksp_ewconv        = PETSC_FALSE;
15296f24a144SLois Curfman McInnes   snes->nwork             = 0;
153058c9b817SLisandro Dalcin   snes->work              = 0;
153158c9b817SLisandro Dalcin   snes->nvwork            = 0;
153258c9b817SLisandro Dalcin   snes->vwork             = 0;
1533758f92a0SBarry Smith   snes->conv_hist_len     = 0;
1534758f92a0SBarry Smith   snes->conv_hist_max     = 0;
15350298fd71SBarry Smith   snes->conv_hist         = NULL;
15360298fd71SBarry Smith   snes->conv_hist_its     = NULL;
1537758f92a0SBarry Smith   snes->conv_hist_reset   = PETSC_TRUE;
1538971e163fSPeter Brune   snes->counters_reset    = PETSC_TRUE;
1539e4ed7901SPeter Brune   snes->vec_func_init_set = PETSC_FALSE;
1540184914b5SBarry Smith   snes->reason            = SNES_CONVERGED_ITERATING;
1541*efd4aadfSBarry Smith   snes->npcside           = PC_RIGHT;
1542c40d0f55SPeter Brune 
1543d8f46077SPeter Brune   snes->mf          = PETSC_FALSE;
1544d8f46077SPeter Brune   snes->mf_operator = PETSC_FALSE;
1545d8f46077SPeter Brune   snes->mf_version  = 1;
1546d8f46077SPeter Brune 
15473d4c4710SBarry Smith   snes->numLinearSolveFailures = 0;
15483d4c4710SBarry Smith   snes->maxLinearSolveFailures = 1;
15493d4c4710SBarry Smith 
1550349187a7SBarry Smith   snes->vizerotolerance = 1.e-8;
1551349187a7SBarry Smith 
15524fc747eaSLawrence Mitchell   /* Set this to true if the implementation of SNESSolve_XXX does compute the residual at the final solution. */
15534fc747eaSLawrence Mitchell   snes->alwayscomputesfinalresidual = PETSC_FALSE;
15544fc747eaSLawrence Mitchell 
15559b94acceSBarry Smith   /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
1556b00a9115SJed Brown   ierr = PetscNewLog(snes,&kctx);CHKERRQ(ierr);
1557f5af7f23SKarl Rupp 
15589b94acceSBarry Smith   snes->kspconvctx  = (void*)kctx;
15599b94acceSBarry Smith   kctx->version     = 2;
15609b94acceSBarry Smith   kctx->rtol_0      = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
15619b94acceSBarry Smith                              this was too large for some test cases */
156275567043SBarry Smith   kctx->rtol_last   = 0.0;
15639b94acceSBarry Smith   kctx->rtol_max    = .9;
15649b94acceSBarry Smith   kctx->gamma       = 1.0;
156562d1f40fSBarry Smith   kctx->alpha       = .5*(1.0 + PetscSqrtReal(5.0));
156671f87433Sdalcinl   kctx->alpha2      = kctx->alpha;
15679b94acceSBarry Smith   kctx->threshold   = .1;
156875567043SBarry Smith   kctx->lresid_last = 0.0;
156975567043SBarry Smith   kctx->norm_last   = 0.0;
15709b94acceSBarry Smith 
15719b94acceSBarry Smith   *outsnes = snes;
15723a40ed3dSBarry Smith   PetscFunctionReturn(0);
15739b94acceSBarry Smith }
15749b94acceSBarry Smith 
157588f0584fSBarry Smith /*MC
1576411c0326SBarry Smith     SNESFunction - Functional form used to convey the nonlinear function to be solved by SNES
157788f0584fSBarry Smith 
157888f0584fSBarry Smith      Synopsis:
1579411c0326SBarry Smith      #include "petscsnes.h"
1580411c0326SBarry Smith      PetscErrorCode SNESFunction(SNES snes,Vec x,Vec f,void *ctx);
158188f0584fSBarry Smith 
158288f0584fSBarry Smith      Input Parameters:
158388f0584fSBarry Smith +     snes - the SNES context
158488f0584fSBarry Smith .     x    - state at which to evaluate residual
158588f0584fSBarry Smith -     ctx     - optional user-defined function context, passed in with SNESSetFunction()
158688f0584fSBarry Smith 
158788f0584fSBarry Smith      Output Parameter:
158888f0584fSBarry Smith .     f  - vector to put residual (function value)
158988f0584fSBarry Smith 
1590878cb397SSatish Balay    Level: intermediate
1591878cb397SSatish Balay 
159288f0584fSBarry Smith .seealso:   SNESSetFunction(), SNESGetFunction()
159388f0584fSBarry Smith M*/
159488f0584fSBarry Smith 
15959b94acceSBarry Smith /*@C
15969b94acceSBarry Smith    SNESSetFunction - Sets the function evaluation routine and function
15979b94acceSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
15989b94acceSBarry Smith    equations.
15999b94acceSBarry Smith 
16003f9fe445SBarry Smith    Logically Collective on SNES
1601fee21e36SBarry Smith 
1602c7afd0dbSLois Curfman McInnes    Input Parameters:
1603c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1604c7afd0dbSLois Curfman McInnes .  r - vector to store function value
1605f8b49ee9SBarry Smith .  f - function evaluation routine; see SNESFunction for calling sequence details
1606c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
16070298fd71SBarry Smith          function evaluation routine (may be NULL)
16089b94acceSBarry Smith 
16099b94acceSBarry Smith    Notes:
16109b94acceSBarry Smith    The Newton-like methods typically solve linear systems of the form
16119b94acceSBarry Smith $      f'(x) x = -f(x),
1612c7afd0dbSLois Curfman McInnes    where f'(x) denotes the Jacobian matrix and f(x) is the function.
16139b94acceSBarry Smith 
161436851e7fSLois Curfman McInnes    Level: beginner
161536851e7fSLois Curfman McInnes 
16169b94acceSBarry Smith .keywords: SNES, nonlinear, set, function
16179b94acceSBarry Smith 
1618bf388a1fSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard(), SNESFunction
16199b94acceSBarry Smith @*/
1620f8b49ee9SBarry Smith PetscErrorCode  SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx)
16219b94acceSBarry Smith {
162285385478SLisandro Dalcin   PetscErrorCode ierr;
16236cab3a1bSJed Brown   DM             dm;
16246cab3a1bSJed Brown 
16253a40ed3dSBarry Smith   PetscFunctionBegin;
16260700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1627d2a683ecSLisandro Dalcin   if (r) {
1628d2a683ecSLisandro Dalcin     PetscValidHeaderSpecific(r,VEC_CLASSID,2);
1629d2a683ecSLisandro Dalcin     PetscCheckSameComm(snes,1,r,2);
163085385478SLisandro Dalcin     ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr);
16316bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
1632f5af7f23SKarl Rupp 
163385385478SLisandro Dalcin     snes->vec_func = r;
1634d2a683ecSLisandro Dalcin   }
16356cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
1636f8b49ee9SBarry Smith   ierr = DMSNESSetFunction(dm,f,ctx);CHKERRQ(ierr);
16373a40ed3dSBarry Smith   PetscFunctionReturn(0);
16389b94acceSBarry Smith }
16399b94acceSBarry Smith 
1640646217ecSPeter Brune 
1641e4ed7901SPeter Brune /*@C
1642e4ed7901SPeter Brune    SNESSetInitialFunction - Sets the function vector to be used as the
1643e4ed7901SPeter Brune    function norm at the initialization of the method.  In some
1644e4ed7901SPeter Brune    instances, the user has precomputed the function before calling
1645e4ed7901SPeter Brune    SNESSolve.  This function allows one to avoid a redundant call
1646e4ed7901SPeter Brune    to SNESComputeFunction in that case.
1647e4ed7901SPeter Brune 
1648e4ed7901SPeter Brune    Logically Collective on SNES
1649e4ed7901SPeter Brune 
1650e4ed7901SPeter Brune    Input Parameters:
1651e4ed7901SPeter Brune +  snes - the SNES context
1652e4ed7901SPeter Brune -  f - vector to store function value
1653e4ed7901SPeter Brune 
1654e4ed7901SPeter Brune    Notes:
1655e4ed7901SPeter Brune    This should not be modified during the solution procedure.
1656e4ed7901SPeter Brune 
1657e4ed7901SPeter Brune    This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning.
1658e4ed7901SPeter Brune 
1659e4ed7901SPeter Brune    Level: developer
1660e4ed7901SPeter Brune 
1661e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function
1662e4ed7901SPeter Brune 
1663e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunctionNorm()
1664e4ed7901SPeter Brune @*/
1665e4ed7901SPeter Brune PetscErrorCode  SNESSetInitialFunction(SNES snes, Vec f)
1666e4ed7901SPeter Brune {
1667e4ed7901SPeter Brune   PetscErrorCode ierr;
1668e4ed7901SPeter Brune   Vec            vec_func;
1669e4ed7901SPeter Brune 
1670e4ed7901SPeter Brune   PetscFunctionBegin;
1671e4ed7901SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1672e4ed7901SPeter Brune   PetscValidHeaderSpecific(f,VEC_CLASSID,2);
1673e4ed7901SPeter Brune   PetscCheckSameComm(snes,1,f,2);
1674*efd4aadfSBarry Smith   if (snes->npcside== PC_LEFT && snes->functype == SNES_FUNCTION_PRECONDITIONED) {
1675902f982fSPeter Brune     snes->vec_func_init_set = PETSC_FALSE;
1676902f982fSPeter Brune     PetscFunctionReturn(0);
1677902f982fSPeter Brune   }
16780298fd71SBarry Smith   ierr = SNESGetFunction(snes,&vec_func,NULL,NULL);CHKERRQ(ierr);
1679e4ed7901SPeter Brune   ierr = VecCopy(f, vec_func);CHKERRQ(ierr);
1680f5af7f23SKarl Rupp 
1681217b9c2eSPeter Brune   snes->vec_func_init_set = PETSC_TRUE;
1682e4ed7901SPeter Brune   PetscFunctionReturn(0);
1683e4ed7901SPeter Brune }
1684e4ed7901SPeter Brune 
1685534ebe21SPeter Brune /*@
1686365a6726SPeter Brune    SNESSetNormSchedule - Sets the SNESNormSchedule used in covergence and monitoring
1687534ebe21SPeter Brune    of the SNES method.
1688534ebe21SPeter Brune 
1689534ebe21SPeter Brune    Logically Collective on SNES
1690534ebe21SPeter Brune 
1691534ebe21SPeter Brune    Input Parameters:
1692534ebe21SPeter Brune +  snes - the SNES context
1693365a6726SPeter Brune -  normschedule - the frequency of norm computation
1694534ebe21SPeter Brune 
1695517f1916SMatthew G. Knepley    Options Database Key:
1696517f1916SMatthew G. Knepley .  -snes_norm_schedule <none, always, initialonly, finalonly, initalfinalonly>
1697517f1916SMatthew G. Knepley 
1698534ebe21SPeter Brune    Notes:
1699365a6726SPeter Brune    Only certain SNES methods support certain SNESNormSchedules.  Most require evaluation
1700534ebe21SPeter Brune    of the nonlinear function and the taking of its norm at every iteration to
1701534ebe21SPeter Brune    even ensure convergence at all.  However, methods such as custom Gauss-Seidel methods
1702be95d8f1SBarry Smith    (SNESNGS) and the like do not require the norm of the function to be computed, and therfore
1703534ebe21SPeter Brune    may either be monitored for convergence or not.  As these are often used as nonlinear
1704534ebe21SPeter Brune    preconditioners, monitoring the norm of their error is not a useful enterprise within
1705534ebe21SPeter Brune    their solution.
1706534ebe21SPeter Brune 
1707534ebe21SPeter Brune    Level: developer
1708534ebe21SPeter Brune 
1709534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type
1710534ebe21SPeter Brune 
1711365a6726SPeter Brune .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
1712534ebe21SPeter Brune @*/
1713365a6726SPeter Brune PetscErrorCode  SNESSetNormSchedule(SNES snes, SNESNormSchedule normschedule)
1714534ebe21SPeter Brune {
1715534ebe21SPeter Brune   PetscFunctionBegin;
1716534ebe21SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1717365a6726SPeter Brune   snes->normschedule = normschedule;
1718534ebe21SPeter Brune   PetscFunctionReturn(0);
1719534ebe21SPeter Brune }
1720534ebe21SPeter Brune 
1721534ebe21SPeter Brune 
1722534ebe21SPeter Brune /*@
1723365a6726SPeter Brune    SNESGetNormSchedule - Gets the SNESNormSchedule used in covergence and monitoring
1724534ebe21SPeter Brune    of the SNES method.
1725534ebe21SPeter Brune 
1726534ebe21SPeter Brune    Logically Collective on SNES
1727534ebe21SPeter Brune 
1728534ebe21SPeter Brune    Input Parameters:
1729534ebe21SPeter Brune +  snes - the SNES context
1730365a6726SPeter Brune -  normschedule - the type of the norm used
1731534ebe21SPeter Brune 
1732534ebe21SPeter Brune    Level: advanced
1733534ebe21SPeter Brune 
1734534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type
1735534ebe21SPeter Brune 
1736365a6726SPeter Brune .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
1737534ebe21SPeter Brune @*/
1738365a6726SPeter Brune PetscErrorCode  SNESGetNormSchedule(SNES snes, SNESNormSchedule *normschedule)
1739534ebe21SPeter Brune {
1740534ebe21SPeter Brune   PetscFunctionBegin;
1741534ebe21SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1742365a6726SPeter Brune   *normschedule = snes->normschedule;
1743534ebe21SPeter Brune   PetscFunctionReturn(0);
1744534ebe21SPeter Brune }
1745534ebe21SPeter Brune 
174647073ea2SPeter Brune 
1747c5ce4427SMatthew G. Knepley /*@
1748c5ce4427SMatthew G. Knepley   SNESSetFunctionNorm - Sets the last computed residual norm.
1749c5ce4427SMatthew G. Knepley 
1750c5ce4427SMatthew G. Knepley   Logically Collective on SNES
1751c5ce4427SMatthew G. Knepley 
1752c5ce4427SMatthew G. Knepley   Input Parameters:
1753c5ce4427SMatthew G. Knepley + snes - the SNES context
1754c5ce4427SMatthew G. Knepley 
1755c5ce4427SMatthew G. Knepley - normschedule - the frequency of norm computation
1756c5ce4427SMatthew G. Knepley 
1757c5ce4427SMatthew G. Knepley   Level: developer
1758c5ce4427SMatthew G. Knepley 
1759c5ce4427SMatthew G. Knepley .keywords: SNES, nonlinear, set, function, norm, type
1760c5ce4427SMatthew G. Knepley .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
1761c5ce4427SMatthew G. Knepley @*/
1762c5ce4427SMatthew G. Knepley PetscErrorCode SNESSetFunctionNorm(SNES snes, PetscReal norm)
1763c5ce4427SMatthew G. Knepley {
1764c5ce4427SMatthew G. Knepley   PetscFunctionBegin;
1765c5ce4427SMatthew G. Knepley   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1766c5ce4427SMatthew G. Knepley   snes->norm = norm;
1767c5ce4427SMatthew G. Knepley   PetscFunctionReturn(0);
1768c5ce4427SMatthew G. Knepley }
1769c5ce4427SMatthew G. Knepley 
1770c5ce4427SMatthew G. Knepley /*@
1771c5ce4427SMatthew G. Knepley   SNESGetFunctionNorm - Gets the last computed norm of the residual
1772c5ce4427SMatthew G. Knepley 
1773c5ce4427SMatthew G. Knepley   Not Collective
1774c5ce4427SMatthew G. Knepley 
1775c5ce4427SMatthew G. Knepley   Input Parameter:
1776c5ce4427SMatthew G. Knepley . snes - the SNES context
1777c5ce4427SMatthew G. Knepley 
1778c5ce4427SMatthew G. Knepley   Output Parameter:
1779c5ce4427SMatthew G. Knepley . norm - the last computed residual norm
1780c5ce4427SMatthew G. Knepley 
1781c5ce4427SMatthew G. Knepley   Level: developer
1782c5ce4427SMatthew G. Knepley 
1783c5ce4427SMatthew G. Knepley .keywords: SNES, nonlinear, set, function, norm, type
1784c5ce4427SMatthew G. Knepley .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
1785c5ce4427SMatthew G. Knepley @*/
1786c5ce4427SMatthew G. Knepley PetscErrorCode SNESGetFunctionNorm(SNES snes, PetscReal *norm)
1787c5ce4427SMatthew G. Knepley {
1788c5ce4427SMatthew G. Knepley   PetscFunctionBegin;
1789c5ce4427SMatthew G. Knepley   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1790c5ce4427SMatthew G. Knepley   PetscValidPointer(norm, 2);
1791c5ce4427SMatthew G. Knepley   *norm = snes->norm;
1792c5ce4427SMatthew G. Knepley   PetscFunctionReturn(0);
1793c5ce4427SMatthew G. Knepley }
1794c5ce4427SMatthew G. Knepley 
179547073ea2SPeter Brune /*@C
179647073ea2SPeter Brune    SNESSetFunctionType - Sets the SNESNormSchedule used in covergence and monitoring
179747073ea2SPeter Brune    of the SNES method.
179847073ea2SPeter Brune 
179947073ea2SPeter Brune    Logically Collective on SNES
180047073ea2SPeter Brune 
180147073ea2SPeter Brune    Input Parameters:
180247073ea2SPeter Brune +  snes - the SNES context
180347073ea2SPeter Brune -  normschedule - the frequency of norm computation
180447073ea2SPeter Brune 
180547073ea2SPeter Brune    Notes:
180647073ea2SPeter Brune    Only certain SNES methods support certain SNESNormSchedules.  Most require evaluation
180747073ea2SPeter Brune    of the nonlinear function and the taking of its norm at every iteration to
180847073ea2SPeter Brune    even ensure convergence at all.  However, methods such as custom Gauss-Seidel methods
1809be95d8f1SBarry Smith    (SNESNGS) and the like do not require the norm of the function to be computed, and therfore
181047073ea2SPeter Brune    may either be monitored for convergence or not.  As these are often used as nonlinear
181147073ea2SPeter Brune    preconditioners, monitoring the norm of their error is not a useful enterprise within
181247073ea2SPeter Brune    their solution.
181347073ea2SPeter Brune 
181447073ea2SPeter Brune    Level: developer
181547073ea2SPeter Brune 
181647073ea2SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type
181747073ea2SPeter Brune 
181847073ea2SPeter Brune .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
181947073ea2SPeter Brune @*/
182047073ea2SPeter Brune PetscErrorCode  SNESSetFunctionType(SNES snes, SNESFunctionType type)
182147073ea2SPeter Brune {
182247073ea2SPeter Brune   PetscFunctionBegin;
182347073ea2SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
182447073ea2SPeter Brune   snes->functype = type;
182547073ea2SPeter Brune   PetscFunctionReturn(0);
182647073ea2SPeter Brune }
182747073ea2SPeter Brune 
182847073ea2SPeter Brune 
182947073ea2SPeter Brune /*@C
183047073ea2SPeter Brune    SNESGetFunctionType - Gets the SNESNormSchedule used in covergence and monitoring
183147073ea2SPeter Brune    of the SNES method.
183247073ea2SPeter Brune 
183347073ea2SPeter Brune    Logically Collective on SNES
183447073ea2SPeter Brune 
183547073ea2SPeter Brune    Input Parameters:
183647073ea2SPeter Brune +  snes - the SNES context
183747073ea2SPeter Brune -  normschedule - the type of the norm used
183847073ea2SPeter Brune 
183947073ea2SPeter Brune    Level: advanced
184047073ea2SPeter Brune 
184147073ea2SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type
184247073ea2SPeter Brune 
184347073ea2SPeter Brune .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
184447073ea2SPeter Brune @*/
184547073ea2SPeter Brune PetscErrorCode  SNESGetFunctionType(SNES snes, SNESFunctionType *type)
184647073ea2SPeter Brune {
184747073ea2SPeter Brune   PetscFunctionBegin;
184847073ea2SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
184947073ea2SPeter Brune   *type = snes->functype;
1850534ebe21SPeter Brune   PetscFunctionReturn(0);
1851534ebe21SPeter Brune }
1852534ebe21SPeter Brune 
1853bf388a1fSBarry Smith /*MC
1854be95d8f1SBarry Smith     SNESNGSFunction - function used to convey a Gauss-Seidel sweep on the nonlinear function
1855bf388a1fSBarry Smith 
1856bf388a1fSBarry Smith      Synopsis:
1857aaa7dc30SBarry Smith      #include <petscsnes.h>
1858be95d8f1SBarry Smith $    SNESNGSFunction(SNES snes,Vec x,Vec b,void *ctx);
1859bf388a1fSBarry Smith 
1860bf388a1fSBarry Smith +  X   - solution vector
1861bf388a1fSBarry Smith .  B   - RHS vector
1862bf388a1fSBarry Smith -  ctx - optional user-defined Gauss-Seidel context
1863bf388a1fSBarry Smith 
1864878cb397SSatish Balay    Level: intermediate
1865878cb397SSatish Balay 
1866be95d8f1SBarry Smith .seealso:   SNESSetNGS(), SNESGetNGS()
1867bf388a1fSBarry Smith M*/
1868bf388a1fSBarry Smith 
1869c79ef259SPeter Brune /*@C
1870be95d8f1SBarry Smith    SNESSetNGS - Sets the user nonlinear Gauss-Seidel routine for
1871c79ef259SPeter Brune    use with composed nonlinear solvers.
1872c79ef259SPeter Brune 
1873c79ef259SPeter Brune    Input Parameters:
1874c79ef259SPeter Brune +  snes   - the SNES context
1875be95d8f1SBarry Smith .  f - function evaluation routine to apply Gauss-Seidel see SNESNGSFunction
1876c79ef259SPeter Brune -  ctx    - [optional] user-defined context for private data for the
18770298fd71SBarry Smith             smoother evaluation routine (may be NULL)
1878c79ef259SPeter Brune 
1879c79ef259SPeter Brune    Notes:
1880be95d8f1SBarry Smith    The NGS routines are used by the composed nonlinear solver to generate
1881c79ef259SPeter Brune     a problem appropriate update to the solution, particularly FAS.
1882c79ef259SPeter Brune 
1883d28543b3SPeter Brune    Level: intermediate
1884c79ef259SPeter Brune 
1885d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel
1886c79ef259SPeter Brune 
1887be95d8f1SBarry Smith .seealso: SNESGetFunction(), SNESComputeNGS()
1888c79ef259SPeter Brune @*/
1889be95d8f1SBarry Smith PetscErrorCode SNESSetNGS(SNES snes,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx)
18906cab3a1bSJed Brown {
18916cab3a1bSJed Brown   PetscErrorCode ierr;
18926cab3a1bSJed Brown   DM             dm;
18936cab3a1bSJed Brown 
1894646217ecSPeter Brune   PetscFunctionBegin;
18956cab3a1bSJed Brown   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
18966cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
1897be95d8f1SBarry Smith   ierr = DMSNESSetNGS(dm,f,ctx);CHKERRQ(ierr);
1898646217ecSPeter Brune   PetscFunctionReturn(0);
1899646217ecSPeter Brune }
1900646217ecSPeter Brune 
190182b59a81SJed Brown PETSC_EXTERN PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx)
19028b0a5094SBarry Smith {
19038b0a5094SBarry Smith   PetscErrorCode ierr;
1904e03ab78fSPeter Brune   DM             dm;
1905942e3340SBarry Smith   DMSNES         sdm;
19066cab3a1bSJed Brown 
19078b0a5094SBarry Smith   PetscFunctionBegin;
1908e03ab78fSPeter Brune   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
1909942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
19108b0a5094SBarry Smith   /*  A(x)*x - b(x) */
191122c6f798SBarry Smith   if (sdm->ops->computepfunction) {
191222c6f798SBarry Smith     ierr = (*sdm->ops->computepfunction)(snes,x,f,sdm->pctx);CHKERRQ(ierr);
191322c6f798SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard function.");
1914e03ab78fSPeter Brune 
191522c6f798SBarry Smith   if (sdm->ops->computepjacobian) {
1916d1e9a80fSBarry Smith     ierr = (*sdm->ops->computepjacobian)(snes,x,snes->jacobian,snes->jacobian_pre,sdm->pctx);CHKERRQ(ierr);
191774e1e8c1SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard matrix.");
19188b0a5094SBarry Smith   ierr = VecScale(f,-1.0);CHKERRQ(ierr);
191995eabcedSBarry Smith   ierr = MatMultAdd(snes->jacobian,x,f,f);CHKERRQ(ierr);
19208b0a5094SBarry Smith   PetscFunctionReturn(0);
19218b0a5094SBarry Smith }
19228b0a5094SBarry Smith 
1923d1e9a80fSBarry Smith PETSC_EXTERN PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat J,Mat B,void *ctx)
19248b0a5094SBarry Smith {
19258b0a5094SBarry Smith   PetscFunctionBegin;
1926e03ab78fSPeter Brune   /* the jacobian matrix should be pre-filled in SNESPicardComputeFunction */
19278b0a5094SBarry Smith   PetscFunctionReturn(0);
19288b0a5094SBarry Smith }
19298b0a5094SBarry Smith 
19308b0a5094SBarry Smith /*@C
19310d04baf8SBarry Smith    SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization)
19328b0a5094SBarry Smith 
19338b0a5094SBarry Smith    Logically Collective on SNES
19348b0a5094SBarry Smith 
19358b0a5094SBarry Smith    Input Parameters:
19368b0a5094SBarry Smith +  snes - the SNES context
19378b0a5094SBarry Smith .  r - vector to store function value
1938f8b49ee9SBarry Smith .  b - function evaluation routine
1939e5d3d808SBarry Smith .  Amat - matrix with which A(x) x - b(x) is to be computed
1940e5d3d808SBarry Smith .  Pmat - matrix from which preconditioner is computed (usually the same as Amat)
1941411c0326SBarry Smith .  J  - function to compute matrix value, see SNESJacobianFunction for details on its calling sequence
19428b0a5094SBarry Smith -  ctx - [optional] user-defined context for private data for the
19430298fd71SBarry Smith          function evaluation routine (may be NULL)
19448b0a5094SBarry Smith 
19458b0a5094SBarry Smith    Notes:
1946f450aa47SBarry 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
1947f450aa47SBarry 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.
1948f450aa47SBarry Smith 
19498b0a5094SBarry Smith     One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both
19508b0a5094SBarry Smith 
19518b0a5094SBarry 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}
19528b0a5094SBarry 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.
19538b0a5094SBarry Smith 
19548b0a5094SBarry Smith      Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner.
19558b0a5094SBarry Smith 
19560d04baf8SBarry Smith    We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then
19570d04baf8SBarry Smith    the direct Picard iteration A(x^n) x^{n+1} = b(x^n)
19588b0a5094SBarry Smith 
19598b0a5094SBarry 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
19608b0a5094SBarry 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
19618b0a5094SBarry Smith    different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-).
19628b0a5094SBarry Smith 
1963f450aa47SBarry Smith    Level: intermediate
19648b0a5094SBarry Smith 
19658b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function
19668b0a5094SBarry Smith 
1967411c0326SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard(), SNESJacobianFunction
19688b0a5094SBarry Smith @*/
1969d1e9a80fSBarry 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)
19708b0a5094SBarry Smith {
19718b0a5094SBarry Smith   PetscErrorCode ierr;
1972e03ab78fSPeter Brune   DM             dm;
1973e03ab78fSPeter Brune 
19748b0a5094SBarry Smith   PetscFunctionBegin;
19758b0a5094SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1976e03ab78fSPeter Brune   ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr);
1977f8b49ee9SBarry Smith   ierr = DMSNESSetPicard(dm,b,J,ctx);CHKERRQ(ierr);
19788b0a5094SBarry Smith   ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr);
1979e5d3d808SBarry Smith   ierr = SNESSetJacobian(snes,Amat,Pmat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr);
19808b0a5094SBarry Smith   PetscFunctionReturn(0);
19818b0a5094SBarry Smith }
19828b0a5094SBarry Smith 
19837971a8bfSPeter Brune /*@C
19847971a8bfSPeter Brune    SNESGetPicard - Returns the context for the Picard iteration
19857971a8bfSPeter Brune 
19867971a8bfSPeter Brune    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
19877971a8bfSPeter Brune 
19887971a8bfSPeter Brune    Input Parameter:
19897971a8bfSPeter Brune .  snes - the SNES context
19907971a8bfSPeter Brune 
19917971a8bfSPeter Brune    Output Parameter:
19920298fd71SBarry Smith +  r - the function (or NULL)
1993f8b49ee9SBarry Smith .  f - the function (or NULL); see SNESFunction for calling sequence details
1994e4357dc4SBarry Smith .  Amat - the matrix used to defined the operation A(x) x - b(x) (or NULL)
1995e4357dc4SBarry Smith .  Pmat  - the matrix from which the preconditioner will be constructed (or NULL)
1996f8b49ee9SBarry Smith .  J - the function for matrix evaluation (or NULL); see SNESJacobianFunction for calling sequence details
19970298fd71SBarry Smith -  ctx - the function context (or NULL)
19987971a8bfSPeter Brune 
19997971a8bfSPeter Brune    Level: advanced
20007971a8bfSPeter Brune 
20017971a8bfSPeter Brune .keywords: SNES, nonlinear, get, function
20027971a8bfSPeter Brune 
2003e4357dc4SBarry Smith .seealso: SNESSetPicard(), SNESGetFunction(), SNESGetJacobian(), SNESGetDM(), SNESFunction, SNESJacobianFunction
20047971a8bfSPeter Brune @*/
2005d1e9a80fSBarry 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)
20067971a8bfSPeter Brune {
20077971a8bfSPeter Brune   PetscErrorCode ierr;
20087971a8bfSPeter Brune   DM             dm;
20097971a8bfSPeter Brune 
20107971a8bfSPeter Brune   PetscFunctionBegin;
20117971a8bfSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
20120298fd71SBarry Smith   ierr = SNESGetFunction(snes,r,NULL,NULL);CHKERRQ(ierr);
2013e4357dc4SBarry Smith   ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr);
20147971a8bfSPeter Brune   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2015f8b49ee9SBarry Smith   ierr = DMSNESGetPicard(dm,f,J,ctx);CHKERRQ(ierr);
20167971a8bfSPeter Brune   PetscFunctionReturn(0);
20177971a8bfSPeter Brune }
20187971a8bfSPeter Brune 
2019d25893d9SBarry Smith /*@C
2020d25893d9SBarry Smith    SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem
2021d25893d9SBarry Smith 
2022d25893d9SBarry Smith    Logically Collective on SNES
2023d25893d9SBarry Smith 
2024d25893d9SBarry Smith    Input Parameters:
2025d25893d9SBarry Smith +  snes - the SNES context
2026d25893d9SBarry Smith .  func - function evaluation routine
2027d25893d9SBarry Smith -  ctx - [optional] user-defined context for private data for the
20280298fd71SBarry Smith          function evaluation routine (may be NULL)
2029d25893d9SBarry Smith 
2030d25893d9SBarry Smith    Calling sequence of func:
2031d25893d9SBarry Smith $    func (SNES snes,Vec x,void *ctx);
2032d25893d9SBarry Smith 
2033d25893d9SBarry Smith .  f - function vector
2034d25893d9SBarry Smith -  ctx - optional user-defined function context
2035d25893d9SBarry Smith 
2036d25893d9SBarry Smith    Level: intermediate
2037d25893d9SBarry Smith 
2038d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function
2039d25893d9SBarry Smith 
2040d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
2041d25893d9SBarry Smith @*/
2042d25893d9SBarry Smith PetscErrorCode  SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx)
2043d25893d9SBarry Smith {
2044d25893d9SBarry Smith   PetscFunctionBegin;
2045d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2046d25893d9SBarry Smith   if (func) snes->ops->computeinitialguess = func;
2047d25893d9SBarry Smith   if (ctx)  snes->initialguessP            = ctx;
2048d25893d9SBarry Smith   PetscFunctionReturn(0);
2049d25893d9SBarry Smith }
2050d25893d9SBarry Smith 
20513ab0aad5SBarry Smith /* --------------------------------------------------------------- */
20521096aae1SMatthew Knepley /*@C
20531096aae1SMatthew Knepley    SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
20541096aae1SMatthew Knepley    it assumes a zero right hand side.
20551096aae1SMatthew Knepley 
20563f9fe445SBarry Smith    Logically Collective on SNES
20571096aae1SMatthew Knepley 
20581096aae1SMatthew Knepley    Input Parameter:
20591096aae1SMatthew Knepley .  snes - the SNES context
20601096aae1SMatthew Knepley 
20611096aae1SMatthew Knepley    Output Parameter:
20620298fd71SBarry Smith .  rhs - the right hand side vector or NULL if the right hand side vector is null
20631096aae1SMatthew Knepley 
20641096aae1SMatthew Knepley    Level: intermediate
20651096aae1SMatthew Knepley 
20661096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side
20671096aae1SMatthew Knepley 
206885385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
20691096aae1SMatthew Knepley @*/
20707087cfbeSBarry Smith PetscErrorCode  SNESGetRhs(SNES snes,Vec *rhs)
20711096aae1SMatthew Knepley {
20721096aae1SMatthew Knepley   PetscFunctionBegin;
20730700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
20741096aae1SMatthew Knepley   PetscValidPointer(rhs,2);
207585385478SLisandro Dalcin   *rhs = snes->vec_rhs;
20761096aae1SMatthew Knepley   PetscFunctionReturn(0);
20771096aae1SMatthew Knepley }
20781096aae1SMatthew Knepley 
20799b94acceSBarry Smith /*@
2080bf388a1fSBarry Smith    SNESComputeFunction - Calls the function that has been set with SNESSetFunction().
20819b94acceSBarry Smith 
2082c7afd0dbSLois Curfman McInnes    Collective on SNES
2083c7afd0dbSLois Curfman McInnes 
20849b94acceSBarry Smith    Input Parameters:
2085c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2086c7afd0dbSLois Curfman McInnes -  x - input vector
20879b94acceSBarry Smith 
20889b94acceSBarry Smith    Output Parameter:
20893638b69dSLois Curfman McInnes .  y - function vector, as set by SNESSetFunction()
20909b94acceSBarry Smith 
20911bffabb2SLois Curfman McInnes    Notes:
209236851e7fSLois Curfman McInnes    SNESComputeFunction() is typically used within nonlinear solvers
209336851e7fSLois Curfman McInnes    implementations, so most users would not generally call this routine
209436851e7fSLois Curfman McInnes    themselves.
209536851e7fSLois Curfman McInnes 
209636851e7fSLois Curfman McInnes    Level: developer
209736851e7fSLois Curfman McInnes 
20989b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function
20999b94acceSBarry Smith 
2100a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction()
21019b94acceSBarry Smith @*/
21027087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction(SNES snes,Vec x,Vec y)
21039b94acceSBarry Smith {
2104dfbe8321SBarry Smith   PetscErrorCode ierr;
21056cab3a1bSJed Brown   DM             dm;
2106942e3340SBarry Smith   DMSNES         sdm;
21079b94acceSBarry Smith 
21083a40ed3dSBarry Smith   PetscFunctionBegin;
21090700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
21100700a824SBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
21110700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2112c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,x,2);
2113c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,3);
211462796dfbSBarry Smith   ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);
2115184914b5SBarry Smith 
21166cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2117942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
211832f3f7c2SPeter Brune   if (sdm->ops->computefunction) {
211994db00ebSBarry Smith     if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) {
2120ccf3c845SPeter Brune       ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
212194db00ebSBarry Smith     }
21225edff71fSBarry Smith     ierr = VecLockPush(x);CHKERRQ(ierr);
2123d64ed03dSBarry Smith     PetscStackPush("SNES user function");
212422c6f798SBarry Smith     ierr = (*sdm->ops->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr);
2125d64ed03dSBarry Smith     PetscStackPop;
21265edff71fSBarry Smith     ierr = VecLockPop(x);CHKERRQ(ierr);
212794db00ebSBarry Smith     if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) {
2128ccf3c845SPeter Brune       ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
212994db00ebSBarry Smith     }
2130c90fad12SPeter Brune   } else if (snes->vec_rhs) {
2131c90fad12SPeter Brune     ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr);
2132644e2e5bSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve().");
213385385478SLisandro Dalcin   if (snes->vec_rhs) {
213485385478SLisandro Dalcin     ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr);
21353ab0aad5SBarry Smith   }
2136ae3c334cSLois Curfman McInnes   snes->nfuncs++;
2137422a814eSBarry Smith   /*
2138422a814eSBarry Smith      domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will
2139422a814eSBarry Smith      propagate the value to all processes
2140422a814eSBarry Smith   */
2141422a814eSBarry Smith   if (snes->domainerror) {
2142422a814eSBarry Smith     ierr = VecSetInf(y);CHKERRQ(ierr);
2143422a814eSBarry Smith   }
21443a40ed3dSBarry Smith   PetscFunctionReturn(0);
21459b94acceSBarry Smith }
21469b94acceSBarry Smith 
2147c79ef259SPeter Brune /*@
2148be95d8f1SBarry Smith    SNESComputeNGS - Calls the Gauss-Seidel function that has been set with  SNESSetNGS().
2149c79ef259SPeter Brune 
2150c79ef259SPeter Brune    Collective on SNES
2151c79ef259SPeter Brune 
2152c79ef259SPeter Brune    Input Parameters:
2153c79ef259SPeter Brune +  snes - the SNES context
2154c79ef259SPeter Brune .  x - input vector
2155c79ef259SPeter Brune -  b - rhs vector
2156c79ef259SPeter Brune 
2157c79ef259SPeter Brune    Output Parameter:
2158c79ef259SPeter Brune .  x - new solution vector
2159c79ef259SPeter Brune 
2160c79ef259SPeter Brune    Notes:
2161be95d8f1SBarry Smith    SNESComputeNGS() is typically used within composed nonlinear solver
2162c79ef259SPeter Brune    implementations, so most users would not generally call this routine
2163c79ef259SPeter Brune    themselves.
2164c79ef259SPeter Brune 
2165c79ef259SPeter Brune    Level: developer
2166c79ef259SPeter Brune 
2167c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function
2168c79ef259SPeter Brune 
2169be95d8f1SBarry Smith .seealso: SNESSetNGS(), SNESComputeFunction()
2170c79ef259SPeter Brune @*/
2171be95d8f1SBarry Smith PetscErrorCode  SNESComputeNGS(SNES snes,Vec b,Vec x)
2172646217ecSPeter Brune {
2173646217ecSPeter Brune   PetscErrorCode ierr;
21746cab3a1bSJed Brown   DM             dm;
2175942e3340SBarry Smith   DMSNES         sdm;
2176646217ecSPeter Brune 
2177646217ecSPeter Brune   PetscFunctionBegin;
2178646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2179646217ecSPeter Brune   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2180646217ecSPeter Brune   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3);
2181646217ecSPeter Brune   PetscCheckSameComm(snes,1,x,2);
2182646217ecSPeter Brune   if (b) PetscCheckSameComm(snes,1,b,3);
218362796dfbSBarry Smith   if (b) {ierr = VecValidValues(b,2,PETSC_TRUE);CHKERRQ(ierr);}
2184be95d8f1SBarry Smith   ierr = PetscLogEventBegin(SNES_NGSEval,snes,x,b,0);CHKERRQ(ierr);
21856cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2186942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
218722c6f798SBarry Smith   if (sdm->ops->computegs) {
21885edff71fSBarry Smith     if (b) {ierr = VecLockPush(b);CHKERRQ(ierr);}
2189be95d8f1SBarry Smith     PetscStackPush("SNES user NGS");
219022c6f798SBarry Smith     ierr = (*sdm->ops->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr);
2191646217ecSPeter Brune     PetscStackPop;
21925edff71fSBarry Smith     if (b) {ierr = VecLockPop(b);CHKERRQ(ierr);}
2193be95d8f1SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetNGS() before SNESComputeNGS(), likely called from SNESSolve().");
2194be95d8f1SBarry Smith   ierr = PetscLogEventEnd(SNES_NGSEval,snes,x,b,0);CHKERRQ(ierr);
2195646217ecSPeter Brune   PetscFunctionReturn(0);
2196646217ecSPeter Brune }
2197646217ecSPeter Brune 
219862fef451SLois Curfman McInnes /*@
2199bf388a1fSBarry Smith    SNESComputeJacobian - Computes the Jacobian matrix that has been set with SNESSetJacobian().
220062fef451SLois Curfman McInnes 
2201c7afd0dbSLois Curfman McInnes    Collective on SNES and Mat
2202c7afd0dbSLois Curfman McInnes 
220362fef451SLois Curfman McInnes    Input Parameters:
2204c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2205c7afd0dbSLois Curfman McInnes -  x - input vector
220662fef451SLois Curfman McInnes 
220762fef451SLois Curfman McInnes    Output Parameters:
2208c7afd0dbSLois Curfman McInnes +  A - Jacobian matrix
2209d1e9a80fSBarry Smith -  B - optional preconditioning matrix
2210fee21e36SBarry Smith 
2211e35cf81dSBarry Smith   Options Database Keys:
2212e35cf81dSBarry Smith +    -snes_lag_preconditioner <lag>
2213693365a8SJed Brown .    -snes_lag_jacobian <lag>
2214693365a8SJed Brown .    -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences
2215693365a8SJed Brown .    -snes_compare_explicit_draw  - Compare the computed Jacobian to the finite difference Jacobian and draw the result
2216693365a8SJed Brown .    -snes_compare_explicit_contour  - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result
22174c30e9fbSJed Brown .    -snes_compare_operator  - Make the comparison options above use the operator instead of the preconditioning matrix
221894d6a431SBarry Smith .    -snes_compare_coloring - Compute the finite difference Jacobian using coloring and display norms of difference
2219c01495d3SJed Brown .    -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences
2220c01495d3SJed Brown .    -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold
2221c01495d3SJed Brown .    -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
2222c01495d3SJed Brown .    -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
22234c30e9fbSJed Brown .    -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences
2224c01495d3SJed Brown -    -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences
2225c01495d3SJed Brown 
2226e35cf81dSBarry Smith 
222762fef451SLois Curfman McInnes    Notes:
222862fef451SLois Curfman McInnes    Most users should not need to explicitly call this routine, as it
222962fef451SLois Curfman McInnes    is used internally within the nonlinear solvers.
223062fef451SLois Curfman McInnes 
223136851e7fSLois Curfman McInnes    Level: developer
223236851e7fSLois Curfman McInnes 
223362fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix
223462fef451SLois Curfman McInnes 
2235e35cf81dSBarry Smith .seealso:  SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian()
223662fef451SLois Curfman McInnes @*/
2237d1e9a80fSBarry Smith PetscErrorCode  SNESComputeJacobian(SNES snes,Vec X,Mat A,Mat B)
22389b94acceSBarry Smith {
2239dfbe8321SBarry Smith   PetscErrorCode ierr;
2240ace3abfcSBarry Smith   PetscBool      flag;
22416cab3a1bSJed Brown   DM             dm;
2242942e3340SBarry Smith   DMSNES         sdm;
2243e0e3a89bSBarry Smith   KSP            ksp;
22443a40ed3dSBarry Smith 
22453a40ed3dSBarry Smith   PetscFunctionBegin;
22460700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
22470700a824SBarry Smith   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
2248c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,X,2);
224962796dfbSBarry Smith   ierr = VecValidValues(X,2,PETSC_TRUE);CHKERRQ(ierr);
22506cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2251942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
22523232da50SPeter Brune 
2253ce94432eSBarry Smith   if (!sdm->ops->computejacobian) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc");
2254ebd3b9afSBarry Smith 
2255ebd3b9afSBarry Smith   /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */
2256ebd3b9afSBarry Smith 
2257fe3ffe1eSBarry Smith   if (snes->lagjacobian == -2) {
2258fe3ffe1eSBarry Smith     snes->lagjacobian = -1;
2259f5af7f23SKarl Rupp 
2260fe3ffe1eSBarry Smith     ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr);
2261fe3ffe1eSBarry Smith   } else if (snes->lagjacobian == -1) {
2262e35cf81dSBarry Smith     ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr);
226394ab13aaSBarry Smith     ierr = PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag);CHKERRQ(ierr);
2264ebd3b9afSBarry Smith     if (flag) {
226594ab13aaSBarry Smith       ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
226694ab13aaSBarry Smith       ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2267ebd3b9afSBarry Smith     }
2268e35cf81dSBarry Smith     PetscFunctionReturn(0);
226937ec4e1aSPeter Brune   } else if (snes->lagjacobian > 1 && (snes->iter + snes->jac_iter) % snes->lagjacobian) {
2270e35cf81dSBarry Smith     ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr);
227194ab13aaSBarry Smith     ierr = PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag);CHKERRQ(ierr);
2272ebd3b9afSBarry Smith     if (flag) {
227394ab13aaSBarry Smith       ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
227494ab13aaSBarry Smith       ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2275ebd3b9afSBarry Smith     }
2276e35cf81dSBarry Smith     PetscFunctionReturn(0);
2277e35cf81dSBarry Smith   }
2278*efd4aadfSBarry Smith   if (snes->npc && snes->npcside== PC_LEFT) {
227994ab13aaSBarry Smith       ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
228094ab13aaSBarry Smith       ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2281d728fb7dSPeter Brune       PetscFunctionReturn(0);
2282d728fb7dSPeter Brune   }
2283e35cf81dSBarry Smith 
228494ab13aaSBarry Smith   ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,A,B);CHKERRQ(ierr);
22855edff71fSBarry Smith   ierr = VecLockPush(X);CHKERRQ(ierr);
2286d64ed03dSBarry Smith   PetscStackPush("SNES user Jacobian function");
2287d1e9a80fSBarry Smith   ierr = (*sdm->ops->computejacobian)(snes,X,A,B,sdm->jacobianctx);CHKERRQ(ierr);
2288d64ed03dSBarry Smith   PetscStackPop;
22895edff71fSBarry Smith   ierr = VecLockPop(X);CHKERRQ(ierr);
229094ab13aaSBarry Smith   ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,A,B);CHKERRQ(ierr);
2291a8054027SBarry Smith 
2292e0e3a89bSBarry Smith   /* the next line ensures that snes->ksp exists */
2293e0e3a89bSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
22943b4f5425SBarry Smith   if (snes->lagpreconditioner == -2) {
22953b4f5425SBarry Smith     ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr);
2296d1e9a80fSBarry Smith     ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE);CHKERRQ(ierr);
22973b4f5425SBarry Smith     snes->lagpreconditioner = -1;
22983b4f5425SBarry Smith   } else if (snes->lagpreconditioner == -1) {
2299a8054027SBarry Smith     ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr);
2300d1e9a80fSBarry Smith     ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE);CHKERRQ(ierr);
230137ec4e1aSPeter Brune   } else if (snes->lagpreconditioner > 1 && (snes->iter + snes->pre_iter) % snes->lagpreconditioner) {
2302a8054027SBarry Smith     ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr);
2303d1e9a80fSBarry Smith     ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE);CHKERRQ(ierr);
2304d1e9a80fSBarry Smith   } else {
2305d1e9a80fSBarry Smith     ierr = PetscInfo(snes,"Rebuilding preconditioner\n");CHKERRQ(ierr);
2306d1e9a80fSBarry Smith     ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE);CHKERRQ(ierr);
2307a8054027SBarry Smith   }
2308a8054027SBarry Smith 
23096d84be18SBarry Smith   /* make sure user returned a correct Jacobian and preconditioner */
231094ab13aaSBarry Smith   /* PetscValidHeaderSpecific(A,MAT_CLASSID,3);
231194ab13aaSBarry Smith     PetscValidHeaderSpecific(B,MAT_CLASSID,4);   */
2312693365a8SJed Brown   {
2313693365a8SJed Brown     PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE;
231427b0f280SBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_explicit",NULL,NULL,&flag);CHKERRQ(ierr);
231527b0f280SBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",NULL,NULL,&flag_draw);CHKERRQ(ierr);
231627b0f280SBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",NULL,NULL,&flag_contour);CHKERRQ(ierr);
231727b0f280SBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_operator",NULL,NULL,&flag_operator);CHKERRQ(ierr);
2318693365a8SJed Brown     if (flag || flag_draw || flag_contour) {
23190298fd71SBarry Smith       Mat          Bexp_mine = NULL,Bexp,FDexp;
2320693365a8SJed Brown       PetscViewer  vdraw,vstdout;
23216b3a5b13SJed Brown       PetscBool    flg;
2322693365a8SJed Brown       if (flag_operator) {
232394ab13aaSBarry Smith         ierr = MatComputeExplicitOperator(A,&Bexp_mine);CHKERRQ(ierr);
2324693365a8SJed Brown         Bexp = Bexp_mine;
2325693365a8SJed Brown       } else {
2326693365a8SJed Brown         /* See if the preconditioning matrix can be viewed and added directly */
232794ab13aaSBarry Smith         ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr);
232894ab13aaSBarry Smith         if (flg) Bexp = B;
2329693365a8SJed Brown         else {
2330693365a8SJed Brown           /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */
233194ab13aaSBarry Smith           ierr = MatComputeExplicitOperator(B,&Bexp_mine);CHKERRQ(ierr);
2332693365a8SJed Brown           Bexp = Bexp_mine;
2333693365a8SJed Brown         }
2334693365a8SJed Brown       }
2335693365a8SJed Brown       ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr);
2336d1e9a80fSBarry Smith       ierr = SNESComputeJacobianDefault(snes,X,FDexp,FDexp,NULL);CHKERRQ(ierr);
2337ce94432eSBarry Smith       ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout);CHKERRQ(ierr);
2338693365a8SJed Brown       if (flag_draw || flag_contour) {
2339ce94432eSBarry Smith         ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
2340693365a8SJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
23410298fd71SBarry Smith       } else vdraw = NULL;
2342693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator ? "Jacobian" : "preconditioning Jacobian");CHKERRQ(ierr);
2343693365a8SJed Brown       if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);}
2344693365a8SJed Brown       if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);}
2345693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr);
2346693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
2347693365a8SJed Brown       if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);}
2348693365a8SJed Brown       ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2349693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr);
2350693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
2351693365a8SJed Brown       if (vdraw) {              /* Always use contour for the difference */
2352693365a8SJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
2353693365a8SJed Brown         ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);
2354693365a8SJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
2355693365a8SJed Brown       }
2356693365a8SJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
2357693365a8SJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
2358693365a8SJed Brown       ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr);
2359693365a8SJed Brown       ierr = MatDestroy(&FDexp);CHKERRQ(ierr);
2360693365a8SJed Brown     }
2361693365a8SJed Brown   }
23624c30e9fbSJed Brown   {
23636719d8e4SJed Brown     PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE;
23646719d8e4SJed Brown     PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON;
236527b0f280SBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring",NULL,NULL,&flag);CHKERRQ(ierr);
236627b0f280SBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring_display",NULL,NULL,&flag_display);CHKERRQ(ierr);
236727b0f280SBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",NULL,NULL,&flag_draw);CHKERRQ(ierr);
236827b0f280SBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",NULL,NULL,&flag_contour);CHKERRQ(ierr);
236927b0f280SBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",NULL,NULL,&flag_threshold);CHKERRQ(ierr);
237027b0f280SBarry Smith     if (flag_threshold) {
2371c5929fdfSBarry Smith       ierr = PetscOptionsGetReal(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,NULL);CHKERRQ(ierr);
2372c5929fdfSBarry Smith       ierr = PetscOptionsGetReal(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,NULL);CHKERRQ(ierr);
237327b0f280SBarry Smith     }
23746719d8e4SJed Brown     if (flag || flag_display || flag_draw || flag_contour || flag_threshold) {
23754c30e9fbSJed Brown       Mat            Bfd;
23764c30e9fbSJed Brown       PetscViewer    vdraw,vstdout;
2377335efc43SPeter Brune       MatColoring    coloring;
23784c30e9fbSJed Brown       ISColoring     iscoloring;
23794c30e9fbSJed Brown       MatFDColoring  matfdcoloring;
23804c30e9fbSJed Brown       PetscErrorCode (*func)(SNES,Vec,Vec,void*);
23814c30e9fbSJed Brown       void           *funcctx;
23826719d8e4SJed Brown       PetscReal      norm1,norm2,normmax;
23834c30e9fbSJed Brown 
238494ab13aaSBarry Smith       ierr = MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr);
2385335efc43SPeter Brune       ierr = MatColoringCreate(Bfd,&coloring);CHKERRQ(ierr);
2386335efc43SPeter Brune       ierr = MatColoringSetType(coloring,MATCOLORINGSL);CHKERRQ(ierr);
2387335efc43SPeter Brune       ierr = MatColoringSetFromOptions(coloring);CHKERRQ(ierr);
2388335efc43SPeter Brune       ierr = MatColoringApply(coloring,&iscoloring);CHKERRQ(ierr);
2389335efc43SPeter Brune       ierr = MatColoringDestroy(&coloring);CHKERRQ(ierr);
23904c30e9fbSJed Brown       ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr);
2391f86b9fbaSHong Zhang       ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr);
2392f86b9fbaSHong Zhang       ierr = MatFDColoringSetUp(Bfd,iscoloring,matfdcoloring);CHKERRQ(ierr);
23934c30e9fbSJed Brown       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
23944c30e9fbSJed Brown 
23954c30e9fbSJed Brown       /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */
23960298fd71SBarry Smith       ierr = SNESGetFunction(snes,NULL,&func,&funcctx);CHKERRQ(ierr);
23974c30e9fbSJed Brown       ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode (*)(void))func,funcctx);CHKERRQ(ierr);
23984c30e9fbSJed Brown       ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr);
23994c30e9fbSJed Brown       ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr);
24004c30e9fbSJed Brown       ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr);
2401d1e9a80fSBarry Smith       ierr = MatFDColoringApply(Bfd,matfdcoloring,X,snes);CHKERRQ(ierr);
24024c30e9fbSJed Brown       ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr);
24034c30e9fbSJed Brown 
2404ce94432eSBarry Smith       ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout);CHKERRQ(ierr);
24054c30e9fbSJed Brown       if (flag_draw || flag_contour) {
2406ce94432eSBarry Smith         ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
24074c30e9fbSJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
24080298fd71SBarry Smith       } else vdraw = NULL;
24094c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr);
241094ab13aaSBarry Smith       if (flag_display) {ierr = MatView(B,vstdout);CHKERRQ(ierr);}
241194ab13aaSBarry Smith       if (vdraw) {ierr = MatView(B,vdraw);CHKERRQ(ierr);}
24124c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr);
24136719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
24144c30e9fbSJed Brown       if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);}
241594ab13aaSBarry Smith       ierr = MatAYPX(Bfd,-1.0,B,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
24164c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr);
24176719d8e4SJed Brown       ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr);
24184c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr);
241957622a8eSBarry 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);
24206719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
24214c30e9fbSJed Brown       if (vdraw) {              /* Always use contour for the difference */
24224c30e9fbSJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
24234c30e9fbSJed Brown         ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);
24244c30e9fbSJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
24254c30e9fbSJed Brown       }
24264c30e9fbSJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
24276719d8e4SJed Brown 
24286719d8e4SJed Brown       if (flag_threshold) {
24296719d8e4SJed Brown         PetscInt bs,rstart,rend,i;
243094ab13aaSBarry Smith         ierr = MatGetBlockSize(B,&bs);CHKERRQ(ierr);
243194ab13aaSBarry Smith         ierr = MatGetOwnershipRange(B,&rstart,&rend);CHKERRQ(ierr);
24326719d8e4SJed Brown         for (i=rstart; i<rend; i++) {
24336719d8e4SJed Brown           const PetscScalar *ba,*ca;
24346719d8e4SJed Brown           const PetscInt    *bj,*cj;
24356719d8e4SJed Brown           PetscInt          bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1;
24366719d8e4SJed Brown           PetscReal         maxentry = 0,maxdiff = 0,maxrdiff = 0;
243794ab13aaSBarry Smith           ierr = MatGetRow(B,i,&bn,&bj,&ba);CHKERRQ(ierr);
24386719d8e4SJed Brown           ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
243994ab13aaSBarry Smith           if (bn != cn) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold");
24406719d8e4SJed Brown           for (j=0; j<bn; j++) {
24416719d8e4SJed Brown             PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
24426719d8e4SJed Brown             if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) {
24436719d8e4SJed Brown               maxentrycol = bj[j];
24446719d8e4SJed Brown               maxentry    = PetscRealPart(ba[j]);
24456719d8e4SJed Brown             }
24466719d8e4SJed Brown             if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) {
24476719d8e4SJed Brown               maxdiffcol = bj[j];
24486719d8e4SJed Brown               maxdiff    = PetscRealPart(ca[j]);
24496719d8e4SJed Brown             }
24506719d8e4SJed Brown             if (rdiff > maxrdiff) {
24516719d8e4SJed Brown               maxrdiffcol = bj[j];
24526719d8e4SJed Brown               maxrdiff    = rdiff;
24536719d8e4SJed Brown             }
24546719d8e4SJed Brown           }
24556719d8e4SJed Brown           if (maxrdiff > 1) {
245657622a8eSBarry 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);
24576719d8e4SJed Brown             for (j=0; j<bn; j++) {
24586719d8e4SJed Brown               PetscReal rdiff;
24596719d8e4SJed Brown               rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
24606719d8e4SJed Brown               if (rdiff > 1) {
246157622a8eSBarry Smith                 ierr = PetscViewerASCIIPrintf(vstdout," (%D,%g:%g)",bj[j],(double)PetscRealPart(ba[j]),(double)PetscRealPart(ca[j]));CHKERRQ(ierr);
24626719d8e4SJed Brown               }
24636719d8e4SJed Brown             }
24646719d8e4SJed Brown             ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr);
24656719d8e4SJed Brown           }
246694ab13aaSBarry Smith           ierr = MatRestoreRow(B,i,&bn,&bj,&ba);CHKERRQ(ierr);
24676719d8e4SJed Brown           ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
24686719d8e4SJed Brown         }
24696719d8e4SJed Brown       }
24704c30e9fbSJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
24714c30e9fbSJed Brown       ierr = MatDestroy(&Bfd);CHKERRQ(ierr);
24724c30e9fbSJed Brown     }
24734c30e9fbSJed Brown   }
24743a40ed3dSBarry Smith   PetscFunctionReturn(0);
24759b94acceSBarry Smith }
24769b94acceSBarry Smith 
2477bf388a1fSBarry Smith /*MC
2478411c0326SBarry Smith     SNESJacobianFunction - Function used to convey the nonlinear Jacobian of the function to be solved by SNES
2479bf388a1fSBarry Smith 
2480bf388a1fSBarry Smith      Synopsis:
2481411c0326SBarry Smith      #include "petscsnes.h"
2482411c0326SBarry Smith      PetscErrorCode SNESJacobianFunction(SNES snes,Vec x,Mat Amat,Mat Pmat,void *ctx);
2483bf388a1fSBarry Smith 
2484bf388a1fSBarry Smith +  x - input vector
2485e5d3d808SBarry Smith .  Amat - the matrix that defines the (approximate) Jacobian
2486e5d3d808SBarry Smith .  Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat.
2487bf388a1fSBarry Smith -  ctx - [optional] user-defined Jacobian context
2488bf388a1fSBarry Smith 
2489878cb397SSatish Balay    Level: intermediate
2490878cb397SSatish Balay 
2491bf388a1fSBarry Smith .seealso:   SNESSetFunction(), SNESGetFunction(), SNESSetJacobian(), SNESGetJacobian()
2492bf388a1fSBarry Smith M*/
2493bf388a1fSBarry Smith 
24949b94acceSBarry Smith /*@C
24959b94acceSBarry Smith    SNESSetJacobian - Sets the function to compute Jacobian as well as the
2496044dda88SLois Curfman McInnes    location to store the matrix.
24979b94acceSBarry Smith 
24983f9fe445SBarry Smith    Logically Collective on SNES and Mat
2499c7afd0dbSLois Curfman McInnes 
25009b94acceSBarry Smith    Input Parameters:
2501c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2502e5d3d808SBarry Smith .  Amat - the matrix that defines the (approximate) Jacobian
2503e5d3d808SBarry Smith .  Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat.
2504411c0326SBarry Smith .  J - Jacobian evaluation routine (if NULL then SNES retains any previously set value), see SNESJacobianFunction for details
2505c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
25060298fd71SBarry Smith          Jacobian evaluation routine (may be NULL) (if NULL then SNES retains any previously set value)
25079b94acceSBarry Smith 
25089b94acceSBarry Smith    Notes:
2509e5d3d808SBarry Smith    If the Amat matrix and Pmat matrix are different you must call MatAssemblyBegin/End() on
251016913363SBarry Smith    each matrix.
251116913363SBarry Smith 
2512895c21f2SBarry Smith    If you know the operator Amat has a null space you can use MatSetNullSpace() and MatSetTransposeNullSpace() to supply the null
2513895c21f2SBarry Smith    space to Amat and the KSP solvers will automatically use that null space as needed during the solution process.
2514895c21f2SBarry Smith 
25158d359177SBarry Smith    If using SNESComputeJacobianDefaultColor() to assemble a Jacobian, the ctx argument
2516a8a26c1eSJed Brown    must be a MatFDColoring.
2517a8a26c1eSJed Brown 
2518c3cc8fd1SJed Brown    Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian.  One common
2519c3cc8fd1SJed Brown    example is to use the "Picard linearization" which only differentiates through the highest order parts of each term.
2520c3cc8fd1SJed Brown 
252136851e7fSLois Curfman McInnes    Level: beginner
252236851e7fSLois Curfman McInnes 
25239b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix
25249b94acceSBarry Smith 
2525411c0326SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESComputeJacobianDefaultColor(), MatStructure, J,
2526411c0326SBarry Smith           SNESSetPicard(), SNESJacobianFunction
25279b94acceSBarry Smith @*/
2528d1e9a80fSBarry Smith PetscErrorCode  SNESSetJacobian(SNES snes,Mat Amat,Mat Pmat,PetscErrorCode (*J)(SNES,Vec,Mat,Mat,void*),void *ctx)
25299b94acceSBarry Smith {
2530dfbe8321SBarry Smith   PetscErrorCode ierr;
25316cab3a1bSJed Brown   DM             dm;
25323a7fca6bSBarry Smith 
25333a40ed3dSBarry Smith   PetscFunctionBegin;
25340700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2535e5d3d808SBarry Smith   if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2);
2536e5d3d808SBarry Smith   if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_CLASSID,3);
2537e5d3d808SBarry Smith   if (Amat) PetscCheckSameComm(snes,1,Amat,2);
2538e5d3d808SBarry Smith   if (Pmat) PetscCheckSameComm(snes,1,Pmat,3);
25396cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2540f8b49ee9SBarry Smith   ierr = DMSNESSetJacobian(dm,J,ctx);CHKERRQ(ierr);
2541e5d3d808SBarry Smith   if (Amat) {
2542e5d3d808SBarry Smith     ierr = PetscObjectReference((PetscObject)Amat);CHKERRQ(ierr);
25436bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
2544f5af7f23SKarl Rupp 
2545e5d3d808SBarry Smith     snes->jacobian = Amat;
25463a7fca6bSBarry Smith   }
2547e5d3d808SBarry Smith   if (Pmat) {
2548e5d3d808SBarry Smith     ierr = PetscObjectReference((PetscObject)Pmat);CHKERRQ(ierr);
25496bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
2550f5af7f23SKarl Rupp 
2551e5d3d808SBarry Smith     snes->jacobian_pre = Pmat;
25523a7fca6bSBarry Smith   }
25533a40ed3dSBarry Smith   PetscFunctionReturn(0);
25549b94acceSBarry Smith }
255562fef451SLois Curfman McInnes 
2556c2aafc4cSSatish Balay /*@C
2557b4fd4287SBarry Smith    SNESGetJacobian - Returns the Jacobian matrix and optionally the user
2558b4fd4287SBarry Smith    provided context for evaluating the Jacobian.
2559b4fd4287SBarry Smith 
2560c7afd0dbSLois Curfman McInnes    Not Collective, but Mat object will be parallel if SNES object is
2561c7afd0dbSLois Curfman McInnes 
2562b4fd4287SBarry Smith    Input Parameter:
2563b4fd4287SBarry Smith .  snes - the nonlinear solver context
2564b4fd4287SBarry Smith 
2565b4fd4287SBarry Smith    Output Parameters:
2566e5d3d808SBarry Smith +  Amat - location to stash (approximate) Jacobian matrix (or NULL)
2567e5d3d808SBarry Smith .  Pmat - location to stash matrix used to compute the preconditioner (or NULL)
2568411c0326SBarry Smith .  J - location to put Jacobian function (or NULL), see SNESJacobianFunction for details on its calling sequence
25690298fd71SBarry Smith -  ctx - location to stash Jacobian ctx (or NULL)
2570fee21e36SBarry Smith 
257136851e7fSLois Curfman McInnes    Level: advanced
257236851e7fSLois Curfman McInnes 
2573411c0326SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian(), SNESJacobianFunction, SNESGetFunction()
2574b4fd4287SBarry Smith @*/
2575d1e9a80fSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *Amat,Mat *Pmat,PetscErrorCode (**J)(SNES,Vec,Mat,Mat,void*),void **ctx)
2576b4fd4287SBarry Smith {
25776cab3a1bSJed Brown   PetscErrorCode ierr;
25786cab3a1bSJed Brown   DM             dm;
2579942e3340SBarry Smith   DMSNES         sdm;
25806cab3a1bSJed Brown 
25813a40ed3dSBarry Smith   PetscFunctionBegin;
25820700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2583e5d3d808SBarry Smith   if (Amat) *Amat = snes->jacobian;
2584e5d3d808SBarry Smith   if (Pmat) *Pmat = snes->jacobian_pre;
25856cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2586942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
2587f8b49ee9SBarry Smith   if (J) *J = sdm->ops->computejacobian;
25886cab3a1bSJed Brown   if (ctx) *ctx = sdm->jacobianctx;
25893a40ed3dSBarry Smith   PetscFunctionReturn(0);
2590b4fd4287SBarry Smith }
2591b4fd4287SBarry Smith 
25929b94acceSBarry Smith /*@
25939b94acceSBarry Smith    SNESSetUp - Sets up the internal data structures for the later use
2594272ac6f2SLois Curfman McInnes    of a nonlinear solver.
25959b94acceSBarry Smith 
2596fee21e36SBarry Smith    Collective on SNES
2597fee21e36SBarry Smith 
2598c7afd0dbSLois Curfman McInnes    Input Parameters:
259970e92668SMatthew Knepley .  snes - the SNES context
2600c7afd0dbSLois Curfman McInnes 
2601272ac6f2SLois Curfman McInnes    Notes:
2602272ac6f2SLois Curfman McInnes    For basic use of the SNES solvers the user need not explicitly call
2603272ac6f2SLois Curfman McInnes    SNESSetUp(), since these actions will automatically occur during
2604272ac6f2SLois Curfman McInnes    the call to SNESSolve().  However, if one wishes to control this
2605272ac6f2SLois Curfman McInnes    phase separately, SNESSetUp() should be called after SNESCreate()
2606272ac6f2SLois Curfman McInnes    and optional routines of the form SNESSetXXX(), but before SNESSolve().
2607272ac6f2SLois Curfman McInnes 
260836851e7fSLois Curfman McInnes    Level: advanced
260936851e7fSLois Curfman McInnes 
26109b94acceSBarry Smith .keywords: SNES, nonlinear, setup
26119b94acceSBarry Smith 
26129b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
26139b94acceSBarry Smith @*/
26147087cfbeSBarry Smith PetscErrorCode  SNESSetUp(SNES snes)
26159b94acceSBarry Smith {
2616dfbe8321SBarry Smith   PetscErrorCode ierr;
26176cab3a1bSJed Brown   DM             dm;
2618942e3340SBarry Smith   DMSNES         sdm;
2619c35f09e5SBarry Smith   SNESLineSearch linesearch, pclinesearch;
26206e2a1849SPeter Brune   void           *lsprectx,*lspostctx;
26216b2b7091SBarry Smith   PetscErrorCode (*precheck)(SNESLineSearch,Vec,Vec,PetscBool*,void*);
26226b2b7091SBarry Smith   PetscErrorCode (*postcheck)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*);
26236e2a1849SPeter Brune   PetscErrorCode (*func)(SNES,Vec,Vec,void*);
26246e2a1849SPeter Brune   Vec            f,fpc;
26256e2a1849SPeter Brune   void           *funcctx;
2626d1e9a80fSBarry Smith   PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*);
26271eb13d49SPeter Brune   void           *jacctx,*appctx;
262832b97717SPeter Brune   Mat            j,jpre;
26293a40ed3dSBarry Smith 
26303a40ed3dSBarry Smith   PetscFunctionBegin;
26310700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
26324dc4c822SBarry Smith   if (snes->setupcalled) PetscFunctionReturn(0);
26339b94acceSBarry Smith 
26347adad957SLisandro Dalcin   if (!((PetscObject)snes)->type_name) {
263504d7464bSBarry Smith     ierr = SNESSetType(snes,SNESNEWTONLS);CHKERRQ(ierr);
263685385478SLisandro Dalcin   }
263785385478SLisandro Dalcin 
26380298fd71SBarry Smith   ierr = SNESGetFunction(snes,&snes->vec_func,NULL,NULL);CHKERRQ(ierr);
263958c9b817SLisandro Dalcin 
26406cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2641942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
2642ce94432eSBarry Smith   if (!sdm->ops->computefunction) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Function never provided to SNES object");
264322c6f798SBarry Smith   if (!sdm->ops->computejacobian) {
26448d359177SBarry Smith     ierr = DMSNESSetJacobian(dm,SNESComputeJacobianDefaultColor,NULL);CHKERRQ(ierr);
264519f7a02aSBarry Smith   }
26466cab3a1bSJed Brown   if (!snes->vec_func) {
26476cab3a1bSJed Brown     ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr);
2648214df951SJed Brown   }
2649efd51863SBarry Smith 
265022d28d08SBarry Smith   if (!snes->ksp) {
265122d28d08SBarry Smith     ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);
265222d28d08SBarry Smith   }
2653b710008aSBarry Smith 
265422d28d08SBarry Smith   if (!snes->linesearch) {
26557601faf0SJed Brown     ierr = SNESGetLineSearch(snes, &snes->linesearch);CHKERRQ(ierr);
265622d28d08SBarry Smith   }
2657ed07d7d7SPeter Brune   ierr = SNESLineSearchSetFunction(snes->linesearch,SNESComputeFunction);CHKERRQ(ierr);
26589e764e56SPeter Brune 
2659*efd4aadfSBarry Smith   if (snes->npc && (snes->npcside== PC_LEFT)) {
2660172a4300SPeter Brune     snes->mf          = PETSC_TRUE;
2661172a4300SPeter Brune     snes->mf_operator = PETSC_FALSE;
2662172a4300SPeter Brune   }
2663d8f46077SPeter Brune 
2664*efd4aadfSBarry Smith   if (snes->npc) {
26656e2a1849SPeter Brune     /* copy the DM over */
26666e2a1849SPeter Brune     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2667*efd4aadfSBarry Smith     ierr = SNESSetDM(snes->npc,dm);CHKERRQ(ierr);
26686e2a1849SPeter Brune 
26696e2a1849SPeter Brune     ierr = SNESGetFunction(snes,&f,&func,&funcctx);CHKERRQ(ierr);
26706e2a1849SPeter Brune     ierr = VecDuplicate(f,&fpc);CHKERRQ(ierr);
2671*efd4aadfSBarry Smith     ierr = SNESSetFunction(snes->npc,fpc,func,funcctx);CHKERRQ(ierr);
267232b97717SPeter Brune     ierr = SNESGetJacobian(snes,&j,&jpre,&jac,&jacctx);CHKERRQ(ierr);
2673*efd4aadfSBarry Smith     ierr = SNESSetJacobian(snes->npc,j,jpre,jac,jacctx);CHKERRQ(ierr);
26741eb13d49SPeter Brune     ierr = SNESGetApplicationContext(snes,&appctx);CHKERRQ(ierr);
2675*efd4aadfSBarry Smith     ierr = SNESSetApplicationContext(snes->npc,appctx);CHKERRQ(ierr);
26766e2a1849SPeter Brune     ierr = VecDestroy(&fpc);CHKERRQ(ierr);
26776e2a1849SPeter Brune 
26786e2a1849SPeter Brune     /* copy the function pointers over */
2679*efd4aadfSBarry Smith     ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)snes,(PetscObject)snes->npc);CHKERRQ(ierr);
26806e2a1849SPeter Brune 
26816e2a1849SPeter Brune     /* default to 1 iteration */
2682*efd4aadfSBarry Smith     ierr = SNESSetTolerances(snes->npc,0.0,0.0,0.0,1,snes->npc->max_funcs);CHKERRQ(ierr);
2683*efd4aadfSBarry Smith     if (snes->npcside==PC_RIGHT) {
2684*efd4aadfSBarry Smith       ierr = SNESSetNormSchedule(snes->npc,SNES_NORM_FINAL_ONLY);CHKERRQ(ierr);
2685a9936a0cSPeter Brune     } else {
2686*efd4aadfSBarry Smith       ierr = SNESSetNormSchedule(snes->npc,SNES_NORM_NONE);CHKERRQ(ierr);
2687a9936a0cSPeter Brune     }
2688*efd4aadfSBarry Smith     ierr = SNESSetFromOptions(snes->npc);CHKERRQ(ierr);
26896e2a1849SPeter Brune 
26906e2a1849SPeter Brune     /* copy the line search context over */
26917601faf0SJed Brown     ierr = SNESGetLineSearch(snes,&linesearch);CHKERRQ(ierr);
2692*efd4aadfSBarry Smith     ierr = SNESGetLineSearch(snes->npc,&pclinesearch);CHKERRQ(ierr);
26936b2b7091SBarry Smith     ierr = SNESLineSearchGetPreCheck(linesearch,&precheck,&lsprectx);CHKERRQ(ierr);
26946b2b7091SBarry Smith     ierr = SNESLineSearchGetPostCheck(linesearch,&postcheck,&lspostctx);CHKERRQ(ierr);
26956b2b7091SBarry Smith     ierr = SNESLineSearchSetPreCheck(pclinesearch,precheck,lsprectx);CHKERRQ(ierr);
26966b2b7091SBarry Smith     ierr = SNESLineSearchSetPostCheck(pclinesearch,postcheck,lspostctx);CHKERRQ(ierr);
26976e2a1849SPeter Brune     ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch);CHKERRQ(ierr);
26986e2a1849SPeter Brune   }
269932b97717SPeter Brune   if (snes->mf) {
270032b97717SPeter Brune     ierr = SNESSetUpMatrixFree_Private(snes, snes->mf_operator, snes->mf_version);CHKERRQ(ierr);
270132b97717SPeter Brune   }
270232b97717SPeter Brune   if (snes->ops->usercompute && !snes->user) {
270332b97717SPeter Brune     ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr);
270432b97717SPeter Brune   }
27056e2a1849SPeter Brune 
270637ec4e1aSPeter Brune   snes->jac_iter = 0;
270737ec4e1aSPeter Brune   snes->pre_iter = 0;
270837ec4e1aSPeter Brune 
2709410397dcSLisandro Dalcin   if (snes->ops->setup) {
2710410397dcSLisandro Dalcin     ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr);
2711410397dcSLisandro Dalcin   }
271258c9b817SLisandro Dalcin 
2713*efd4aadfSBarry Smith   if (snes->npc && (snes->npcside== PC_LEFT)) {
27146c67d002SPeter Brune     if (snes->functype == SNES_FUNCTION_PRECONDITIONED) {
271555d4788fSPeter Brune       ierr = SNESGetLineSearch(snes,&linesearch);CHKERRQ(ierr);
2716be95d8f1SBarry Smith       ierr = SNESLineSearchSetFunction(linesearch,SNESComputeFunctionDefaultNPC);CHKERRQ(ierr);
27176c67d002SPeter Brune     }
27186c67d002SPeter Brune   }
27196c67d002SPeter Brune 
27207aaed0d8SBarry Smith   snes->setupcalled = PETSC_TRUE;
27213a40ed3dSBarry Smith   PetscFunctionReturn(0);
27229b94acceSBarry Smith }
27239b94acceSBarry Smith 
272437596af1SLisandro Dalcin /*@
272537596af1SLisandro Dalcin    SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats
272637596af1SLisandro Dalcin 
272737596af1SLisandro Dalcin    Collective on SNES
272837596af1SLisandro Dalcin 
272937596af1SLisandro Dalcin    Input Parameter:
273037596af1SLisandro Dalcin .  snes - iterative context obtained from SNESCreate()
273137596af1SLisandro Dalcin 
2732d25893d9SBarry Smith    Level: intermediate
2733d25893d9SBarry Smith 
2734d25893d9SBarry Smith    Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext()
273537596af1SLisandro Dalcin 
273637596af1SLisandro Dalcin .keywords: SNES, destroy
273737596af1SLisandro Dalcin 
273837596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve()
273937596af1SLisandro Dalcin @*/
274037596af1SLisandro Dalcin PetscErrorCode  SNESReset(SNES snes)
274137596af1SLisandro Dalcin {
274237596af1SLisandro Dalcin   PetscErrorCode ierr;
274337596af1SLisandro Dalcin 
274437596af1SLisandro Dalcin   PetscFunctionBegin;
274537596af1SLisandro Dalcin   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2746d25893d9SBarry Smith   if (snes->ops->userdestroy && snes->user) {
2747d25893d9SBarry Smith     ierr       = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr);
27480298fd71SBarry Smith     snes->user = NULL;
2749d25893d9SBarry Smith   }
2750*efd4aadfSBarry Smith   if (snes->npc) {
2751*efd4aadfSBarry Smith     ierr = SNESReset(snes->npc);CHKERRQ(ierr);
27528a23116dSBarry Smith   }
27538a23116dSBarry Smith 
275437596af1SLisandro Dalcin   if (snes->ops->reset) {
275537596af1SLisandro Dalcin     ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr);
275637596af1SLisandro Dalcin   }
27579e764e56SPeter Brune   if (snes->ksp) {
27589e764e56SPeter Brune     ierr = KSPReset(snes->ksp);CHKERRQ(ierr);
27599e764e56SPeter Brune   }
27609e764e56SPeter Brune 
27619e764e56SPeter Brune   if (snes->linesearch) {
2762f1c6b773SPeter Brune     ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr);
27639e764e56SPeter Brune   }
27649e764e56SPeter Brune 
27656bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
27666bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
27676bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr);
27686bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
27696bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
27706bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
2771c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);
2772c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);
2773f5af7f23SKarl Rupp 
277440fdac6aSLawrence Mitchell   snes->alwayscomputesfinalresidual = PETSC_FALSE;
277540fdac6aSLawrence Mitchell 
277637596af1SLisandro Dalcin   snes->nwork       = snes->nvwork = 0;
277737596af1SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
277837596af1SLisandro Dalcin   PetscFunctionReturn(0);
277937596af1SLisandro Dalcin }
278037596af1SLisandro Dalcin 
278152baeb72SSatish Balay /*@
27829b94acceSBarry Smith    SNESDestroy - Destroys the nonlinear solver context that was created
27839b94acceSBarry Smith    with SNESCreate().
27849b94acceSBarry Smith 
2785c7afd0dbSLois Curfman McInnes    Collective on SNES
2786c7afd0dbSLois Curfman McInnes 
27879b94acceSBarry Smith    Input Parameter:
27889b94acceSBarry Smith .  snes - the SNES context
27899b94acceSBarry Smith 
279036851e7fSLois Curfman McInnes    Level: beginner
279136851e7fSLois Curfman McInnes 
27929b94acceSBarry Smith .keywords: SNES, nonlinear, destroy
27939b94acceSBarry Smith 
279463a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve()
27959b94acceSBarry Smith @*/
27966bf464f9SBarry Smith PetscErrorCode  SNESDestroy(SNES *snes)
27979b94acceSBarry Smith {
27986849ba73SBarry Smith   PetscErrorCode ierr;
27993a40ed3dSBarry Smith 
28003a40ed3dSBarry Smith   PetscFunctionBegin;
28016bf464f9SBarry Smith   if (!*snes) PetscFunctionReturn(0);
28026bf464f9SBarry Smith   PetscValidHeaderSpecific((*snes),SNES_CLASSID,1);
28036bf464f9SBarry Smith   if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);}
2804d4bb536fSBarry Smith 
28056bf464f9SBarry Smith   ierr = SNESReset((*snes));CHKERRQ(ierr);
2806*efd4aadfSBarry Smith   ierr = SNESDestroy(&(*snes)->npc);CHKERRQ(ierr);
28076b8b9a38SLisandro Dalcin 
2808e04113cfSBarry Smith   /* if memory was published with SAWs then destroy it */
2809e04113cfSBarry Smith   ierr = PetscObjectSAWsViewOff((PetscObject)*snes);CHKERRQ(ierr);
28106bf464f9SBarry Smith   if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);}
28116d4c513bSLisandro Dalcin 
28126bf464f9SBarry Smith   ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr);
28136bf464f9SBarry Smith   ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr);
2814f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr);
28156b8b9a38SLisandro Dalcin 
28166bf464f9SBarry Smith   ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr);
28176bf464f9SBarry Smith   if ((*snes)->ops->convergeddestroy) {
28186bf464f9SBarry Smith     ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr);
28196b8b9a38SLisandro Dalcin   }
28206bf464f9SBarry Smith   if ((*snes)->conv_malloc) {
28216bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr);
28226bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr);
282358c9b817SLisandro Dalcin   }
28246bf464f9SBarry Smith   ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr);
2825a79aaaedSSatish Balay   ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr);
28263a40ed3dSBarry Smith   PetscFunctionReturn(0);
28279b94acceSBarry Smith }
28289b94acceSBarry Smith 
28299b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */
28309b94acceSBarry Smith 
2831a8054027SBarry Smith /*@
2832a8054027SBarry Smith    SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.
2833a8054027SBarry Smith 
28343f9fe445SBarry Smith    Logically Collective on SNES
2835a8054027SBarry Smith 
2836a8054027SBarry Smith    Input Parameters:
2837a8054027SBarry Smith +  snes - the SNES context
2838a8054027SBarry 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
28393b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2840a8054027SBarry Smith 
2841a8054027SBarry Smith    Options Database Keys:
2842a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2843a8054027SBarry Smith 
2844a8054027SBarry Smith    Notes:
2845a8054027SBarry Smith    The default is 1
2846a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2847a8054027SBarry Smith    If  -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use
2848a8054027SBarry Smith 
2849a8054027SBarry Smith    Level: intermediate
2850a8054027SBarry Smith 
2851a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2852a8054027SBarry Smith 
2853e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2854a8054027SBarry Smith 
2855a8054027SBarry Smith @*/
28567087cfbeSBarry Smith PetscErrorCode  SNESSetLagPreconditioner(SNES snes,PetscInt lag)
2857a8054027SBarry Smith {
2858a8054027SBarry Smith   PetscFunctionBegin;
28590700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2860e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2861e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2862c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2863a8054027SBarry Smith   snes->lagpreconditioner = lag;
2864a8054027SBarry Smith   PetscFunctionReturn(0);
2865a8054027SBarry Smith }
2866a8054027SBarry Smith 
2867efd51863SBarry Smith /*@
2868efd51863SBarry Smith    SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does
2869efd51863SBarry Smith 
2870efd51863SBarry Smith    Logically Collective on SNES
2871efd51863SBarry Smith 
2872efd51863SBarry Smith    Input Parameters:
2873efd51863SBarry Smith +  snes - the SNES context
2874efd51863SBarry Smith -  steps - the number of refinements to do, defaults to 0
2875efd51863SBarry Smith 
2876efd51863SBarry Smith    Options Database Keys:
2877efd51863SBarry Smith .    -snes_grid_sequence <steps>
2878efd51863SBarry Smith 
2879efd51863SBarry Smith    Level: intermediate
2880efd51863SBarry Smith 
2881c0df2a02SJed Brown    Notes:
2882c0df2a02SJed Brown    Use SNESGetSolution() to extract the fine grid solution after grid sequencing.
2883c0df2a02SJed Brown 
2884efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2885efd51863SBarry Smith 
2886fa19ca70SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetGridSequence()
2887efd51863SBarry Smith 
2888efd51863SBarry Smith @*/
2889efd51863SBarry Smith PetscErrorCode  SNESSetGridSequence(SNES snes,PetscInt steps)
2890efd51863SBarry Smith {
2891efd51863SBarry Smith   PetscFunctionBegin;
2892efd51863SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2893efd51863SBarry Smith   PetscValidLogicalCollectiveInt(snes,steps,2);
2894efd51863SBarry Smith   snes->gridsequence = steps;
2895efd51863SBarry Smith   PetscFunctionReturn(0);
2896efd51863SBarry Smith }
2897efd51863SBarry Smith 
2898fa19ca70SBarry Smith /*@
2899fa19ca70SBarry Smith    SNESGetGridSequence - gets the number of steps of grid sequencing that SNES does
2900fa19ca70SBarry Smith 
2901fa19ca70SBarry Smith    Logically Collective on SNES
2902fa19ca70SBarry Smith 
2903fa19ca70SBarry Smith    Input Parameter:
2904fa19ca70SBarry Smith .  snes - the SNES context
2905fa19ca70SBarry Smith 
2906fa19ca70SBarry Smith    Output Parameter:
2907fa19ca70SBarry Smith .  steps - the number of refinements to do, defaults to 0
2908fa19ca70SBarry Smith 
2909fa19ca70SBarry Smith    Options Database Keys:
2910fa19ca70SBarry Smith .    -snes_grid_sequence <steps>
2911fa19ca70SBarry Smith 
2912fa19ca70SBarry Smith    Level: intermediate
2913fa19ca70SBarry Smith 
2914fa19ca70SBarry Smith    Notes:
2915fa19ca70SBarry Smith    Use SNESGetSolution() to extract the fine grid solution after grid sequencing.
2916fa19ca70SBarry Smith 
2917fa19ca70SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2918fa19ca70SBarry Smith 
2919fa19ca70SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESSetGridSequence()
2920fa19ca70SBarry Smith 
2921fa19ca70SBarry Smith @*/
2922fa19ca70SBarry Smith PetscErrorCode  SNESGetGridSequence(SNES snes,PetscInt *steps)
2923fa19ca70SBarry Smith {
2924fa19ca70SBarry Smith   PetscFunctionBegin;
2925fa19ca70SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2926fa19ca70SBarry Smith   *steps = snes->gridsequence;
2927fa19ca70SBarry Smith   PetscFunctionReturn(0);
2928fa19ca70SBarry Smith }
2929fa19ca70SBarry Smith 
2930a8054027SBarry Smith /*@
2931a8054027SBarry Smith    SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt
2932a8054027SBarry Smith 
29333f9fe445SBarry Smith    Not Collective
2934a8054027SBarry Smith 
2935a8054027SBarry Smith    Input Parameter:
2936a8054027SBarry Smith .  snes - the SNES context
2937a8054027SBarry Smith 
2938a8054027SBarry Smith    Output Parameter:
2939a8054027SBarry 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
29403b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2941a8054027SBarry Smith 
2942a8054027SBarry Smith    Options Database Keys:
2943a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2944a8054027SBarry Smith 
2945a8054027SBarry Smith    Notes:
2946a8054027SBarry Smith    The default is 1
2947a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2948a8054027SBarry Smith 
2949a8054027SBarry Smith    Level: intermediate
2950a8054027SBarry Smith 
2951a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2952a8054027SBarry Smith 
2953a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner()
2954a8054027SBarry Smith 
2955a8054027SBarry Smith @*/
29567087cfbeSBarry Smith PetscErrorCode  SNESGetLagPreconditioner(SNES snes,PetscInt *lag)
2957a8054027SBarry Smith {
2958a8054027SBarry Smith   PetscFunctionBegin;
29590700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2960a8054027SBarry Smith   *lag = snes->lagpreconditioner;
2961a8054027SBarry Smith   PetscFunctionReturn(0);
2962a8054027SBarry Smith }
2963a8054027SBarry Smith 
2964e35cf81dSBarry Smith /*@
2965e35cf81dSBarry Smith    SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how
2966e35cf81dSBarry Smith      often the preconditioner is rebuilt.
2967e35cf81dSBarry Smith 
29683f9fe445SBarry Smith    Logically Collective on SNES
2969e35cf81dSBarry Smith 
2970e35cf81dSBarry Smith    Input Parameters:
2971e35cf81dSBarry Smith +  snes - the SNES context
2972e35cf81dSBarry 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
2973fe3ffe1eSBarry Smith          the Jacobian is built etc. -2 means rebuild at next chance but then never again
2974e35cf81dSBarry Smith 
2975e35cf81dSBarry Smith    Options Database Keys:
2976e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2977e35cf81dSBarry Smith 
2978e35cf81dSBarry Smith    Notes:
2979e35cf81dSBarry Smith    The default is 1
2980e35cf81dSBarry Smith    The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2981fe3ffe1eSBarry 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
2982fe3ffe1eSBarry Smith    at the next Newton step but never again (unless it is reset to another value)
2983e35cf81dSBarry Smith 
2984e35cf81dSBarry Smith    Level: intermediate
2985e35cf81dSBarry Smith 
2986e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2987e35cf81dSBarry Smith 
2988e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian()
2989e35cf81dSBarry Smith 
2990e35cf81dSBarry Smith @*/
29917087cfbeSBarry Smith PetscErrorCode  SNESSetLagJacobian(SNES snes,PetscInt lag)
2992e35cf81dSBarry Smith {
2993e35cf81dSBarry Smith   PetscFunctionBegin;
29940700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2995e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2996e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2997c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2998e35cf81dSBarry Smith   snes->lagjacobian = lag;
2999e35cf81dSBarry Smith   PetscFunctionReturn(0);
3000e35cf81dSBarry Smith }
3001e35cf81dSBarry Smith 
3002e35cf81dSBarry Smith /*@
3003e35cf81dSBarry Smith    SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt
3004e35cf81dSBarry Smith 
30053f9fe445SBarry Smith    Not Collective
3006e35cf81dSBarry Smith 
3007e35cf81dSBarry Smith    Input Parameter:
3008e35cf81dSBarry Smith .  snes - the SNES context
3009e35cf81dSBarry Smith 
3010e35cf81dSBarry Smith    Output Parameter:
3011e35cf81dSBarry 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
3012e35cf81dSBarry Smith          the Jacobian is built etc.
3013e35cf81dSBarry Smith 
3014e35cf81dSBarry Smith    Options Database Keys:
3015e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
3016e35cf81dSBarry Smith 
3017e35cf81dSBarry Smith    Notes:
3018e35cf81dSBarry Smith    The default is 1
3019e35cf81dSBarry Smith    The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
3020e35cf81dSBarry Smith 
3021e35cf81dSBarry Smith    Level: intermediate
3022e35cf81dSBarry Smith 
3023e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
3024e35cf81dSBarry Smith 
3025e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner()
3026e35cf81dSBarry Smith 
3027e35cf81dSBarry Smith @*/
30287087cfbeSBarry Smith PetscErrorCode  SNESGetLagJacobian(SNES snes,PetscInt *lag)
3029e35cf81dSBarry Smith {
3030e35cf81dSBarry Smith   PetscFunctionBegin;
30310700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3032e35cf81dSBarry Smith   *lag = snes->lagjacobian;
3033e35cf81dSBarry Smith   PetscFunctionReturn(0);
3034e35cf81dSBarry Smith }
3035e35cf81dSBarry Smith 
303637ec4e1aSPeter Brune /*@
303737ec4e1aSPeter Brune    SNESSetLagJacobianPersists - Set whether or not the Jacobian lagging persists through multiple solves
303837ec4e1aSPeter Brune 
303937ec4e1aSPeter Brune    Logically collective on SNES
304037ec4e1aSPeter Brune 
304137ec4e1aSPeter Brune    Input Parameter:
304237ec4e1aSPeter Brune +  snes - the SNES context
30439d7e2deaSPeter Brune -   flg - jacobian lagging persists if true
304437ec4e1aSPeter Brune 
304537ec4e1aSPeter Brune    Options Database Keys:
304637ec4e1aSPeter Brune .    -snes_lag_jacobian_persists <flg>
304737ec4e1aSPeter Brune 
304837ec4e1aSPeter Brune    Notes: This is useful both for nonlinear preconditioning, where it's appropriate to have the Jacobian be stale by
304937ec4e1aSPeter Brune    several solves, and for implicit time-stepping, where Jacobian lagging in the inner nonlinear solve over several
305037ec4e1aSPeter Brune    timesteps may present huge efficiency gains.
305137ec4e1aSPeter Brune 
305237ec4e1aSPeter Brune    Level: developer
305337ec4e1aSPeter Brune 
3054be95d8f1SBarry Smith .keywords: SNES, nonlinear, lag
305537ec4e1aSPeter Brune 
3056be95d8f1SBarry Smith .seealso: SNESSetLagPreconditionerPersists(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetNPC()
305737ec4e1aSPeter Brune 
305837ec4e1aSPeter Brune @*/
305937ec4e1aSPeter Brune PetscErrorCode  SNESSetLagJacobianPersists(SNES snes,PetscBool flg)
306037ec4e1aSPeter Brune {
306137ec4e1aSPeter Brune   PetscFunctionBegin;
306237ec4e1aSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
306337ec4e1aSPeter Brune   PetscValidLogicalCollectiveBool(snes,flg,2);
306437ec4e1aSPeter Brune   snes->lagjac_persist = flg;
306537ec4e1aSPeter Brune   PetscFunctionReturn(0);
306637ec4e1aSPeter Brune }
306737ec4e1aSPeter Brune 
306837ec4e1aSPeter Brune /*@
306937ec4e1aSPeter Brune    SNESSetLagPreconditionerPersists - Set whether or not the preconditioner lagging persists through multiple solves
307037ec4e1aSPeter Brune 
307137ec4e1aSPeter Brune    Logically Collective on SNES
307237ec4e1aSPeter Brune 
307337ec4e1aSPeter Brune    Input Parameter:
307437ec4e1aSPeter Brune +  snes - the SNES context
30759d7e2deaSPeter Brune -   flg - preconditioner lagging persists if true
307637ec4e1aSPeter Brune 
307737ec4e1aSPeter Brune    Options Database Keys:
307837ec4e1aSPeter Brune .    -snes_lag_jacobian_persists <flg>
307937ec4e1aSPeter Brune 
308037ec4e1aSPeter Brune    Notes: This is useful both for nonlinear preconditioning, where it's appropriate to have the preconditioner be stale
308137ec4e1aSPeter Brune    by several solves, and for implicit time-stepping, where preconditioner lagging in the inner nonlinear solve over
308237ec4e1aSPeter Brune    several timesteps may present huge efficiency gains.
308337ec4e1aSPeter Brune 
308437ec4e1aSPeter Brune    Level: developer
308537ec4e1aSPeter Brune 
3086be95d8f1SBarry Smith .keywords: SNES, nonlinear, lag
308737ec4e1aSPeter Brune 
3088be95d8f1SBarry Smith .seealso: SNESSetLagJacobianPersists(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetNPC()
308937ec4e1aSPeter Brune 
309037ec4e1aSPeter Brune @*/
309137ec4e1aSPeter Brune PetscErrorCode  SNESSetLagPreconditionerPersists(SNES snes,PetscBool flg)
309237ec4e1aSPeter Brune {
309337ec4e1aSPeter Brune   PetscFunctionBegin;
309437ec4e1aSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
309537ec4e1aSPeter Brune   PetscValidLogicalCollectiveBool(snes,flg,2);
309637ec4e1aSPeter Brune   snes->lagpre_persist = flg;
309737ec4e1aSPeter Brune   PetscFunctionReturn(0);
309837ec4e1aSPeter Brune }
309937ec4e1aSPeter Brune 
31009b94acceSBarry Smith /*@
3101d7a720efSLois Curfman McInnes    SNESSetTolerances - Sets various parameters used in convergence tests.
31029b94acceSBarry Smith 
31033f9fe445SBarry Smith    Logically Collective on SNES
3104c7afd0dbSLois Curfman McInnes 
31059b94acceSBarry Smith    Input Parameters:
3106c7afd0dbSLois Curfman McInnes +  snes - the SNES context
310770441072SBarry Smith .  abstol - absolute convergence tolerance
310833174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
31095358d0d4SBarry Smith .  stol -  convergence tolerance in terms of the norm of the change in the solution between steps,  || delta x || < stol*|| x ||
311033174efeSLois Curfman McInnes .  maxit - maximum number of iterations
3111c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
3112fee21e36SBarry Smith 
311333174efeSLois Curfman McInnes    Options Database Keys:
311470441072SBarry Smith +    -snes_atol <abstol> - Sets abstol
3115c7afd0dbSLois Curfman McInnes .    -snes_rtol <rtol> - Sets rtol
3116c7afd0dbSLois Curfman McInnes .    -snes_stol <stol> - Sets stol
3117c7afd0dbSLois Curfman McInnes .    -snes_max_it <maxit> - Sets maxit
3118c7afd0dbSLois Curfman McInnes -    -snes_max_funcs <maxf> - Sets maxf
31199b94acceSBarry Smith 
3120d7a720efSLois Curfman McInnes    Notes:
31219b94acceSBarry Smith    The default maximum number of iterations is 50.
31229b94acceSBarry Smith    The default maximum number of function evaluations is 1000.
31239b94acceSBarry Smith 
312436851e7fSLois Curfman McInnes    Level: intermediate
312536851e7fSLois Curfman McInnes 
312633174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances
31279b94acceSBarry Smith 
3128e4d06f11SPatrick Farrell .seealso: SNESSetTrustRegionTolerance(), SNESSetDivergenceTolerance()
31299b94acceSBarry Smith @*/
31307087cfbeSBarry Smith PetscErrorCode  SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
31319b94acceSBarry Smith {
31323a40ed3dSBarry Smith   PetscFunctionBegin;
31330700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3134c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,abstol,2);
3135c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol,3);
3136c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,stol,4);
3137c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxit,5);
3138c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxf,6);
3139c5eb9154SBarry Smith 
3140ab54825eSJed Brown   if (abstol != PETSC_DEFAULT) {
314157622a8eSBarry Smith     if (abstol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %g must be non-negative",(double)abstol);
3142ab54825eSJed Brown     snes->abstol = abstol;
3143ab54825eSJed Brown   }
3144ab54825eSJed Brown   if (rtol != PETSC_DEFAULT) {
314557622a8eSBarry 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);
3146ab54825eSJed Brown     snes->rtol = rtol;
3147ab54825eSJed Brown   }
3148ab54825eSJed Brown   if (stol != PETSC_DEFAULT) {
314957622a8eSBarry Smith     if (stol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %g must be non-negative",(double)stol);
3150c60f73f4SPeter Brune     snes->stol = stol;
3151ab54825eSJed Brown   }
3152ab54825eSJed Brown   if (maxit != PETSC_DEFAULT) {
3153ce94432eSBarry Smith     if (maxit < 0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit);
3154ab54825eSJed Brown     snes->max_its = maxit;
3155ab54825eSJed Brown   }
3156ab54825eSJed Brown   if (maxf != PETSC_DEFAULT) {
3157ce94432eSBarry Smith     if (maxf < 0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf);
3158ab54825eSJed Brown     snes->max_funcs = maxf;
3159ab54825eSJed Brown   }
316088976e71SPeter Brune   snes->tolerancesset = PETSC_TRUE;
31613a40ed3dSBarry Smith   PetscFunctionReturn(0);
31629b94acceSBarry Smith }
31639b94acceSBarry Smith 
3164e4d06f11SPatrick Farrell /*@
3165e4d06f11SPatrick Farrell    SNESSetDivergenceTolerance - Sets the divergence tolerance used for the SNES divergence test.
3166e4d06f11SPatrick Farrell 
3167e4d06f11SPatrick Farrell    Logically Collective on SNES
3168e4d06f11SPatrick Farrell 
3169e4d06f11SPatrick Farrell    Input Parameters:
3170e4d06f11SPatrick Farrell +  snes - the SNES context
3171e4d06f11SPatrick Farrell -  divtol - the divergence tolerance. Use -1 to deactivate the test.
3172e4d06f11SPatrick Farrell 
3173e4d06f11SPatrick Farrell    Options Database Keys:
3174e4d06f11SPatrick Farrell +    -snes_divergence_tolerance <divtol> - Sets divtol
3175e4d06f11SPatrick Farrell 
3176e4d06f11SPatrick Farrell    Notes:
3177e4d06f11SPatrick Farrell    The default divergence tolerance is 1e4.
3178e4d06f11SPatrick Farrell 
3179e4d06f11SPatrick Farrell    Level: intermediate
3180e4d06f11SPatrick Farrell 
3181e4d06f11SPatrick Farrell .keywords: SNES, nonlinear, set, divergence, tolerance
3182e4d06f11SPatrick Farrell 
3183e4d06f11SPatrick Farrell .seealso: SNESSetTolerances(), SNESGetDivergenceTolerance
3184e4d06f11SPatrick Farrell @*/
3185e4d06f11SPatrick Farrell PetscErrorCode  SNESSetDivergenceTolerance(SNES snes,PetscReal divtol)
3186e4d06f11SPatrick Farrell {
3187e4d06f11SPatrick Farrell   PetscFunctionBegin;
3188e4d06f11SPatrick Farrell   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3189e4d06f11SPatrick Farrell   PetscValidLogicalCollectiveReal(snes,divtol,2);
3190e4d06f11SPatrick Farrell 
3191e4d06f11SPatrick Farrell   if (divtol != PETSC_DEFAULT) {
3192e4d06f11SPatrick Farrell     snes->divtol = divtol;
3193e4d06f11SPatrick Farrell   }
3194e4d06f11SPatrick Farrell   else {
3195e4d06f11SPatrick Farrell     snes->divtol = 1.0e4;
3196e4d06f11SPatrick Farrell   }
3197e4d06f11SPatrick Farrell   PetscFunctionReturn(0);
3198e4d06f11SPatrick Farrell }
3199e4d06f11SPatrick Farrell 
32009b94acceSBarry Smith /*@
320133174efeSLois Curfman McInnes    SNESGetTolerances - Gets various parameters used in convergence tests.
320233174efeSLois Curfman McInnes 
3203c7afd0dbSLois Curfman McInnes    Not Collective
3204c7afd0dbSLois Curfman McInnes 
320533174efeSLois Curfman McInnes    Input Parameters:
3206c7afd0dbSLois Curfman McInnes +  snes - the SNES context
320785385478SLisandro Dalcin .  atol - absolute convergence tolerance
320833174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
320933174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
321033174efeSLois Curfman McInnes            of the change in the solution between steps
321133174efeSLois Curfman McInnes .  maxit - maximum number of iterations
3212c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
3213fee21e36SBarry Smith 
321433174efeSLois Curfman McInnes    Notes:
32150298fd71SBarry Smith    The user can specify NULL for any parameter that is not needed.
321633174efeSLois Curfman McInnes 
321736851e7fSLois Curfman McInnes    Level: intermediate
321836851e7fSLois Curfman McInnes 
321933174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances
322033174efeSLois Curfman McInnes 
322133174efeSLois Curfman McInnes .seealso: SNESSetTolerances()
322233174efeSLois Curfman McInnes @*/
32237087cfbeSBarry Smith PetscErrorCode  SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
322433174efeSLois Curfman McInnes {
32253a40ed3dSBarry Smith   PetscFunctionBegin;
32260700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
322785385478SLisandro Dalcin   if (atol)  *atol  = snes->abstol;
322833174efeSLois Curfman McInnes   if (rtol)  *rtol  = snes->rtol;
3229c60f73f4SPeter Brune   if (stol)  *stol  = snes->stol;
323033174efeSLois Curfman McInnes   if (maxit) *maxit = snes->max_its;
323133174efeSLois Curfman McInnes   if (maxf)  *maxf  = snes->max_funcs;
32323a40ed3dSBarry Smith   PetscFunctionReturn(0);
323333174efeSLois Curfman McInnes }
323433174efeSLois Curfman McInnes 
3235e4d06f11SPatrick Farrell /*@
3236e4d06f11SPatrick Farrell    SNESGetDivergenceTolerance - Gets divergence tolerance used in divergence test.
3237e4d06f11SPatrick Farrell 
3238e4d06f11SPatrick Farrell    Not Collective
3239e4d06f11SPatrick Farrell 
3240e4d06f11SPatrick Farrell    Input Parameters:
3241e4d06f11SPatrick Farrell +  snes - the SNES context
3242e4d06f11SPatrick Farrell -  divtol - divergence tolerance
3243e4d06f11SPatrick Farrell 
3244e4d06f11SPatrick Farrell    Level: intermediate
3245e4d06f11SPatrick Farrell 
3246e4d06f11SPatrick Farrell .keywords: SNES, nonlinear, get, divergence, tolerance
3247e4d06f11SPatrick Farrell 
3248e4d06f11SPatrick Farrell .seealso: SNESSetDivergenceTolerance()
3249e4d06f11SPatrick Farrell @*/
3250e4d06f11SPatrick Farrell PetscErrorCode  SNESGetDivergenceTolerance(SNES snes,PetscReal *divtol)
3251e4d06f11SPatrick Farrell {
3252e4d06f11SPatrick Farrell   PetscFunctionBegin;
3253e4d06f11SPatrick Farrell   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3254e4d06f11SPatrick Farrell   if (divtol) *divtol = snes->divtol;
3255e4d06f11SPatrick Farrell   PetscFunctionReturn(0);
3256e4d06f11SPatrick Farrell }
3257e4d06f11SPatrick Farrell 
325833174efeSLois Curfman McInnes /*@
32599b94acceSBarry Smith    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
32609b94acceSBarry Smith 
32613f9fe445SBarry Smith    Logically Collective on SNES
3262fee21e36SBarry Smith 
3263c7afd0dbSLois Curfman McInnes    Input Parameters:
3264c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3265c7afd0dbSLois Curfman McInnes -  tol - tolerance
3266c7afd0dbSLois Curfman McInnes 
32679b94acceSBarry Smith    Options Database Key:
3268c7afd0dbSLois Curfman McInnes .  -snes_trtol <tol> - Sets tol
32699b94acceSBarry Smith 
327036851e7fSLois Curfman McInnes    Level: intermediate
327136851e7fSLois Curfman McInnes 
32729b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance
32739b94acceSBarry Smith 
32742492ecdbSBarry Smith .seealso: SNESSetTolerances()
32759b94acceSBarry Smith @*/
32767087cfbeSBarry Smith PetscErrorCode  SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
32779b94acceSBarry Smith {
32783a40ed3dSBarry Smith   PetscFunctionBegin;
32790700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3280c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,tol,2);
32819b94acceSBarry Smith   snes->deltatol = tol;
32823a40ed3dSBarry Smith   PetscFunctionReturn(0);
32839b94acceSBarry Smith }
32849b94acceSBarry Smith 
3285df9fa365SBarry Smith /*
3286df9fa365SBarry Smith    Duplicate the lg monitors for SNES from KSP; for some reason with
3287df9fa365SBarry Smith    dynamic libraries things don't work under Sun4 if we just use
3288df9fa365SBarry Smith    macros instead of functions
3289df9fa365SBarry Smith */
3290d96771aaSLisandro Dalcin PetscErrorCode  SNESMonitorLGResidualNorm(SNES snes,PetscInt it,PetscReal norm,void *ctx)
3291ce1608b8SBarry Smith {
3292dfbe8321SBarry Smith   PetscErrorCode ierr;
3293ce1608b8SBarry Smith 
3294ce1608b8SBarry Smith   PetscFunctionBegin;
32950700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3296d96771aaSLisandro Dalcin   ierr = KSPMonitorLGResidualNorm((KSP)snes,it,norm,ctx);CHKERRQ(ierr);
3297ce1608b8SBarry Smith   PetscFunctionReturn(0);
3298ce1608b8SBarry Smith }
3299ce1608b8SBarry Smith 
3300d96771aaSLisandro Dalcin PetscErrorCode  SNESMonitorLGCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *lgctx)
3301df9fa365SBarry Smith {
3302dfbe8321SBarry Smith   PetscErrorCode ierr;
3303df9fa365SBarry Smith 
3304df9fa365SBarry Smith   PetscFunctionBegin;
3305d96771aaSLisandro Dalcin   ierr = KSPMonitorLGResidualNormCreate(comm,host,label,x,y,m,n,lgctx);CHKERRQ(ierr);
3306df9fa365SBarry Smith   PetscFunctionReturn(0);
3307df9fa365SBarry Smith }
3308df9fa365SBarry Smith 
33096ba87a44SLisandro Dalcin PETSC_INTERN PetscErrorCode  SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
33106ba87a44SLisandro Dalcin 
33117087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx)
3312b271bb04SBarry Smith {
3313b271bb04SBarry Smith   PetscDrawLG      lg;
3314b271bb04SBarry Smith   PetscErrorCode   ierr;
3315b271bb04SBarry Smith   PetscReal        x,y,per;
3316b271bb04SBarry Smith   PetscViewer      v = (PetscViewer)monctx;
3317b271bb04SBarry Smith   static PetscReal prev; /* should be in the context */
3318b271bb04SBarry Smith   PetscDraw        draw;
3319b271bb04SBarry Smith 
3320459f5d12SBarry Smith   PetscFunctionBegin;
33214d4332d5SBarry Smith   PetscValidHeaderSpecific(v,PETSC_VIEWER_CLASSID,4);
3322b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr);
3323b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
3324b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
3325b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr);
3326b271bb04SBarry Smith   x    = (PetscReal)n;
332777b4d14cSPeter Brune   if (rnorm > 0.0) y = PetscLog10Real(rnorm);
332894c9c6d3SKarl Rupp   else y = -15.0;
3329b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
33306934998bSLisandro Dalcin   if (n < 20 || !(n % 5) || snes->reason) {
3331b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
33326934998bSLisandro Dalcin     ierr = PetscDrawLGSave(lg);CHKERRQ(ierr);
3333b271bb04SBarry Smith   }
3334b271bb04SBarry Smith 
3335b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr);
3336b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
3337b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
3338b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr);
3339b271bb04SBarry Smith   ierr =  SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr);
3340b271bb04SBarry Smith   x    = (PetscReal)n;
3341b271bb04SBarry Smith   y    = 100.0*per;
3342b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
33436934998bSLisandro Dalcin   if (n < 20 || !(n % 5) || snes->reason) {
3344b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
33456934998bSLisandro Dalcin     ierr = PetscDrawLGSave(lg);CHKERRQ(ierr);
3346b271bb04SBarry Smith   }
3347b271bb04SBarry Smith 
3348b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr);
3349b271bb04SBarry Smith   if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
3350b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
3351b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr);
3352b271bb04SBarry Smith   x    = (PetscReal)n;
3353b271bb04SBarry Smith   y    = (prev - rnorm)/prev;
3354b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
33556934998bSLisandro Dalcin   if (n < 20 || !(n % 5) || snes->reason) {
3356b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
33576934998bSLisandro Dalcin     ierr = PetscDrawLGSave(lg);CHKERRQ(ierr);
3358b271bb04SBarry Smith   }
3359b271bb04SBarry Smith 
3360b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr);
3361b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
3362b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
3363b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr);
3364b271bb04SBarry Smith   x    = (PetscReal)n;
3365b271bb04SBarry Smith   y    = (prev - rnorm)/(prev*per);
3366b271bb04SBarry Smith   if (n > 2) { /*skip initial crazy value */
3367b271bb04SBarry Smith     ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
3368b271bb04SBarry Smith   }
33696934998bSLisandro Dalcin   if (n < 20 || !(n % 5) || snes->reason) {
3370b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
33716934998bSLisandro Dalcin     ierr = PetscDrawLGSave(lg);CHKERRQ(ierr);
3372b271bb04SBarry Smith   }
3373b271bb04SBarry Smith   prev = rnorm;
3374b271bb04SBarry Smith   PetscFunctionReturn(0);
3375b271bb04SBarry Smith }
3376b271bb04SBarry Smith 
3377228d79bcSJed Brown /*@
3378228d79bcSJed Brown    SNESMonitor - runs the user provided monitor routines, if they exist
3379228d79bcSJed Brown 
3380228d79bcSJed Brown    Collective on SNES
3381228d79bcSJed Brown 
3382228d79bcSJed Brown    Input Parameters:
3383228d79bcSJed Brown +  snes - nonlinear solver context obtained from SNESCreate()
3384228d79bcSJed Brown .  iter - iteration number
3385228d79bcSJed Brown -  rnorm - relative norm of the residual
3386228d79bcSJed Brown 
3387228d79bcSJed Brown    Notes:
3388228d79bcSJed Brown    This routine is called by the SNES implementations.
3389228d79bcSJed Brown    It does not typically need to be called by the user.
3390228d79bcSJed Brown 
3391228d79bcSJed Brown    Level: developer
3392228d79bcSJed Brown 
3393228d79bcSJed Brown .seealso: SNESMonitorSet()
3394228d79bcSJed Brown @*/
33957a03ce2fSLisandro Dalcin PetscErrorCode  SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm)
33967a03ce2fSLisandro Dalcin {
33977a03ce2fSLisandro Dalcin   PetscErrorCode ierr;
33987a03ce2fSLisandro Dalcin   PetscInt       i,n = snes->numbermonitors;
33997a03ce2fSLisandro Dalcin 
34007a03ce2fSLisandro Dalcin   PetscFunctionBegin;
34015edff71fSBarry Smith   ierr = VecLockPush(snes->vec_sol);CHKERRQ(ierr);
34027a03ce2fSLisandro Dalcin   for (i=0; i<n; i++) {
34037a03ce2fSLisandro Dalcin     ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr);
34047a03ce2fSLisandro Dalcin   }
34055edff71fSBarry Smith   ierr = VecLockPop(snes->vec_sol);CHKERRQ(ierr);
34067a03ce2fSLisandro Dalcin   PetscFunctionReturn(0);
34077a03ce2fSLisandro Dalcin }
34087a03ce2fSLisandro Dalcin 
34099b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */
34109b94acceSBarry Smith 
3411bf388a1fSBarry Smith /*MC
3412bf388a1fSBarry Smith     SNESMonitorFunction - functional form passed to SNESMonitorSet() to monitor convergence of nonlinear solver
3413bf388a1fSBarry Smith 
3414bf388a1fSBarry Smith      Synopsis:
3415aaa7dc30SBarry Smith      #include <petscsnes.h>
3416bf388a1fSBarry Smith $    PetscErrorCode SNESMonitorFunction(SNES snes,PetscInt its, PetscReal norm,void *mctx)
3417bf388a1fSBarry Smith 
3418bf388a1fSBarry Smith +    snes - the SNES context
3419bf388a1fSBarry Smith .    its - iteration number
3420bf388a1fSBarry Smith .    norm - 2-norm function value (may be estimated)
3421bf388a1fSBarry Smith -    mctx - [optional] monitoring context
3422bf388a1fSBarry Smith 
3423878cb397SSatish Balay    Level: advanced
3424878cb397SSatish Balay 
3425bf388a1fSBarry Smith .seealso:   SNESMonitorSet(), SNESMonitorGet()
3426bf388a1fSBarry Smith M*/
3427bf388a1fSBarry Smith 
34289b94acceSBarry Smith /*@C
3429a6570f20SBarry Smith    SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
34309b94acceSBarry Smith    iteration of the nonlinear solver to display the iteration's
34319b94acceSBarry Smith    progress.
34329b94acceSBarry Smith 
34333f9fe445SBarry Smith    Logically Collective on SNES
3434fee21e36SBarry Smith 
3435c7afd0dbSLois Curfman McInnes    Input Parameters:
3436c7afd0dbSLois Curfman McInnes +  snes - the SNES context
34376e4dcb14SBarry Smith .  f - the monitor function, see SNESMonitorFunction for the calling sequence
3438b8a78c4aSBarry Smith .  mctx - [optional] user-defined context for private data for the
34390298fd71SBarry Smith           monitor routine (use NULL if no context is desired)
3440b3006f0bSLois Curfman McInnes -  monitordestroy - [optional] routine that frees monitor context
34410298fd71SBarry Smith           (may be NULL)
34429b94acceSBarry Smith 
34439665c990SLois Curfman McInnes    Options Database Keys:
3444a6570f20SBarry Smith +    -snes_monitor        - sets SNESMonitorDefault()
34454619e776SBarry Smith .    -snes_monitor_lg_residualnorm    - sets line graph monitor,
3446a6570f20SBarry Smith                             uses SNESMonitorLGCreate()
3447cca6129bSJed Brown -    -snes_monitor_cancel - cancels all monitors that have
3448c7afd0dbSLois Curfman McInnes                             been hardwired into a code by
3449a6570f20SBarry Smith                             calls to SNESMonitorSet(), but
3450c7afd0dbSLois Curfman McInnes                             does not cancel those set via
3451c7afd0dbSLois Curfman McInnes                             the options database.
34529665c990SLois Curfman McInnes 
3453639f9d9dSBarry Smith    Notes:
34546bc08f3fSLois Curfman McInnes    Several different monitoring routines may be set by calling
3455a6570f20SBarry Smith    SNESMonitorSet() multiple times; all will be called in the
34566bc08f3fSLois Curfman McInnes    order in which they were set.
3457639f9d9dSBarry Smith 
3458025f1a04SBarry Smith    Fortran notes: Only a single monitor function can be set for each SNES object
3459025f1a04SBarry Smith 
346036851e7fSLois Curfman McInnes    Level: intermediate
346136851e7fSLois Curfman McInnes 
34629b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor
34639b94acceSBarry Smith 
3464bf388a1fSBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel(), SNESMonitorFunction
34659b94acceSBarry Smith @*/
34666e4dcb14SBarry Smith PetscErrorCode  SNESMonitorSet(SNES snes,PetscErrorCode (*f)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
34679b94acceSBarry Smith {
3468b90d0a6eSBarry Smith   PetscInt       i;
3469649052a6SBarry Smith   PetscErrorCode ierr;
347078064530SBarry Smith   PetscBool      identical;
3471b90d0a6eSBarry Smith 
34723a40ed3dSBarry Smith   PetscFunctionBegin;
34730700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3474b90d0a6eSBarry Smith   for (i=0; i<snes->numbermonitors;i++) {
347578064530SBarry Smith     ierr = PetscMonitorCompare((PetscErrorCode (*)(void))f,mctx,monitordestroy,(PetscErrorCode (*)(void))snes->monitor[i],snes->monitorcontext[i],snes->monitordestroy[i],&identical);CHKERRQ(ierr);
347678064530SBarry Smith     if (identical) PetscFunctionReturn(0);
3477649052a6SBarry Smith   }
347878064530SBarry Smith   if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
34796e4dcb14SBarry Smith   snes->monitor[snes->numbermonitors]          = f;
3480b8a78c4aSBarry Smith   snes->monitordestroy[snes->numbermonitors]   = monitordestroy;
3481639f9d9dSBarry Smith   snes->monitorcontext[snes->numbermonitors++] = (void*)mctx;
34823a40ed3dSBarry Smith   PetscFunctionReturn(0);
34839b94acceSBarry Smith }
34849b94acceSBarry Smith 
3485a278d85bSSatish Balay /*@
3486a6570f20SBarry Smith    SNESMonitorCancel - Clears all the monitor functions for a SNES object.
34875cd90555SBarry Smith 
34883f9fe445SBarry Smith    Logically Collective on SNES
3489c7afd0dbSLois Curfman McInnes 
34905cd90555SBarry Smith    Input Parameters:
34915cd90555SBarry Smith .  snes - the SNES context
34925cd90555SBarry Smith 
34931a480d89SAdministrator    Options Database Key:
3494a6570f20SBarry Smith .  -snes_monitor_cancel - cancels all monitors that have been hardwired
3495a6570f20SBarry Smith     into a code by calls to SNESMonitorSet(), but does not cancel those
3496c7afd0dbSLois Curfman McInnes     set via the options database
34975cd90555SBarry Smith 
34985cd90555SBarry Smith    Notes:
34995cd90555SBarry Smith    There is no way to clear one specific monitor from a SNES object.
35005cd90555SBarry Smith 
350136851e7fSLois Curfman McInnes    Level: intermediate
350236851e7fSLois Curfman McInnes 
35035cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor
35045cd90555SBarry Smith 
3505a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet()
35065cd90555SBarry Smith @*/
35077087cfbeSBarry Smith PetscErrorCode  SNESMonitorCancel(SNES snes)
35085cd90555SBarry Smith {
3509d952e501SBarry Smith   PetscErrorCode ierr;
3510d952e501SBarry Smith   PetscInt       i;
3511d952e501SBarry Smith 
35125cd90555SBarry Smith   PetscFunctionBegin;
35130700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3514d952e501SBarry Smith   for (i=0; i<snes->numbermonitors; i++) {
3515d952e501SBarry Smith     if (snes->monitordestroy[i]) {
35163c4aec1bSBarry Smith       ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr);
3517d952e501SBarry Smith     }
3518d952e501SBarry Smith   }
35195cd90555SBarry Smith   snes->numbermonitors = 0;
35205cd90555SBarry Smith   PetscFunctionReturn(0);
35215cd90555SBarry Smith }
35225cd90555SBarry Smith 
3523bf388a1fSBarry Smith /*MC
3524bf388a1fSBarry Smith     SNESConvergenceTestFunction - functional form used for testing of convergence of nonlinear solver
3525bf388a1fSBarry Smith 
3526bf388a1fSBarry Smith      Synopsis:
3527aaa7dc30SBarry Smith      #include <petscsnes.h>
3528bf388a1fSBarry Smith $     PetscErrorCode SNESConvergenceTest(SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
3529bf388a1fSBarry Smith 
3530bf388a1fSBarry Smith +    snes - the SNES context
3531bf388a1fSBarry Smith .    it - current iteration (0 is the first and is before any Newton step)
3532bf388a1fSBarry Smith .    cctx - [optional] convergence context
3533bf388a1fSBarry Smith .    reason - reason for convergence/divergence
3534bf388a1fSBarry Smith .    xnorm - 2-norm of current iterate
3535bf388a1fSBarry Smith .    gnorm - 2-norm of current step
3536bf388a1fSBarry Smith -    f - 2-norm of function
3537bf388a1fSBarry Smith 
3538878cb397SSatish Balay    Level: intermediate
3539bf388a1fSBarry Smith 
3540bf388a1fSBarry Smith .seealso:   SNESSetConvergenceTest(), SNESGetConvergenceTest()
3541bf388a1fSBarry Smith M*/
3542bf388a1fSBarry Smith 
35439b94acceSBarry Smith /*@C
35449b94acceSBarry Smith    SNESSetConvergenceTest - Sets the function that is to be used
35459b94acceSBarry Smith    to test for convergence of the nonlinear iterative solution.
35469b94acceSBarry Smith 
35473f9fe445SBarry Smith    Logically Collective on SNES
3548fee21e36SBarry Smith 
3549c7afd0dbSLois Curfman McInnes    Input Parameters:
3550c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3551bf388a1fSBarry Smith .  SNESConvergenceTestFunction - routine to test for convergence
35520298fd71SBarry Smith .  cctx - [optional] context for private data for the convergence routine  (may be NULL)
35530298fd71SBarry Smith -  destroy - [optional] destructor for the context (may be NULL; NULL_FUNCTION in Fortran)
35549b94acceSBarry Smith 
355536851e7fSLois Curfman McInnes    Level: advanced
355636851e7fSLois Curfman McInnes 
35579b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test
35589b94acceSBarry Smith 
3559e2a6519dSDmitry Karpeev .seealso: SNESConvergedDefault(), SNESConvergedSkip(), SNESConvergenceTestFunction
35609b94acceSBarry Smith @*/
3561bf388a1fSBarry Smith PetscErrorCode  SNESSetConvergenceTest(SNES snes,PetscErrorCode (*SNESConvergenceTestFunction)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
35629b94acceSBarry Smith {
35637f7931b9SBarry Smith   PetscErrorCode ierr;
35647f7931b9SBarry Smith 
35653a40ed3dSBarry Smith   PetscFunctionBegin;
35660700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3567e2a6519dSDmitry Karpeev   if (!SNESConvergenceTestFunction) SNESConvergenceTestFunction = SNESConvergedSkip;
35687f7931b9SBarry Smith   if (snes->ops->convergeddestroy) {
35697f7931b9SBarry Smith     ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr);
35707f7931b9SBarry Smith   }
3571bf388a1fSBarry Smith   snes->ops->converged        = SNESConvergenceTestFunction;
35727f7931b9SBarry Smith   snes->ops->convergeddestroy = destroy;
357385385478SLisandro Dalcin   snes->cnvP                  = cctx;
35743a40ed3dSBarry Smith   PetscFunctionReturn(0);
35759b94acceSBarry Smith }
35769b94acceSBarry Smith 
357752baeb72SSatish Balay /*@
3578184914b5SBarry Smith    SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
3579184914b5SBarry Smith 
3580184914b5SBarry Smith    Not Collective
3581184914b5SBarry Smith 
3582184914b5SBarry Smith    Input Parameter:
3583184914b5SBarry Smith .  snes - the SNES context
3584184914b5SBarry Smith 
3585184914b5SBarry Smith    Output Parameter:
35864d0a8057SBarry Smith .  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
3587184914b5SBarry Smith             manual pages for the individual convergence tests for complete lists
3588184914b5SBarry Smith 
35896a4d7782SBarry Smith    Options Database:
35906a4d7782SBarry Smith .   -snes_converged_reason - prints the reason to standard out
35916a4d7782SBarry Smith 
3592184914b5SBarry Smith    Level: intermediate
3593184914b5SBarry Smith 
35946a4d7782SBarry 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.
3595184914b5SBarry Smith 
3596184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test
3597184914b5SBarry Smith 
359833866048SMatthew G. Knepley .seealso: SNESSetConvergenceTest(), SNESSetConvergedReason(), SNESConvergedReason
3599184914b5SBarry Smith @*/
36007087cfbeSBarry Smith PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
3601184914b5SBarry Smith {
3602184914b5SBarry Smith   PetscFunctionBegin;
36030700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
36044482741eSBarry Smith   PetscValidPointer(reason,2);
3605184914b5SBarry Smith   *reason = snes->reason;
3606184914b5SBarry Smith   PetscFunctionReturn(0);
3607184914b5SBarry Smith }
3608184914b5SBarry Smith 
360933866048SMatthew G. Knepley /*@
361033866048SMatthew G. Knepley    SNESSetConvergedReason - Sets the reason the SNES iteration was stopped.
361133866048SMatthew G. Knepley 
361233866048SMatthew G. Knepley    Not Collective
361333866048SMatthew G. Knepley 
361433866048SMatthew G. Knepley    Input Parameters:
361533866048SMatthew G. Knepley +  snes - the SNES context
361633866048SMatthew G. Knepley -  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
361733866048SMatthew G. Knepley             manual pages for the individual convergence tests for complete lists
361833866048SMatthew G. Knepley 
361933866048SMatthew G. Knepley    Level: intermediate
362033866048SMatthew G. Knepley 
362133866048SMatthew G. Knepley .keywords: SNES, nonlinear, set, convergence, test
362233866048SMatthew G. Knepley .seealso: SNESGetConvergedReason(), SNESSetConvergenceTest(), SNESConvergedReason
362333866048SMatthew G. Knepley @*/
362433866048SMatthew G. Knepley PetscErrorCode SNESSetConvergedReason(SNES snes,SNESConvergedReason reason)
362533866048SMatthew G. Knepley {
362633866048SMatthew G. Knepley   PetscFunctionBegin;
362733866048SMatthew G. Knepley   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
362833866048SMatthew G. Knepley   snes->reason = reason;
362933866048SMatthew G. Knepley   PetscFunctionReturn(0);
363033866048SMatthew G. Knepley }
363133866048SMatthew G. Knepley 
3632c9005455SLois Curfman McInnes /*@
3633c9005455SLois Curfman McInnes    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
3634c9005455SLois Curfman McInnes 
36353f9fe445SBarry Smith    Logically Collective on SNES
3636fee21e36SBarry Smith 
3637c7afd0dbSLois Curfman McInnes    Input Parameters:
3638c7afd0dbSLois Curfman McInnes +  snes - iterative context obtained from SNESCreate()
36398c7482ecSBarry Smith .  a   - array to hold history, this array will contain the function norms computed at each step
3640cd5578b5SBarry Smith .  its - integer array holds the number of linear iterations for each solve.
3641758f92a0SBarry Smith .  na  - size of a and its
364264731454SLois Curfman McInnes -  reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
3643758f92a0SBarry Smith            else it continues storing new values for new nonlinear solves after the old ones
3644c7afd0dbSLois Curfman McInnes 
3645308dcc3eSBarry Smith    Notes:
36460298fd71SBarry Smith    If 'a' and 'its' are NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a
3647308dcc3eSBarry Smith    default array of length 10000 is allocated.
3648308dcc3eSBarry Smith 
3649c9005455SLois Curfman McInnes    This routine is useful, e.g., when running a code for purposes
3650c9005455SLois Curfman McInnes    of accurate performance monitoring, when no I/O should be done
3651c9005455SLois Curfman McInnes    during the section of code that is being timed.
3652c9005455SLois Curfman McInnes 
365336851e7fSLois Curfman McInnes    Level: intermediate
365436851e7fSLois Curfman McInnes 
3655c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history
3656758f92a0SBarry Smith 
365708405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory()
3658758f92a0SBarry Smith 
3659c9005455SLois Curfman McInnes @*/
36607087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset)
3661c9005455SLois Curfman McInnes {
3662308dcc3eSBarry Smith   PetscErrorCode ierr;
3663308dcc3eSBarry Smith 
36643a40ed3dSBarry Smith   PetscFunctionBegin;
36650700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
36667a1ec6d4SBarry Smith   if (a) PetscValidScalarPointer(a,2);
3667a562a398SLisandro Dalcin   if (its) PetscValidIntPointer(its,3);
36687a1ec6d4SBarry Smith   if (!a) {
3669308dcc3eSBarry Smith     if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
36707fdeb8b9SBarry Smith     ierr = PetscCalloc1(na,&a);CHKERRQ(ierr);
36717fdeb8b9SBarry Smith     ierr = PetscCalloc1(na,&its);CHKERRQ(ierr);
3672f5af7f23SKarl Rupp 
3673308dcc3eSBarry Smith     snes->conv_malloc = PETSC_TRUE;
3674308dcc3eSBarry Smith   }
3675c9005455SLois Curfman McInnes   snes->conv_hist       = a;
3676758f92a0SBarry Smith   snes->conv_hist_its   = its;
3677758f92a0SBarry Smith   snes->conv_hist_max   = na;
3678a12bc48fSLisandro Dalcin   snes->conv_hist_len   = 0;
3679758f92a0SBarry Smith   snes->conv_hist_reset = reset;
3680758f92a0SBarry Smith   PetscFunctionReturn(0);
3681758f92a0SBarry Smith }
3682758f92a0SBarry Smith 
3683308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3684c6db04a5SJed Brown #include <engine.h>   /* MATLAB include file */
3685c6db04a5SJed Brown #include <mex.h>      /* MATLAB include file */
368699e0435eSBarry Smith 
36878cc058d9SJed Brown PETSC_EXTERN mxArray *SNESGetConvergenceHistoryMatlab(SNES snes)
3688308dcc3eSBarry Smith {
3689308dcc3eSBarry Smith   mxArray   *mat;
3690308dcc3eSBarry Smith   PetscInt  i;
3691308dcc3eSBarry Smith   PetscReal *ar;
3692308dcc3eSBarry Smith 
3693308dcc3eSBarry Smith   PetscFunctionBegin;
3694308dcc3eSBarry Smith   mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL);
3695308dcc3eSBarry Smith   ar  = (PetscReal*) mxGetData(mat);
3696f5af7f23SKarl Rupp   for (i=0; i<snes->conv_hist_len; i++) ar[i] = snes->conv_hist[i];
3697308dcc3eSBarry Smith   PetscFunctionReturn(mat);
3698308dcc3eSBarry Smith }
3699308dcc3eSBarry Smith #endif
3700308dcc3eSBarry Smith 
37010c4c9dddSBarry Smith /*@C
3702758f92a0SBarry Smith    SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
3703758f92a0SBarry Smith 
37043f9fe445SBarry Smith    Not Collective
3705758f92a0SBarry Smith 
3706758f92a0SBarry Smith    Input Parameter:
3707758f92a0SBarry Smith .  snes - iterative context obtained from SNESCreate()
3708758f92a0SBarry Smith 
3709758f92a0SBarry Smith    Output Parameters:
3710758f92a0SBarry Smith .  a   - array to hold history
3711758f92a0SBarry Smith .  its - integer array holds the number of linear iterations (or
3712758f92a0SBarry Smith          negative if not converged) for each solve.
3713758f92a0SBarry Smith -  na  - size of a and its
3714758f92a0SBarry Smith 
3715758f92a0SBarry Smith    Notes:
3716758f92a0SBarry Smith     The calling sequence for this routine in Fortran is
3717758f92a0SBarry Smith $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
3718758f92a0SBarry Smith 
3719758f92a0SBarry Smith    This routine is useful, e.g., when running a code for purposes
3720758f92a0SBarry Smith    of accurate performance monitoring, when no I/O should be done
3721758f92a0SBarry Smith    during the section of code that is being timed.
3722758f92a0SBarry Smith 
3723758f92a0SBarry Smith    Level: intermediate
3724758f92a0SBarry Smith 
3725758f92a0SBarry Smith .keywords: SNES, get, convergence, history
3726758f92a0SBarry Smith 
3727758f92a0SBarry Smith .seealso: SNESSetConvergencHistory()
3728758f92a0SBarry Smith 
3729758f92a0SBarry Smith @*/
37307087cfbeSBarry Smith PetscErrorCode  SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
3731758f92a0SBarry Smith {
3732758f92a0SBarry Smith   PetscFunctionBegin;
37330700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3734758f92a0SBarry Smith   if (a)   *a   = snes->conv_hist;
3735758f92a0SBarry Smith   if (its) *its = snes->conv_hist_its;
3736758f92a0SBarry Smith   if (na)  *na  = snes->conv_hist_len;
37373a40ed3dSBarry Smith   PetscFunctionReturn(0);
3738c9005455SLois Curfman McInnes }
3739c9005455SLois Curfman McInnes 
3740ac226902SBarry Smith /*@C
374176b2cf59SMatthew Knepley   SNESSetUpdate - Sets the general-purpose update function called
3742eec8f646SJed Brown   at the beginning of every iteration of the nonlinear solve. Specifically
37437e4bb74cSBarry Smith   it is called just before the Jacobian is "evaluated".
374476b2cf59SMatthew Knepley 
37453f9fe445SBarry Smith   Logically Collective on SNES
374676b2cf59SMatthew Knepley 
374776b2cf59SMatthew Knepley   Input Parameters:
374876b2cf59SMatthew Knepley . snes - The nonlinear solver context
374976b2cf59SMatthew Knepley . func - The function
375076b2cf59SMatthew Knepley 
375176b2cf59SMatthew Knepley   Calling sequence of func:
3752b5d30489SBarry Smith . func (SNES snes, PetscInt step);
375376b2cf59SMatthew Knepley 
375476b2cf59SMatthew Knepley . step - The current step of the iteration
375576b2cf59SMatthew Knepley 
3756fe97e370SBarry Smith   Level: advanced
3757fe97e370SBarry Smith 
3758fe97e370SBarry 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()
3759fe97e370SBarry Smith         This is not used by most users.
376076b2cf59SMatthew Knepley 
376176b2cf59SMatthew Knepley .keywords: SNES, update
3762b5d30489SBarry Smith 
37638d359177SBarry Smith .seealso SNESSetJacobian(), SNESSolve()
376476b2cf59SMatthew Knepley @*/
37657087cfbeSBarry Smith PetscErrorCode  SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
376676b2cf59SMatthew Knepley {
376776b2cf59SMatthew Knepley   PetscFunctionBegin;
37680700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID,1);
3769e7788613SBarry Smith   snes->ops->update = func;
377076b2cf59SMatthew Knepley   PetscFunctionReturn(0);
377176b2cf59SMatthew Knepley }
377276b2cf59SMatthew Knepley 
37739b94acceSBarry Smith /*
37749b94acceSBarry Smith    SNESScaleStep_Private - Scales a step so that its length is less than the
37759b94acceSBarry Smith    positive parameter delta.
37769b94acceSBarry Smith 
37779b94acceSBarry Smith     Input Parameters:
3778c7afd0dbSLois Curfman McInnes +   snes - the SNES context
37799b94acceSBarry Smith .   y - approximate solution of linear system
37809b94acceSBarry Smith .   fnorm - 2-norm of current function
3781c7afd0dbSLois Curfman McInnes -   delta - trust region size
37829b94acceSBarry Smith 
37839b94acceSBarry Smith     Output Parameters:
3784c7afd0dbSLois Curfman McInnes +   gpnorm - predicted function norm at the new point, assuming local
37859b94acceSBarry Smith     linearization.  The value is zero if the step lies within the trust
37869b94acceSBarry Smith     region, and exceeds zero otherwise.
3787c7afd0dbSLois Curfman McInnes -   ynorm - 2-norm of the step
37889b94acceSBarry Smith 
37899b94acceSBarry Smith     Note:
379004d7464bSBarry Smith     For non-trust region methods such as SNESNEWTONLS, the parameter delta
37919b94acceSBarry Smith     is set to be the maximum allowable step size.
37929b94acceSBarry Smith 
37939b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step
37949b94acceSBarry Smith */
3795dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
37969b94acceSBarry Smith {
3797064f8208SBarry Smith   PetscReal      nrm;
3798ea709b57SSatish Balay   PetscScalar    cnorm;
3799dfbe8321SBarry Smith   PetscErrorCode ierr;
38003a40ed3dSBarry Smith 
38013a40ed3dSBarry Smith   PetscFunctionBegin;
38020700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
38030700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3804c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,2);
3805184914b5SBarry Smith 
3806064f8208SBarry Smith   ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr);
3807064f8208SBarry Smith   if (nrm > *delta) {
3808064f8208SBarry Smith     nrm     = *delta/nrm;
3809064f8208SBarry Smith     *gpnorm = (1.0 - nrm)*(*fnorm);
3810064f8208SBarry Smith     cnorm   = nrm;
38112dcb1b2aSMatthew Knepley     ierr    = VecScale(y,cnorm);CHKERRQ(ierr);
38129b94acceSBarry Smith     *ynorm  = *delta;
38139b94acceSBarry Smith   } else {
38149b94acceSBarry Smith     *gpnorm = 0.0;
3815064f8208SBarry Smith     *ynorm  = nrm;
38169b94acceSBarry Smith   }
38173a40ed3dSBarry Smith   PetscFunctionReturn(0);
38189b94acceSBarry Smith }
38199b94acceSBarry Smith 
38202a359c20SBarry Smith /*@
38212a359c20SBarry Smith    SNESReasonView - Displays the reason a SNES solve converged or diverged to a viewer
38222a359c20SBarry Smith 
38232a359c20SBarry Smith    Collective on SNES
38242a359c20SBarry Smith 
38252a359c20SBarry Smith    Parameter:
38262a359c20SBarry Smith +  snes - iterative context obtained from SNESCreate()
38272a359c20SBarry Smith -  viewer - the viewer to display the reason
38282a359c20SBarry Smith 
38292a359c20SBarry Smith 
38302a359c20SBarry Smith    Options Database Keys:
38312a359c20SBarry Smith .  -snes_converged_reason - print reason for converged or diverged, also prints number of iterations
38322a359c20SBarry Smith 
38332a359c20SBarry Smith    Level: beginner
38342a359c20SBarry Smith 
38352a359c20SBarry Smith .keywords: SNES, solve, linear system
38362a359c20SBarry Smith 
38372a359c20SBarry Smith .seealso: SNESCreate(), SNESSetUp(), SNESDestroy(), SNESSetTolerances(), SNESConvergedDefault()
38382a359c20SBarry Smith 
38392a359c20SBarry Smith @*/
38402a359c20SBarry Smith PetscErrorCode  SNESReasonView(SNES snes,PetscViewer viewer)
38412a359c20SBarry Smith {
38422a359c20SBarry Smith   PetscErrorCode ierr;
38432a359c20SBarry Smith   PetscBool      isAscii;
38442a359c20SBarry Smith 
38452a359c20SBarry Smith   PetscFunctionBegin;
38462a359c20SBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isAscii);CHKERRQ(ierr);
38472a359c20SBarry Smith   if (isAscii) {
38482a359c20SBarry Smith     ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
38492a359c20SBarry Smith     if (snes->reason > 0) {
38502a359c20SBarry Smith       if (((PetscObject) snes)->prefix) {
38512a359c20SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear %s solve converged due to %s iterations %D\n",((PetscObject) snes)->prefix,SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr);
38522a359c20SBarry Smith       } else {
38532a359c20SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear solve converged due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr);
38542a359c20SBarry Smith       }
38552a359c20SBarry Smith     } else {
38562a359c20SBarry Smith       if (((PetscObject) snes)->prefix) {
38572a359c20SBarry 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);
38582a359c20SBarry Smith       } else {
38592a359c20SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear solve did not converge due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr);
38602a359c20SBarry Smith       }
38612a359c20SBarry Smith     }
38622a359c20SBarry Smith     ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
38632a359c20SBarry Smith   }
38642a359c20SBarry Smith   PetscFunctionReturn(0);
38652a359c20SBarry Smith }
38662a359c20SBarry Smith 
38672a359c20SBarry Smith /*@C
38682a359c20SBarry Smith   SNESReasonViewFromOptions - Processes command line options to determine if/how a SNESReason is to be viewed.
38692a359c20SBarry Smith 
38702a359c20SBarry Smith   Collective on SNES
38712a359c20SBarry Smith 
38722a359c20SBarry Smith   Input Parameters:
38732a359c20SBarry Smith . snes   - the SNES object
38742a359c20SBarry Smith 
38752a359c20SBarry Smith   Level: intermediate
38762a359c20SBarry Smith 
38772a359c20SBarry Smith @*/
38782a359c20SBarry Smith PetscErrorCode SNESReasonViewFromOptions(SNES snes)
38792a359c20SBarry Smith {
38802a359c20SBarry Smith   PetscErrorCode    ierr;
38812a359c20SBarry Smith   PetscViewer       viewer;
38822a359c20SBarry Smith   PetscBool         flg;
38832a359c20SBarry Smith   static PetscBool  incall = PETSC_FALSE;
38842a359c20SBarry Smith   PetscViewerFormat format;
38852a359c20SBarry Smith 
38862a359c20SBarry Smith   PetscFunctionBegin;
38872a359c20SBarry Smith   if (incall) PetscFunctionReturn(0);
38882a359c20SBarry Smith   incall = PETSC_TRUE;
38892a359c20SBarry Smith   ierr   = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_converged_reason",&viewer,&format,&flg);CHKERRQ(ierr);
38902a359c20SBarry Smith   if (flg) {
38912a359c20SBarry Smith     ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr);
38922a359c20SBarry Smith     ierr = SNESReasonView(snes,viewer);CHKERRQ(ierr);
38932a359c20SBarry Smith     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
38942a359c20SBarry Smith     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
38952a359c20SBarry Smith   }
38962a359c20SBarry Smith   incall = PETSC_FALSE;
38972a359c20SBarry Smith   PetscFunctionReturn(0);
38982a359c20SBarry Smith }
38992a359c20SBarry Smith 
39006ce558aeSBarry Smith /*@C
3901f69a0ea3SMatthew Knepley    SNESSolve - Solves a nonlinear system F(x) = b.
3902f69a0ea3SMatthew Knepley    Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
39039b94acceSBarry Smith 
3904c7afd0dbSLois Curfman McInnes    Collective on SNES
3905c7afd0dbSLois Curfman McInnes 
3906b2002411SLois Curfman McInnes    Input Parameters:
3907c7afd0dbSLois Curfman McInnes +  snes - the SNES context
39080298fd71SBarry Smith .  b - the constant part of the equation F(x) = b, or NULL to use zero.
390985385478SLisandro Dalcin -  x - the solution vector.
39109b94acceSBarry Smith 
3911b2002411SLois Curfman McInnes    Notes:
39128ddd3da0SLois Curfman McInnes    The user should initialize the vector,x, with the initial guess
39138ddd3da0SLois Curfman McInnes    for the nonlinear solve prior to calling SNESSolve.  In particular,
39148ddd3da0SLois Curfman McInnes    to employ an initial guess of zero, the user should explicitly set
39158ddd3da0SLois Curfman McInnes    this vector to zero by calling VecSet().
39168ddd3da0SLois Curfman McInnes 
391736851e7fSLois Curfman McInnes    Level: beginner
391836851e7fSLois Curfman McInnes 
39199b94acceSBarry Smith .keywords: SNES, nonlinear, solve
39209b94acceSBarry Smith 
3921c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution()
39229b94acceSBarry Smith @*/
39237087cfbeSBarry Smith PetscErrorCode  SNESSolve(SNES snes,Vec b,Vec x)
39249b94acceSBarry Smith {
3925dfbe8321SBarry Smith   PetscErrorCode    ierr;
3926ace3abfcSBarry Smith   PetscBool         flg;
3927efd51863SBarry Smith   PetscInt          grid;
39280298fd71SBarry Smith   Vec               xcreated = NULL;
3929caa4e7f2SJed Brown   DM                dm;
3930052efed2SBarry Smith 
39313a40ed3dSBarry Smith   PetscFunctionBegin;
39320700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3933a69afd8bSBarry Smith   if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3934a69afd8bSBarry Smith   if (x) PetscCheckSameComm(snes,1,x,3);
39350700a824SBarry Smith   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2);
393685385478SLisandro Dalcin   if (b) PetscCheckSameComm(snes,1,b,2);
393785385478SLisandro Dalcin 
3938caa4e7f2SJed Brown   if (!x) {
3939caa4e7f2SJed Brown     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3940caa4e7f2SJed Brown     ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr);
3941a69afd8bSBarry Smith     x    = xcreated;
3942a69afd8bSBarry Smith   }
3943ce1779c8SBarry Smith   ierr = SNESViewFromOptions(snes,NULL,"-snes_view_pre");CHKERRQ(ierr);
3944f05ece33SBarry Smith 
3945ce94432eSBarry Smith   for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)));CHKERRQ(ierr);}
3946efd51863SBarry Smith   for (grid=0; grid<snes->gridsequence+1; grid++) {
3947efd51863SBarry Smith 
394885385478SLisandro Dalcin     /* set solution vector */
3949efd51863SBarry Smith     if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);}
39506bf464f9SBarry Smith     ierr          = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
395185385478SLisandro Dalcin     snes->vec_sol = x;
3952caa4e7f2SJed Brown     ierr          = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3953caa4e7f2SJed Brown 
3954caa4e7f2SJed Brown     /* set affine vector if provided */
395585385478SLisandro Dalcin     if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); }
39566bf464f9SBarry Smith     ierr          = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
395785385478SLisandro Dalcin     snes->vec_rhs = b;
395885385478SLisandro Dalcin 
3959154060b5SMatthew G. Knepley     if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
3960154060b5SMatthew 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");
3961154060b5SMatthew G. Knepley     if (!snes->vec_sol_update /* && snes->vec_sol */) {
3962154060b5SMatthew G. Knepley       ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr);
3963154060b5SMatthew G. Knepley       ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->vec_sol_update);CHKERRQ(ierr);
3964154060b5SMatthew G. Knepley     }
3965154060b5SMatthew G. Knepley     ierr = DMShellSetGlobalVector(dm,snes->vec_sol);CHKERRQ(ierr);
396670e92668SMatthew Knepley     ierr = SNESSetUp(snes);CHKERRQ(ierr);
39673f149594SLisandro Dalcin 
39687eee914bSBarry Smith     if (!grid) {
39697eee914bSBarry Smith       if (snes->ops->computeinitialguess) {
3970d25893d9SBarry Smith         ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr);
3971d25893d9SBarry Smith       }
3972dd568438SSatish Balay     }
3973d25893d9SBarry Smith 
3974abc0a331SBarry Smith     if (snes->conv_hist_reset) snes->conv_hist_len = 0;
3975971e163fSPeter Brune     if (snes->counters_reset) {snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;}
3976d5e45103SBarry Smith 
39773f149594SLisandro Dalcin     ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
39784936397dSBarry Smith     ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr);
397985385478SLisandro Dalcin     ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
398017186662SBarry Smith     if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
3981422a814eSBarry Smith     snes->domainerror = PETSC_FALSE; /* clear the flag if it has been set */
39823f149594SLisandro Dalcin 
398337ec4e1aSPeter Brune     if (snes->lagjac_persist) snes->jac_iter += snes->iter;
398437ec4e1aSPeter Brune     if (snes->lagpre_persist) snes->pre_iter += snes->iter;
398537ec4e1aSPeter Brune 
398627b0f280SBarry Smith     ierr   = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_test_local_min",NULL,NULL,&flg);CHKERRQ(ierr);
3987da9b6338SBarry Smith     if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); }
39882a359c20SBarry Smith     ierr = SNESReasonViewFromOptions(snes);CHKERRQ(ierr);
39895968eb51SBarry Smith 
3990ce94432eSBarry Smith     if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged");
39919c8e83a9SBarry Smith     if (snes->reason < 0) break;
3992efd51863SBarry Smith     if (grid <  snes->gridsequence) {
3993efd51863SBarry Smith       DM  fine;
3994efd51863SBarry Smith       Vec xnew;
3995efd51863SBarry Smith       Mat interp;
3996efd51863SBarry Smith 
3997ce94432eSBarry Smith       ierr = DMRefine(snes->dm,PetscObjectComm((PetscObject)snes),&fine);CHKERRQ(ierr);
3998ce94432eSBarry Smith       if (!fine) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing");
39990298fd71SBarry Smith       ierr = DMCreateInterpolation(snes->dm,fine,&interp,NULL);CHKERRQ(ierr);
4000efd51863SBarry Smith       ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr);
4001efd51863SBarry Smith       ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr);
4002c833c3b5SJed Brown       ierr = DMInterpolate(snes->dm,interp,fine);CHKERRQ(ierr);
4003efd51863SBarry Smith       ierr = MatDestroy(&interp);CHKERRQ(ierr);
4004efd51863SBarry Smith       x    = xnew;
4005efd51863SBarry Smith 
4006efd51863SBarry Smith       ierr = SNESReset(snes);CHKERRQ(ierr);
4007efd51863SBarry Smith       ierr = SNESSetDM(snes,fine);CHKERRQ(ierr);
4008efd51863SBarry Smith       ierr = DMDestroy(&fine);CHKERRQ(ierr);
4009ce94432eSBarry Smith       ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)));CHKERRQ(ierr);
4010efd51863SBarry Smith     }
4011efd51863SBarry Smith   }
4012ce1779c8SBarry Smith   ierr = SNESViewFromOptions(snes,NULL,"-snes_view");CHKERRQ(ierr);
4013685405a1SBarry Smith   ierr = VecViewFromOptions(snes->vec_sol,(PetscObject)snes,"-snes_view_solution");CHKERRQ(ierr);
40143f7e2da0SPeter Brune 
4015a69afd8bSBarry Smith   ierr = VecDestroy(&xcreated);CHKERRQ(ierr);
4016e04113cfSBarry Smith   ierr = PetscObjectSAWsBlock((PetscObject)snes);CHKERRQ(ierr);
40173a40ed3dSBarry Smith   PetscFunctionReturn(0);
40189b94acceSBarry Smith }
40199b94acceSBarry Smith 
40209b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */
40219b94acceSBarry Smith 
402282bf6240SBarry Smith /*@C
40234b0e389bSBarry Smith    SNESSetType - Sets the method for the nonlinear solver.
40249b94acceSBarry Smith 
4025fee21e36SBarry Smith    Collective on SNES
4026fee21e36SBarry Smith 
4027c7afd0dbSLois Curfman McInnes    Input Parameters:
4028c7afd0dbSLois Curfman McInnes +  snes - the SNES context
4029454a90a3SBarry Smith -  type - a known method
4030c7afd0dbSLois Curfman McInnes 
4031c7afd0dbSLois Curfman McInnes    Options Database Key:
4032454a90a3SBarry Smith .  -snes_type <type> - Sets the method; use -help for a list
403304d7464bSBarry Smith    of available methods (for instance, newtonls or newtontr)
4034ae12b187SLois Curfman McInnes 
40359b94acceSBarry Smith    Notes:
4036e090d566SSatish Balay    See "petsc/include/petscsnes.h" for available methods (for instance)
403704d7464bSBarry Smith +    SNESNEWTONLS - Newton's method with line search
4038c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
403904d7464bSBarry Smith .    SNESNEWTONTR - Newton's method with trust region
4040c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
40419b94acceSBarry Smith 
4042ae12b187SLois Curfman McInnes   Normally, it is best to use the SNESSetFromOptions() command and then
4043ae12b187SLois Curfman McInnes   set the SNES solver type from the options database rather than by using
4044ae12b187SLois Curfman McInnes   this routine.  Using the options database provides the user with
4045ae12b187SLois Curfman McInnes   maximum flexibility in evaluating the many nonlinear solvers.
4046ae12b187SLois Curfman McInnes   The SNESSetType() routine is provided for those situations where it
4047ae12b187SLois Curfman McInnes   is necessary to set the nonlinear solver independently of the command
4048ae12b187SLois Curfman McInnes   line or options database.  This might be the case, for example, when
4049ae12b187SLois Curfman McInnes   the choice of solver changes during the execution of the program,
4050ae12b187SLois Curfman McInnes   and the user's application is taking responsibility for choosing the
4051b0a32e0cSBarry Smith   appropriate method.
405236851e7fSLois Curfman McInnes 
40538f6c3df8SBarry Smith     Developer Notes: SNESRegister() adds a constructor for a new SNESType to SNESList, SNESSetType() locates
40548f6c3df8SBarry Smith     the constructor in that list and calls it to create the spexific object.
40558f6c3df8SBarry Smith 
405636851e7fSLois Curfman McInnes   Level: intermediate
4057a703fe33SLois Curfman McInnes 
4058454a90a3SBarry Smith .keywords: SNES, set, type
4059435da068SBarry Smith 
40608f6c3df8SBarry Smith .seealso: SNESType, SNESCreate(), SNESDestroy(), SNESGetType(), SNESSetFromOptions()
4061435da068SBarry Smith 
40629b94acceSBarry Smith @*/
406319fd82e9SBarry Smith PetscErrorCode  SNESSetType(SNES snes,SNESType type)
40649b94acceSBarry Smith {
4065dfbe8321SBarry Smith   PetscErrorCode ierr,(*r)(SNES);
4066ace3abfcSBarry Smith   PetscBool      match;
40673a40ed3dSBarry Smith 
40683a40ed3dSBarry Smith   PetscFunctionBegin;
40690700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
40704482741eSBarry Smith   PetscValidCharPointer(type,2);
407182bf6240SBarry Smith 
4072251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr);
40730f5bd95cSBarry Smith   if (match) PetscFunctionReturn(0);
407492ff6ae8SBarry Smith 
40751c9cd337SJed Brown   ierr =  PetscFunctionListFind(SNESList,type,&r);CHKERRQ(ierr);
4076e32f2f54SBarry Smith   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
407775396ef9SLisandro Dalcin   /* Destroy the previous private SNES context */
4078b5c23020SJed Brown   if (snes->ops->destroy) {
4079b5c23020SJed Brown     ierr               = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr);
40800298fd71SBarry Smith     snes->ops->destroy = NULL;
4081b5c23020SJed Brown   }
408275396ef9SLisandro Dalcin   /* Reinitialize function pointers in SNESOps structure */
408375396ef9SLisandro Dalcin   snes->ops->setup          = 0;
408475396ef9SLisandro Dalcin   snes->ops->solve          = 0;
408575396ef9SLisandro Dalcin   snes->ops->view           = 0;
408675396ef9SLisandro Dalcin   snes->ops->setfromoptions = 0;
408775396ef9SLisandro Dalcin   snes->ops->destroy        = 0;
408875396ef9SLisandro Dalcin   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
408975396ef9SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
4090f5af7f23SKarl Rupp 
4091454a90a3SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr);
409203bfa161SLisandro Dalcin   ierr = (*r)(snes);CHKERRQ(ierr);
40933a40ed3dSBarry Smith   PetscFunctionReturn(0);
40949b94acceSBarry Smith }
40959b94acceSBarry Smith 
40969b94acceSBarry Smith /*@C
40979a28b0a6SLois Curfman McInnes    SNESGetType - Gets the SNES method type and name (as a string).
40989b94acceSBarry Smith 
4099c7afd0dbSLois Curfman McInnes    Not Collective
4100c7afd0dbSLois Curfman McInnes 
41019b94acceSBarry Smith    Input Parameter:
41024b0e389bSBarry Smith .  snes - nonlinear solver context
41039b94acceSBarry Smith 
41049b94acceSBarry Smith    Output Parameter:
41053a7fca6bSBarry Smith .  type - SNES method (a character string)
41069b94acceSBarry Smith 
410736851e7fSLois Curfman McInnes    Level: intermediate
410836851e7fSLois Curfman McInnes 
4109454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name
41109b94acceSBarry Smith @*/
411119fd82e9SBarry Smith PetscErrorCode  SNESGetType(SNES snes,SNESType *type)
41129b94acceSBarry Smith {
41133a40ed3dSBarry Smith   PetscFunctionBegin;
41140700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
41154482741eSBarry Smith   PetscValidPointer(type,2);
41167adad957SLisandro Dalcin   *type = ((PetscObject)snes)->type_name;
41173a40ed3dSBarry Smith   PetscFunctionReturn(0);
41189b94acceSBarry Smith }
41199b94acceSBarry Smith 
41203cd8a7caSMatthew G. Knepley /*@
41213cd8a7caSMatthew G. Knepley   SNESSetSolution - Sets the solution vector for use by the SNES routines.
41223cd8a7caSMatthew G. Knepley 
41233cd8a7caSMatthew G. Knepley   Logically Collective on SNES and Vec
41243cd8a7caSMatthew G. Knepley 
41253cd8a7caSMatthew G. Knepley   Input Parameters:
41263cd8a7caSMatthew G. Knepley + snes - the SNES context obtained from SNESCreate()
41273cd8a7caSMatthew G. Knepley - u    - the solution vector
41283cd8a7caSMatthew G. Knepley 
41293cd8a7caSMatthew G. Knepley   Level: beginner
41303cd8a7caSMatthew G. Knepley 
41313cd8a7caSMatthew G. Knepley .keywords: SNES, set, solution
41323cd8a7caSMatthew G. Knepley @*/
41333cd8a7caSMatthew G. Knepley PetscErrorCode SNESSetSolution(SNES snes, Vec u)
41343cd8a7caSMatthew G. Knepley {
41353cd8a7caSMatthew G. Knepley   DM             dm;
41363cd8a7caSMatthew G. Knepley   PetscErrorCode ierr;
41373cd8a7caSMatthew G. Knepley 
41383cd8a7caSMatthew G. Knepley   PetscFunctionBegin;
41393cd8a7caSMatthew G. Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
41403cd8a7caSMatthew G. Knepley   PetscValidHeaderSpecific(u, VEC_CLASSID, 2);
41413cd8a7caSMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) u);CHKERRQ(ierr);
41423cd8a7caSMatthew G. Knepley   ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
41433cd8a7caSMatthew G. Knepley 
41443cd8a7caSMatthew G. Knepley   snes->vec_sol = u;
41453cd8a7caSMatthew G. Knepley 
41463cd8a7caSMatthew G. Knepley   ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr);
41473cd8a7caSMatthew G. Knepley   ierr = DMShellSetGlobalVector(dm, u);CHKERRQ(ierr);
41483cd8a7caSMatthew G. Knepley   PetscFunctionReturn(0);
41493cd8a7caSMatthew G. Knepley }
41503cd8a7caSMatthew G. Knepley 
415152baeb72SSatish Balay /*@
41529b94acceSBarry Smith    SNESGetSolution - Returns the vector where the approximate solution is
4153c0df2a02SJed Brown    stored. This is the fine grid solution when using SNESSetGridSequence().
41549b94acceSBarry Smith 
4155c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
4156c7afd0dbSLois Curfman McInnes 
41579b94acceSBarry Smith    Input Parameter:
41589b94acceSBarry Smith .  snes - the SNES context
41599b94acceSBarry Smith 
41609b94acceSBarry Smith    Output Parameter:
41619b94acceSBarry Smith .  x - the solution
41629b94acceSBarry Smith 
416370e92668SMatthew Knepley    Level: intermediate
416436851e7fSLois Curfman McInnes 
41659b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution
41669b94acceSBarry Smith 
416785385478SLisandro Dalcin .seealso:  SNESGetSolutionUpdate(), SNESGetFunction()
41689b94acceSBarry Smith @*/
41697087cfbeSBarry Smith PetscErrorCode  SNESGetSolution(SNES snes,Vec *x)
41709b94acceSBarry Smith {
41713a40ed3dSBarry Smith   PetscFunctionBegin;
41720700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
41734482741eSBarry Smith   PetscValidPointer(x,2);
417485385478SLisandro Dalcin   *x = snes->vec_sol;
417570e92668SMatthew Knepley   PetscFunctionReturn(0);
417670e92668SMatthew Knepley }
417770e92668SMatthew Knepley 
417852baeb72SSatish Balay /*@
41799b94acceSBarry Smith    SNESGetSolutionUpdate - Returns the vector where the solution update is
41809b94acceSBarry Smith    stored.
41819b94acceSBarry Smith 
4182c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
4183c7afd0dbSLois Curfman McInnes 
41849b94acceSBarry Smith    Input Parameter:
41859b94acceSBarry Smith .  snes - the SNES context
41869b94acceSBarry Smith 
41879b94acceSBarry Smith    Output Parameter:
41889b94acceSBarry Smith .  x - the solution update
41899b94acceSBarry Smith 
419036851e7fSLois Curfman McInnes    Level: advanced
419136851e7fSLois Curfman McInnes 
41929b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update
41939b94acceSBarry Smith 
419485385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction()
41959b94acceSBarry Smith @*/
41967087cfbeSBarry Smith PetscErrorCode  SNESGetSolutionUpdate(SNES snes,Vec *x)
41979b94acceSBarry Smith {
41983a40ed3dSBarry Smith   PetscFunctionBegin;
41990700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
42004482741eSBarry Smith   PetscValidPointer(x,2);
420185385478SLisandro Dalcin   *x = snes->vec_sol_update;
42023a40ed3dSBarry Smith   PetscFunctionReturn(0);
42039b94acceSBarry Smith }
42049b94acceSBarry Smith 
42059b94acceSBarry Smith /*@C
42063638b69dSLois Curfman McInnes    SNESGetFunction - Returns the vector where the function is stored.
42079b94acceSBarry Smith 
4208a63bb30eSJed Brown    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
4209c7afd0dbSLois Curfman McInnes 
42109b94acceSBarry Smith    Input Parameter:
42119b94acceSBarry Smith .  snes - the SNES context
42129b94acceSBarry Smith 
42139b94acceSBarry Smith    Output Parameter:
42140298fd71SBarry Smith +  r - the vector that is used to store residuals (or NULL if you don't want it)
4215f8b49ee9SBarry Smith .  f - the function (or NULL if you don't want it); see SNESFunction for calling sequence details
42160298fd71SBarry Smith -  ctx - the function context (or NULL if you don't want it)
42179b94acceSBarry Smith 
421836851e7fSLois Curfman McInnes    Level: advanced
421936851e7fSLois Curfman McInnes 
4220a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function
42219b94acceSBarry Smith 
4222bf388a1fSBarry Smith .seealso: SNESSetFunction(), SNESGetSolution(), SNESFunction
42239b94acceSBarry Smith @*/
4224f8b49ee9SBarry Smith PetscErrorCode  SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**f)(SNES,Vec,Vec,void*),void **ctx)
42259b94acceSBarry Smith {
4226a63bb30eSJed Brown   PetscErrorCode ierr;
42276cab3a1bSJed Brown   DM             dm;
4228a63bb30eSJed Brown 
42293a40ed3dSBarry Smith   PetscFunctionBegin;
42300700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4231a63bb30eSJed Brown   if (r) {
4232a63bb30eSJed Brown     if (!snes->vec_func) {
4233a63bb30eSJed Brown       if (snes->vec_rhs) {
4234a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr);
4235a63bb30eSJed Brown       } else if (snes->vec_sol) {
4236a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr);
4237a63bb30eSJed Brown       } else if (snes->dm) {
4238a63bb30eSJed Brown         ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr);
4239a63bb30eSJed Brown       }
4240a63bb30eSJed Brown     }
4241a63bb30eSJed Brown     *r = snes->vec_func;
4242a63bb30eSJed Brown   }
42436cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
4244f8b49ee9SBarry Smith   ierr = DMSNESGetFunction(dm,f,ctx);CHKERRQ(ierr);
42453a40ed3dSBarry Smith   PetscFunctionReturn(0);
42469b94acceSBarry Smith }
42479b94acceSBarry Smith 
4248c79ef259SPeter Brune /*@C
4249be95d8f1SBarry Smith    SNESGetNGS - Returns the NGS function and context.
4250c79ef259SPeter Brune 
4251c79ef259SPeter Brune    Input Parameter:
4252c79ef259SPeter Brune .  snes - the SNES context
4253c79ef259SPeter Brune 
4254c79ef259SPeter Brune    Output Parameter:
4255be95d8f1SBarry Smith +  f - the function (or NULL) see SNESNGSFunction for details
42560298fd71SBarry Smith -  ctx    - the function context (or NULL)
4257c79ef259SPeter Brune 
4258c79ef259SPeter Brune    Level: advanced
4259c79ef259SPeter Brune 
4260c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function
4261c79ef259SPeter Brune 
4262be95d8f1SBarry Smith .seealso: SNESSetNGS(), SNESGetFunction()
4263c79ef259SPeter Brune @*/
4264c79ef259SPeter Brune 
4265be95d8f1SBarry Smith PetscErrorCode SNESGetNGS (SNES snes, PetscErrorCode (**f)(SNES, Vec, Vec, void*), void ** ctx)
4266646217ecSPeter Brune {
42676cab3a1bSJed Brown   PetscErrorCode ierr;
42686cab3a1bSJed Brown   DM             dm;
42696cab3a1bSJed Brown 
4270646217ecSPeter Brune   PetscFunctionBegin;
4271646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
42726cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
4273be95d8f1SBarry Smith   ierr = DMSNESGetNGS(dm,f,ctx);CHKERRQ(ierr);
4274646217ecSPeter Brune   PetscFunctionReturn(0);
4275646217ecSPeter Brune }
4276646217ecSPeter Brune 
42773c7409f5SSatish Balay /*@C
42783c7409f5SSatish Balay    SNESSetOptionsPrefix - Sets the prefix used for searching for all
4279d850072dSLois Curfman McInnes    SNES options in the database.
42803c7409f5SSatish Balay 
42813f9fe445SBarry Smith    Logically Collective on SNES
4282fee21e36SBarry Smith 
4283c7afd0dbSLois Curfman McInnes    Input Parameter:
4284c7afd0dbSLois Curfman McInnes +  snes - the SNES context
4285c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
4286c7afd0dbSLois Curfman McInnes 
4287d850072dSLois Curfman McInnes    Notes:
4288a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
4289c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
4290d850072dSLois Curfman McInnes 
429136851e7fSLois Curfman McInnes    Level: advanced
429236851e7fSLois Curfman McInnes 
42933c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database
4294a86d99e1SLois Curfman McInnes 
4295a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions()
42963c7409f5SSatish Balay @*/
42977087cfbeSBarry Smith PetscErrorCode  SNESSetOptionsPrefix(SNES snes,const char prefix[])
42983c7409f5SSatish Balay {
4299dfbe8321SBarry Smith   PetscErrorCode ierr;
43003c7409f5SSatish Balay 
43013a40ed3dSBarry Smith   PetscFunctionBegin;
43020700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4303639f9d9dSBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
43041cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
430535f5d045SPeter Brune   if (snes->linesearch) {
43067601faf0SJed Brown     ierr = SNESGetLineSearch(snes,&snes->linesearch);CHKERRQ(ierr);
430708b6c495SPeter Brune     ierr = PetscObjectSetOptionsPrefix((PetscObject)snes->linesearch,prefix);CHKERRQ(ierr);
430835f5d045SPeter Brune   }
430935f5d045SPeter Brune   ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
43103a40ed3dSBarry Smith   PetscFunctionReturn(0);
43113c7409f5SSatish Balay }
43123c7409f5SSatish Balay 
43133c7409f5SSatish Balay /*@C
4314f525115eSLois Curfman McInnes    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
4315d850072dSLois Curfman McInnes    SNES options in the database.
43163c7409f5SSatish Balay 
43173f9fe445SBarry Smith    Logically Collective on SNES
4318fee21e36SBarry Smith 
4319c7afd0dbSLois Curfman McInnes    Input Parameters:
4320c7afd0dbSLois Curfman McInnes +  snes - the SNES context
4321c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
4322c7afd0dbSLois Curfman McInnes 
4323d850072dSLois Curfman McInnes    Notes:
4324a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
4325c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
4326d850072dSLois Curfman McInnes 
432736851e7fSLois Curfman McInnes    Level: advanced
432836851e7fSLois Curfman McInnes 
43293c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database
4330a86d99e1SLois Curfman McInnes 
4331a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix()
43323c7409f5SSatish Balay @*/
43337087cfbeSBarry Smith PetscErrorCode  SNESAppendOptionsPrefix(SNES snes,const char prefix[])
43343c7409f5SSatish Balay {
4335dfbe8321SBarry Smith   PetscErrorCode ierr;
43363c7409f5SSatish Balay 
43373a40ed3dSBarry Smith   PetscFunctionBegin;
43380700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4339639f9d9dSBarry Smith   ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
43401cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
434135f5d045SPeter Brune   if (snes->linesearch) {
43427601faf0SJed Brown     ierr = SNESGetLineSearch(snes,&snes->linesearch);CHKERRQ(ierr);
434308b6c495SPeter Brune     ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes->linesearch,prefix);CHKERRQ(ierr);
434435f5d045SPeter Brune   }
434535f5d045SPeter Brune   ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
43463a40ed3dSBarry Smith   PetscFunctionReturn(0);
43473c7409f5SSatish Balay }
43483c7409f5SSatish Balay 
43499ab63eb5SSatish Balay /*@C
43503c7409f5SSatish Balay    SNESGetOptionsPrefix - Sets the prefix used for searching for all
43513c7409f5SSatish Balay    SNES options in the database.
43523c7409f5SSatish Balay 
4353c7afd0dbSLois Curfman McInnes    Not Collective
4354c7afd0dbSLois Curfman McInnes 
43553c7409f5SSatish Balay    Input Parameter:
43563c7409f5SSatish Balay .  snes - the SNES context
43573c7409f5SSatish Balay 
43583c7409f5SSatish Balay    Output Parameter:
43593c7409f5SSatish Balay .  prefix - pointer to the prefix string used
43603c7409f5SSatish Balay 
43614ef407dbSRichard Tran Mills    Notes: On the fortran side, the user should pass in a string 'prefix' of
43629ab63eb5SSatish Balay    sufficient length to hold the prefix.
43639ab63eb5SSatish Balay 
436436851e7fSLois Curfman McInnes    Level: advanced
436536851e7fSLois Curfman McInnes 
43663c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database
4367a86d99e1SLois Curfman McInnes 
4368a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix()
43693c7409f5SSatish Balay @*/
43707087cfbeSBarry Smith PetscErrorCode  SNESGetOptionsPrefix(SNES snes,const char *prefix[])
43713c7409f5SSatish Balay {
4372dfbe8321SBarry Smith   PetscErrorCode ierr;
43733c7409f5SSatish Balay 
43743a40ed3dSBarry Smith   PetscFunctionBegin;
43750700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4376639f9d9dSBarry Smith   ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
43773a40ed3dSBarry Smith   PetscFunctionReturn(0);
43783c7409f5SSatish Balay }
43793c7409f5SSatish Balay 
4380b2002411SLois Curfman McInnes 
43813cea93caSBarry Smith /*@C
43821c84c290SBarry Smith   SNESRegister - Adds a method to the nonlinear solver package.
43831c84c290SBarry Smith 
43841c84c290SBarry Smith    Not collective
43851c84c290SBarry Smith 
43861c84c290SBarry Smith    Input Parameters:
43871c84c290SBarry Smith +  name_solver - name of a new user-defined solver
43881c84c290SBarry Smith -  routine_create - routine to create method context
43891c84c290SBarry Smith 
43901c84c290SBarry Smith    Notes:
43911c84c290SBarry Smith    SNESRegister() may be called multiple times to add several user-defined solvers.
43921c84c290SBarry Smith 
43931c84c290SBarry Smith    Sample usage:
43941c84c290SBarry Smith .vb
4395bdf89e91SBarry Smith    SNESRegister("my_solver",MySolverCreate);
43961c84c290SBarry Smith .ve
43971c84c290SBarry Smith 
43981c84c290SBarry Smith    Then, your solver can be chosen with the procedural interface via
43991c84c290SBarry Smith $     SNESSetType(snes,"my_solver")
44001c84c290SBarry Smith    or at runtime via the option
44011c84c290SBarry Smith $     -snes_type my_solver
44021c84c290SBarry Smith 
44031c84c290SBarry Smith    Level: advanced
44041c84c290SBarry Smith 
44051c84c290SBarry Smith     Note: If your function is not being put into a shared library then use SNESRegister() instead
44061c84c290SBarry Smith 
44071c84c290SBarry Smith .keywords: SNES, nonlinear, register
44081c84c290SBarry Smith 
44091c84c290SBarry Smith .seealso: SNESRegisterAll(), SNESRegisterDestroy()
44103cea93caSBarry Smith 
44117f6c08e0SMatthew Knepley   Level: advanced
44123cea93caSBarry Smith @*/
4413bdf89e91SBarry Smith PetscErrorCode  SNESRegister(const char sname[],PetscErrorCode (*function)(SNES))
4414b2002411SLois Curfman McInnes {
4415dfbe8321SBarry Smith   PetscErrorCode ierr;
4416b2002411SLois Curfman McInnes 
4417b2002411SLois Curfman McInnes   PetscFunctionBegin;
4418a240a19fSJed Brown   ierr = PetscFunctionListAdd(&SNESList,sname,function);CHKERRQ(ierr);
4419b2002411SLois Curfman McInnes   PetscFunctionReturn(0);
4420b2002411SLois Curfman McInnes }
4421da9b6338SBarry Smith 
44227087cfbeSBarry Smith PetscErrorCode  SNESTestLocalMin(SNES snes)
4423da9b6338SBarry Smith {
4424dfbe8321SBarry Smith   PetscErrorCode ierr;
442577431f27SBarry Smith   PetscInt       N,i,j;
4426da9b6338SBarry Smith   Vec            u,uh,fh;
4427da9b6338SBarry Smith   PetscScalar    value;
4428da9b6338SBarry Smith   PetscReal      norm;
4429da9b6338SBarry Smith 
4430da9b6338SBarry Smith   PetscFunctionBegin;
4431da9b6338SBarry Smith   ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr);
4432da9b6338SBarry Smith   ierr = VecDuplicate(u,&uh);CHKERRQ(ierr);
4433da9b6338SBarry Smith   ierr = VecDuplicate(u,&fh);CHKERRQ(ierr);
4434da9b6338SBarry Smith 
4435da9b6338SBarry Smith   /* currently only works for sequential */
443622d28d08SBarry Smith   ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");CHKERRQ(ierr);
4437da9b6338SBarry Smith   ierr = VecGetSize(u,&N);CHKERRQ(ierr);
4438da9b6338SBarry Smith   for (i=0; i<N; i++) {
4439da9b6338SBarry Smith     ierr = VecCopy(u,uh);CHKERRQ(ierr);
444077431f27SBarry Smith     ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr);
4441da9b6338SBarry Smith     for (j=-10; j<11; j++) {
44428b49ba18SBarry Smith       value = PetscSign(j)*PetscExpReal(PetscAbs(j)-10.0);
4443da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
44443ab0aad5SBarry Smith       ierr  = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr);
4445da9b6338SBarry Smith       ierr  = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr);
444677431f27SBarry Smith       ierr  = PetscPrintf(PETSC_COMM_WORLD,"       j norm %D %18.16e\n",j,norm);CHKERRQ(ierr);
4447da9b6338SBarry Smith       value = -value;
4448da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
4449da9b6338SBarry Smith     }
4450da9b6338SBarry Smith   }
44516bf464f9SBarry Smith   ierr = VecDestroy(&uh);CHKERRQ(ierr);
44526bf464f9SBarry Smith   ierr = VecDestroy(&fh);CHKERRQ(ierr);
4453da9b6338SBarry Smith   PetscFunctionReturn(0);
4454da9b6338SBarry Smith }
445571f87433Sdalcinl 
445671f87433Sdalcinl /*@
4457fa9f3622SBarry Smith    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
445871f87433Sdalcinl    computing relative tolerance for linear solvers within an inexact
445971f87433Sdalcinl    Newton method.
446071f87433Sdalcinl 
44613f9fe445SBarry Smith    Logically Collective on SNES
446271f87433Sdalcinl 
446371f87433Sdalcinl    Input Parameters:
446471f87433Sdalcinl +  snes - SNES context
446571f87433Sdalcinl -  flag - PETSC_TRUE or PETSC_FALSE
446671f87433Sdalcinl 
446764ba62caSBarry Smith     Options Database:
446864ba62caSBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
446964ba62caSBarry Smith .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
447064ba62caSBarry Smith .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
447164ba62caSBarry Smith .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
447264ba62caSBarry Smith .  -snes_ksp_ew_gamma <gamma> - Sets gamma
447364ba62caSBarry Smith .  -snes_ksp_ew_alpha <alpha> - Sets alpha
447464ba62caSBarry Smith .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
447564ba62caSBarry Smith -  -snes_ksp_ew_threshold <threshold> - Sets threshold
447664ba62caSBarry Smith 
447771f87433Sdalcinl    Notes:
447871f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
447971f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
448071f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
448171f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
448271f87433Sdalcinl    solver.
448371f87433Sdalcinl 
448471f87433Sdalcinl    Level: advanced
448571f87433Sdalcinl 
448671f87433Sdalcinl    Reference:
448771f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
448871f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
448971f87433Sdalcinl 
449071f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
449171f87433Sdalcinl 
4492fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
449371f87433Sdalcinl @*/
44947087cfbeSBarry Smith PetscErrorCode  SNESKSPSetUseEW(SNES snes,PetscBool flag)
449571f87433Sdalcinl {
449671f87433Sdalcinl   PetscFunctionBegin;
44970700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4498acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flag,2);
449971f87433Sdalcinl   snes->ksp_ewconv = flag;
450071f87433Sdalcinl   PetscFunctionReturn(0);
450171f87433Sdalcinl }
450271f87433Sdalcinl 
450371f87433Sdalcinl /*@
4504fa9f3622SBarry Smith    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
450571f87433Sdalcinl    for computing relative tolerance for linear solvers within an
450671f87433Sdalcinl    inexact Newton method.
450771f87433Sdalcinl 
450871f87433Sdalcinl    Not Collective
450971f87433Sdalcinl 
451071f87433Sdalcinl    Input Parameter:
451171f87433Sdalcinl .  snes - SNES context
451271f87433Sdalcinl 
451371f87433Sdalcinl    Output Parameter:
451471f87433Sdalcinl .  flag - PETSC_TRUE or PETSC_FALSE
451571f87433Sdalcinl 
451671f87433Sdalcinl    Notes:
451771f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
451871f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
451971f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
452071f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
452171f87433Sdalcinl    solver.
452271f87433Sdalcinl 
452371f87433Sdalcinl    Level: advanced
452471f87433Sdalcinl 
452571f87433Sdalcinl    Reference:
452671f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
452771f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
452871f87433Sdalcinl 
452971f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
453071f87433Sdalcinl 
4531fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
453271f87433Sdalcinl @*/
45337087cfbeSBarry Smith PetscErrorCode  SNESKSPGetUseEW(SNES snes, PetscBool  *flag)
453471f87433Sdalcinl {
453571f87433Sdalcinl   PetscFunctionBegin;
45360700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
453771f87433Sdalcinl   PetscValidPointer(flag,2);
453871f87433Sdalcinl   *flag = snes->ksp_ewconv;
453971f87433Sdalcinl   PetscFunctionReturn(0);
454071f87433Sdalcinl }
454171f87433Sdalcinl 
454271f87433Sdalcinl /*@
4543fa9f3622SBarry Smith    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
454471f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
454571f87433Sdalcinl    Newton method.
454671f87433Sdalcinl 
45473f9fe445SBarry Smith    Logically Collective on SNES
454871f87433Sdalcinl 
454971f87433Sdalcinl    Input Parameters:
455071f87433Sdalcinl +    snes - SNES context
455171f87433Sdalcinl .    version - version 1, 2 (default is 2) or 3
455271f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
455371f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
455471f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
455571f87433Sdalcinl              (0 <= gamma2 <= 1)
455671f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
455771f87433Sdalcinl .    alpha2 - power for safeguard
455871f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
455971f87433Sdalcinl 
456071f87433Sdalcinl    Note:
456171f87433Sdalcinl    Version 3 was contributed by Luis Chacon, June 2006.
456271f87433Sdalcinl 
456371f87433Sdalcinl    Use PETSC_DEFAULT to retain the default for any of the parameters.
456471f87433Sdalcinl 
456571f87433Sdalcinl    Level: advanced
456671f87433Sdalcinl 
456771f87433Sdalcinl    Reference:
456871f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
456971f87433Sdalcinl    inexact Newton method", Utah State University Math. Stat. Dept. Res.
457071f87433Sdalcinl    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
457171f87433Sdalcinl 
457271f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
457371f87433Sdalcinl 
4574fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
457571f87433Sdalcinl @*/
4576f5af7f23SKarl Rupp PetscErrorCode  SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
457771f87433Sdalcinl {
4578fa9f3622SBarry Smith   SNESKSPEW *kctx;
45795fd66863SKarl Rupp 
458071f87433Sdalcinl   PetscFunctionBegin;
45810700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4582fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
4583e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
4584c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,version,2);
4585c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_0,3);
4586c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_max,4);
4587c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,gamma,5);
4588c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha,6);
4589c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha2,7);
4590c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,threshold,8);
459171f87433Sdalcinl 
459271f87433Sdalcinl   if (version != PETSC_DEFAULT)   kctx->version   = version;
459371f87433Sdalcinl   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
459471f87433Sdalcinl   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
459571f87433Sdalcinl   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
459671f87433Sdalcinl   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
459771f87433Sdalcinl   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
459871f87433Sdalcinl   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
459971f87433Sdalcinl 
4600f23aa3ddSBarry 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);
460157622a8eSBarry 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);
460257622a8eSBarry 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);
460357622a8eSBarry 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);
460457622a8eSBarry 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);
460557622a8eSBarry 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);
460671f87433Sdalcinl   PetscFunctionReturn(0);
460771f87433Sdalcinl }
460871f87433Sdalcinl 
460971f87433Sdalcinl /*@
4610fa9f3622SBarry Smith    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
461171f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
461271f87433Sdalcinl    Newton method.
461371f87433Sdalcinl 
461471f87433Sdalcinl    Not Collective
461571f87433Sdalcinl 
461671f87433Sdalcinl    Input Parameters:
461771f87433Sdalcinl      snes - SNES context
461871f87433Sdalcinl 
461971f87433Sdalcinl    Output Parameters:
462071f87433Sdalcinl +    version - version 1, 2 (default is 2) or 3
462171f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
462271f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
4623bf388a1fSBarry Smith .    gamma - multiplicative factor for version 2 rtol computation (0 <= gamma2 <= 1)
462471f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
462571f87433Sdalcinl .    alpha2 - power for safeguard
462671f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
462771f87433Sdalcinl 
462871f87433Sdalcinl    Level: advanced
462971f87433Sdalcinl 
463071f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters
463171f87433Sdalcinl 
4632fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
463371f87433Sdalcinl @*/
4634bf388a1fSBarry Smith PetscErrorCode  SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
463571f87433Sdalcinl {
4636fa9f3622SBarry Smith   SNESKSPEW *kctx;
46375fd66863SKarl Rupp 
463871f87433Sdalcinl   PetscFunctionBegin;
46390700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4640fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
4641e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
464271f87433Sdalcinl   if (version)   *version   = kctx->version;
464371f87433Sdalcinl   if (rtol_0)    *rtol_0    = kctx->rtol_0;
464471f87433Sdalcinl   if (rtol_max)  *rtol_max  = kctx->rtol_max;
464571f87433Sdalcinl   if (gamma)     *gamma     = kctx->gamma;
464671f87433Sdalcinl   if (alpha)     *alpha     = kctx->alpha;
464771f87433Sdalcinl   if (alpha2)    *alpha2    = kctx->alpha2;
464871f87433Sdalcinl   if (threshold) *threshold = kctx->threshold;
464971f87433Sdalcinl   PetscFunctionReturn(0);
465071f87433Sdalcinl }
465171f87433Sdalcinl 
4652d5378b5fSDmitry Karpeev  PetscErrorCode KSPPreSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes)
465371f87433Sdalcinl {
465471f87433Sdalcinl   PetscErrorCode ierr;
4655fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
465671f87433Sdalcinl   PetscReal      rtol  = PETSC_DEFAULT,stol;
465771f87433Sdalcinl 
465871f87433Sdalcinl   PetscFunctionBegin;
4659d4211eb9SBarry Smith   if (!snes->ksp_ewconv) PetscFunctionReturn(0);
466030058271SDmitry Karpeev   if (!snes->iter) {
466130058271SDmitry Karpeev     rtol = kctx->rtol_0; /* first time in, so use the original user rtol */
466230058271SDmitry Karpeev     ierr = VecNorm(snes->vec_func,NORM_2,&kctx->norm_first);CHKERRQ(ierr);
466330058271SDmitry Karpeev   }
4664f5af7f23SKarl Rupp   else {
466571f87433Sdalcinl     if (kctx->version == 1) {
466671f87433Sdalcinl       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
466771f87433Sdalcinl       if (rtol < 0.0) rtol = -rtol;
466885ec1a3cSBarry Smith       stol = PetscPowReal(kctx->rtol_last,kctx->alpha2);
466971f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
467071f87433Sdalcinl     } else if (kctx->version == 2) {
467185ec1a3cSBarry Smith       rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha);
467285ec1a3cSBarry Smith       stol = kctx->gamma * PetscPowReal(kctx->rtol_last,kctx->alpha);
467371f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
467471f87433Sdalcinl     } else if (kctx->version == 3) { /* contributed by Luis Chacon, June 2006. */
467585ec1a3cSBarry Smith       rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha);
467671f87433Sdalcinl       /* safeguard: avoid sharp decrease of rtol */
467785ec1a3cSBarry Smith       stol = kctx->gamma*PetscPowReal(kctx->rtol_last,kctx->alpha);
467871f87433Sdalcinl       stol = PetscMax(rtol,stol);
467971f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
468071f87433Sdalcinl       /* safeguard: avoid oversolving */
468130058271SDmitry Karpeev       stol = kctx->gamma*(kctx->norm_first*snes->rtol)/snes->norm;
468271f87433Sdalcinl       stol = PetscMax(rtol,stol);
468371f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
4684e32f2f54SBarry Smith     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
468571f87433Sdalcinl   }
468671f87433Sdalcinl   /* safeguard: avoid rtol greater than one */
468771f87433Sdalcinl   rtol = PetscMin(rtol,kctx->rtol_max);
468871f87433Sdalcinl   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
468957622a8eSBarry Smith   ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%g\n",snes->iter,kctx->version,(double)rtol);CHKERRQ(ierr);
469071f87433Sdalcinl   PetscFunctionReturn(0);
469171f87433Sdalcinl }
469271f87433Sdalcinl 
4693d5378b5fSDmitry Karpeev PetscErrorCode KSPPostSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes)
469471f87433Sdalcinl {
469571f87433Sdalcinl   PetscErrorCode ierr;
4696fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
469771f87433Sdalcinl   PCSide         pcside;
469871f87433Sdalcinl   Vec            lres;
469971f87433Sdalcinl 
470071f87433Sdalcinl   PetscFunctionBegin;
4701d4211eb9SBarry Smith   if (!snes->ksp_ewconv) PetscFunctionReturn(0);
470271f87433Sdalcinl   ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr);
470371dbe336SPeter Brune   kctx->norm_last = snes->norm;
470471f87433Sdalcinl   if (kctx->version == 1) {
47054f00ce20SMatthew G. Knepley     PC        pc;
47064f00ce20SMatthew G. Knepley     PetscBool isNone;
47074f00ce20SMatthew G. Knepley 
47084f00ce20SMatthew G. Knepley     ierr = KSPGetPC(ksp, &pc);CHKERRQ(ierr);
47094f00ce20SMatthew G. Knepley     ierr = PetscObjectTypeCompare((PetscObject) pc, PCNONE, &isNone);CHKERRQ(ierr);
4710b037da10SBarry Smith     ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr);
47114f00ce20SMatthew G. Knepley      if (pcside == PC_RIGHT || isNone) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
471271f87433Sdalcinl       /* KSP residual is true linear residual */
471371f87433Sdalcinl       ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr);
471471f87433Sdalcinl     } else {
471571f87433Sdalcinl       /* KSP residual is preconditioned residual */
471671f87433Sdalcinl       /* compute true linear residual norm */
471771f87433Sdalcinl       ierr = VecDuplicate(b,&lres);CHKERRQ(ierr);
471871f87433Sdalcinl       ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr);
471971f87433Sdalcinl       ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr);
472071f87433Sdalcinl       ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr);
47216bf464f9SBarry Smith       ierr = VecDestroy(&lres);CHKERRQ(ierr);
472271f87433Sdalcinl     }
472371f87433Sdalcinl   }
472471f87433Sdalcinl   PetscFunctionReturn(0);
472571f87433Sdalcinl }
472671f87433Sdalcinl 
4727d4211eb9SBarry Smith /*@
4728d4211eb9SBarry Smith    SNESGetKSP - Returns the KSP context for a SNES solver.
4729d4211eb9SBarry Smith 
4730d4211eb9SBarry Smith    Not Collective, but if SNES object is parallel, then KSP object is parallel
4731d4211eb9SBarry Smith 
4732d4211eb9SBarry Smith    Input Parameter:
4733d4211eb9SBarry Smith .  snes - the SNES context
4734d4211eb9SBarry Smith 
4735d4211eb9SBarry Smith    Output Parameter:
4736d4211eb9SBarry Smith .  ksp - the KSP context
4737d4211eb9SBarry Smith 
4738d4211eb9SBarry Smith    Notes:
4739d4211eb9SBarry Smith    The user can then directly manipulate the KSP context to set various
4740d4211eb9SBarry Smith    options, etc.  Likewise, the user can then extract and manipulate the
4741d4211eb9SBarry Smith    PC contexts as well.
4742d4211eb9SBarry Smith 
4743d4211eb9SBarry Smith    Level: beginner
4744d4211eb9SBarry Smith 
4745d4211eb9SBarry Smith .keywords: SNES, nonlinear, get, KSP, context
4746d4211eb9SBarry Smith 
4747d4211eb9SBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
4748d4211eb9SBarry Smith @*/
4749d4211eb9SBarry Smith PetscErrorCode  SNESGetKSP(SNES snes,KSP *ksp)
475071f87433Sdalcinl {
475171f87433Sdalcinl   PetscErrorCode ierr;
475271f87433Sdalcinl 
475371f87433Sdalcinl   PetscFunctionBegin;
4754d4211eb9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4755d4211eb9SBarry Smith   PetscValidPointer(ksp,2);
4756d4211eb9SBarry Smith 
4757d4211eb9SBarry Smith   if (!snes->ksp) {
4758a5c2985bSBarry Smith     PetscBool monitor = PETSC_FALSE;
4759a5c2985bSBarry Smith 
4760d4211eb9SBarry Smith     ierr = KSPCreate(PetscObjectComm((PetscObject)snes),&snes->ksp);CHKERRQ(ierr);
4761d4211eb9SBarry Smith     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr);
47623bb1ff40SBarry Smith     ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->ksp);CHKERRQ(ierr);
4763d4211eb9SBarry Smith 
4764d5378b5fSDmitry Karpeev     ierr = KSPSetPreSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPreSolve_SNESEW,snes);CHKERRQ(ierr);
4765d5378b5fSDmitry Karpeev     ierr = KSPSetPostSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPostSolve_SNESEW,snes);CHKERRQ(ierr);
4766a5c2985bSBarry Smith 
4767c5929fdfSBarry Smith     ierr = PetscOptionsGetBool(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-ksp_monitor_snes",&monitor,NULL);CHKERRQ(ierr);
4768a5c2985bSBarry Smith     if (monitor) {
4769a5c2985bSBarry Smith       ierr = KSPMonitorSet(snes->ksp,KSPMonitorSNES,snes,NULL);CHKERRQ(ierr);
4770a5c2985bSBarry Smith     }
4771e5f7ee39SBarry Smith     monitor = PETSC_FALSE;
4772c5929fdfSBarry Smith     ierr = PetscOptionsGetBool(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-ksp_monitor_snes_lg",&monitor,NULL);CHKERRQ(ierr);
4773e5f7ee39SBarry Smith     if (monitor) {
4774e5f7ee39SBarry Smith       PetscObject *objs;
47758b0b5a47SLisandro Dalcin       ierr = KSPMonitorSNESLGResidualNormCreate(PetscObjectComm((PetscObject)snes),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,600,600,&objs);CHKERRQ(ierr);
4776e5f7ee39SBarry Smith       objs[0] = (PetscObject) snes;
4777e5f7ee39SBarry Smith       ierr = KSPMonitorSet(snes->ksp,(PetscErrorCode (*)(KSP,PetscInt,PetscReal,void*))KSPMonitorSNESLGResidualNorm,objs,(PetscErrorCode (*)(void**))KSPMonitorSNESLGResidualNormDestroy);CHKERRQ(ierr);
4778e5f7ee39SBarry Smith     }
4779d4211eb9SBarry Smith   }
4780d4211eb9SBarry Smith   *ksp = snes->ksp;
478171f87433Sdalcinl   PetscFunctionReturn(0);
478271f87433Sdalcinl }
47836c699258SBarry Smith 
4784d4211eb9SBarry Smith 
4785af0996ceSBarry Smith #include <petsc/private/dmimpl.h>
47866c699258SBarry Smith /*@
47872a808120SBarry Smith    SNESSetDM - Sets the DM that may be used by some nonlinear solvers or their underlying preconditioners
47886c699258SBarry Smith 
47893f9fe445SBarry Smith    Logically Collective on SNES
47906c699258SBarry Smith 
47916c699258SBarry Smith    Input Parameters:
47922a808120SBarry Smith +  snes - the nonlinear solver context
47932a808120SBarry Smith -  dm - the dm, cannot be NULL
47946c699258SBarry Smith 
47956c699258SBarry Smith    Level: intermediate
47966c699258SBarry Smith 
47976c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM()
47986c699258SBarry Smith @*/
47997087cfbeSBarry Smith PetscErrorCode  SNESSetDM(SNES snes,DM dm)
48006c699258SBarry Smith {
48016c699258SBarry Smith   PetscErrorCode ierr;
4802345fed2cSBarry Smith   KSP            ksp;
4803942e3340SBarry Smith   DMSNES         sdm;
48046c699258SBarry Smith 
48056c699258SBarry Smith   PetscFunctionBegin;
48060700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
48072a808120SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,2);
48082a808120SBarry Smith   ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);
4809942e3340SBarry Smith   if (snes->dm) {               /* Move the DMSNES context over to the new DM unless the new DM already has one */
481051f4b3c7SToby Isaac     if (snes->dm->dmsnes && !dm->dmsnes) {
4811942e3340SBarry Smith       ierr = DMCopyDMSNES(snes->dm,dm);CHKERRQ(ierr);
4812942e3340SBarry Smith       ierr = DMGetDMSNES(snes->dm,&sdm);CHKERRQ(ierr);
4813f5af7f23SKarl Rupp       if (sdm->originaldm == snes->dm) sdm->originaldm = dm; /* Grant write privileges to the replacement DM */
48146cab3a1bSJed Brown     }
48156bf464f9SBarry Smith     ierr = DMDestroy(&snes->dm);CHKERRQ(ierr);
48166cab3a1bSJed Brown   }
48176c699258SBarry Smith   snes->dm     = dm;
4818116d1032SJed Brown   snes->dmAuto = PETSC_FALSE;
4819f5af7f23SKarl Rupp 
4820345fed2cSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
4821345fed2cSBarry Smith   ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr);
4822f22f69f0SBarry Smith   ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr);
4823*efd4aadfSBarry Smith   if (snes->npc) {
4824*efd4aadfSBarry Smith     ierr = SNESSetDM(snes->npc, snes->dm);CHKERRQ(ierr);
4825*efd4aadfSBarry Smith     ierr = SNESSetNPCSide(snes,snes->npcside);CHKERRQ(ierr);
48262c155ee1SBarry Smith   }
48276c699258SBarry Smith   PetscFunctionReturn(0);
48286c699258SBarry Smith }
48296c699258SBarry Smith 
48306c699258SBarry Smith /*@
48316c699258SBarry Smith    SNESGetDM - Gets the DM that may be used by some preconditioners
48326c699258SBarry Smith 
48333f9fe445SBarry Smith    Not Collective but DM obtained is parallel on SNES
48346c699258SBarry Smith 
48356c699258SBarry Smith    Input Parameter:
48366c699258SBarry Smith . snes - the preconditioner context
48376c699258SBarry Smith 
48386c699258SBarry Smith    Output Parameter:
48396c699258SBarry Smith .  dm - the dm
48406c699258SBarry Smith 
48416c699258SBarry Smith    Level: intermediate
48426c699258SBarry Smith 
48436c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM()
48446c699258SBarry Smith @*/
48457087cfbeSBarry Smith PetscErrorCode  SNESGetDM(SNES snes,DM *dm)
48466c699258SBarry Smith {
48476cab3a1bSJed Brown   PetscErrorCode ierr;
48486cab3a1bSJed Brown 
48496c699258SBarry Smith   PetscFunctionBegin;
48500700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
48516cab3a1bSJed Brown   if (!snes->dm) {
4852ce94432eSBarry Smith     ierr         = DMShellCreate(PetscObjectComm((PetscObject)snes),&snes->dm);CHKERRQ(ierr);
4853116d1032SJed Brown     snes->dmAuto = PETSC_TRUE;
48546cab3a1bSJed Brown   }
48556c699258SBarry Smith   *dm = snes->dm;
48566c699258SBarry Smith   PetscFunctionReturn(0);
48576c699258SBarry Smith }
48580807856dSBarry Smith 
485931823bd8SMatthew G Knepley /*@
4860be95d8f1SBarry Smith   SNESSetNPC - Sets the nonlinear preconditioner to be used.
486131823bd8SMatthew G Knepley 
486231823bd8SMatthew G Knepley   Collective on SNES
486331823bd8SMatthew G Knepley 
486431823bd8SMatthew G Knepley   Input Parameters:
486531823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate()
486631823bd8SMatthew G Knepley - pc   - the preconditioner object
486731823bd8SMatthew G Knepley 
486831823bd8SMatthew G Knepley   Notes:
4869be95d8f1SBarry Smith   Use SNESGetNPC() to retrieve the preconditioner context (for example,
487031823bd8SMatthew G Knepley   to configure it using the API).
487131823bd8SMatthew G Knepley 
487231823bd8SMatthew G Knepley   Level: developer
487331823bd8SMatthew G Knepley 
487431823bd8SMatthew G Knepley .keywords: SNES, set, precondition
48753ad1a0b9SPatrick Farrell .seealso: SNESGetNPC(), SNESHasNPC()
487631823bd8SMatthew G Knepley @*/
4877be95d8f1SBarry Smith PetscErrorCode SNESSetNPC(SNES snes, SNES pc)
487831823bd8SMatthew G Knepley {
487931823bd8SMatthew G Knepley   PetscErrorCode ierr;
488031823bd8SMatthew G Knepley 
488131823bd8SMatthew G Knepley   PetscFunctionBegin;
488231823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
488331823bd8SMatthew G Knepley   PetscValidHeaderSpecific(pc, SNES_CLASSID, 2);
488431823bd8SMatthew G Knepley   PetscCheckSameComm(snes, 1, pc, 2);
488531823bd8SMatthew G Knepley   ierr     = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr);
4886*efd4aadfSBarry Smith   ierr     = SNESDestroy(&snes->npc);CHKERRQ(ierr);
4887*efd4aadfSBarry Smith   snes->npc = pc;
4888*efd4aadfSBarry Smith   ierr     = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->npc);CHKERRQ(ierr);
488931823bd8SMatthew G Knepley   PetscFunctionReturn(0);
489031823bd8SMatthew G Knepley }
489131823bd8SMatthew G Knepley 
489231823bd8SMatthew G Knepley /*@
4893be95d8f1SBarry Smith   SNESGetNPC - Creates a nonlinear preconditioning solver (SNES) to be used to precondition the nonlinear solver.
489431823bd8SMatthew G Knepley 
489531823bd8SMatthew G Knepley   Not Collective
489631823bd8SMatthew G Knepley 
489731823bd8SMatthew G Knepley   Input Parameter:
489831823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate()
489931823bd8SMatthew G Knepley 
490031823bd8SMatthew G Knepley   Output Parameter:
490131823bd8SMatthew G Knepley . pc - preconditioner context
490231823bd8SMatthew G Knepley 
4903be95d8f1SBarry Smith   Notes: If a SNES was previously set with SNESSetNPC() then that SNES is returned.
4904be95d8f1SBarry Smith 
490531823bd8SMatthew G Knepley   Level: developer
490631823bd8SMatthew G Knepley 
490731823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner
49083ad1a0b9SPatrick Farrell .seealso: SNESSetNPC(), SNESHasNPC()
490931823bd8SMatthew G Knepley @*/
4910be95d8f1SBarry Smith PetscErrorCode SNESGetNPC(SNES snes, SNES *pc)
491131823bd8SMatthew G Knepley {
491231823bd8SMatthew G Knepley   PetscErrorCode ierr;
4913a64e098fSPeter Brune   const char     *optionsprefix;
491431823bd8SMatthew G Knepley 
491531823bd8SMatthew G Knepley   PetscFunctionBegin;
491631823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
491731823bd8SMatthew G Knepley   PetscValidPointer(pc, 2);
4918*efd4aadfSBarry Smith   if (!snes->npc) {
4919*efd4aadfSBarry Smith     ierr = SNESCreate(PetscObjectComm((PetscObject)snes),&snes->npc);CHKERRQ(ierr);
4920*efd4aadfSBarry Smith     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->npc,(PetscObject)snes,1);CHKERRQ(ierr);
4921*efd4aadfSBarry Smith     ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->npc);CHKERRQ(ierr);
4922a64e098fSPeter Brune     ierr = SNESGetOptionsPrefix(snes,&optionsprefix);CHKERRQ(ierr);
4923*efd4aadfSBarry Smith     ierr = SNESSetOptionsPrefix(snes->npc,optionsprefix);CHKERRQ(ierr);
4924*efd4aadfSBarry Smith     ierr = SNESAppendOptionsPrefix(snes->npc,"npc_");CHKERRQ(ierr);
4925*efd4aadfSBarry Smith     ierr = SNESSetCountersReset(snes->npc,PETSC_FALSE);CHKERRQ(ierr);
492631823bd8SMatthew G Knepley   }
4927*efd4aadfSBarry Smith   *pc = snes->npc;
492831823bd8SMatthew G Knepley   PetscFunctionReturn(0);
492931823bd8SMatthew G Knepley }
493031823bd8SMatthew G Knepley 
49313ad1a0b9SPatrick Farrell /*@
49323ad1a0b9SPatrick Farrell   SNESHasNPC - Returns whether a nonlinear preconditioner exists
49333ad1a0b9SPatrick Farrell 
49343ad1a0b9SPatrick Farrell   Not Collective
49353ad1a0b9SPatrick Farrell 
49363ad1a0b9SPatrick Farrell   Input Parameter:
49373ad1a0b9SPatrick Farrell . snes - iterative context obtained from SNESCreate()
49383ad1a0b9SPatrick Farrell 
49393ad1a0b9SPatrick Farrell   Output Parameter:
49403ad1a0b9SPatrick Farrell . has_npc - whether the SNES has an NPC or not
49413ad1a0b9SPatrick Farrell 
49423ad1a0b9SPatrick Farrell   Level: developer
49433ad1a0b9SPatrick Farrell 
49443ad1a0b9SPatrick Farrell .keywords: SNES, has, preconditioner
49453ad1a0b9SPatrick Farrell .seealso: SNESSetNPC(), SNESGetNPC()
49463ad1a0b9SPatrick Farrell @*/
49473ad1a0b9SPatrick Farrell PetscErrorCode SNESHasNPC(SNES snes, PetscBool *has_npc)
49483ad1a0b9SPatrick Farrell {
49493ad1a0b9SPatrick Farrell   PetscFunctionBegin;
49503ad1a0b9SPatrick Farrell   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4951*efd4aadfSBarry Smith   *has_npc = (PetscBool) (snes->npc ? PETSC_TRUE : PETSC_FALSE);
49523ad1a0b9SPatrick Farrell   PetscFunctionReturn(0);
49533ad1a0b9SPatrick Farrell }
49543ad1a0b9SPatrick Farrell 
4955c40d0f55SPeter Brune /*@
4956be95d8f1SBarry Smith     SNESSetNPCSide - Sets the preconditioning side.
4957c40d0f55SPeter Brune 
4958c40d0f55SPeter Brune     Logically Collective on SNES
4959c40d0f55SPeter Brune 
4960c40d0f55SPeter Brune     Input Parameter:
4961c40d0f55SPeter Brune .   snes - iterative context obtained from SNESCreate()
4962c40d0f55SPeter Brune 
4963c40d0f55SPeter Brune     Output Parameter:
4964c40d0f55SPeter Brune .   side - the preconditioning side, where side is one of
4965c40d0f55SPeter Brune .vb
49662d547940SBarry Smith       PC_LEFT - left preconditioning
49672d547940SBarry Smith       PC_RIGHT - right preconditioning (default for most nonlinear solvers)
4968c40d0f55SPeter Brune .ve
4969c40d0f55SPeter Brune 
4970c40d0f55SPeter Brune     Options Database Keys:
4971c40d0f55SPeter Brune .   -snes_pc_side <right,left>
4972c40d0f55SPeter Brune 
49732d547940SBarry Smith     Notes: SNESNRICHARDSON and SNESNCG only support left preconditioning.
49742d547940SBarry Smith 
4975c40d0f55SPeter Brune     Level: intermediate
4976c40d0f55SPeter Brune 
4977c40d0f55SPeter Brune .keywords: SNES, set, right, left, side, preconditioner, flag
4978c40d0f55SPeter Brune 
4979be95d8f1SBarry Smith .seealso: SNESGetNPCSide(), KSPSetPCSide()
4980c40d0f55SPeter Brune @*/
4981be95d8f1SBarry Smith PetscErrorCode  SNESSetNPCSide(SNES snes,PCSide side)
4982c40d0f55SPeter Brune {
4983c40d0f55SPeter Brune   PetscFunctionBegin;
4984c40d0f55SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4985c40d0f55SPeter Brune   PetscValidLogicalCollectiveEnum(snes,side,2);
4986*efd4aadfSBarry Smith   snes->npcside= side;
4987c40d0f55SPeter Brune   PetscFunctionReturn(0);
4988c40d0f55SPeter Brune }
4989c40d0f55SPeter Brune 
4990c40d0f55SPeter Brune /*@
4991be95d8f1SBarry Smith     SNESGetNPCSide - Gets the preconditioning side.
4992c40d0f55SPeter Brune 
4993c40d0f55SPeter Brune     Not Collective
4994c40d0f55SPeter Brune 
4995c40d0f55SPeter Brune     Input Parameter:
4996c40d0f55SPeter Brune .   snes - iterative context obtained from SNESCreate()
4997c40d0f55SPeter Brune 
4998c40d0f55SPeter Brune     Output Parameter:
4999c40d0f55SPeter Brune .   side - the preconditioning side, where side is one of
5000c40d0f55SPeter Brune .vb
50012d547940SBarry Smith       PC_LEFT - left preconditioning
50022d547940SBarry Smith       PC_RIGHT - right preconditioning (default for most nonlinear solvers)
5003c40d0f55SPeter Brune .ve
5004c40d0f55SPeter Brune 
5005c40d0f55SPeter Brune     Level: intermediate
5006c40d0f55SPeter Brune 
5007c40d0f55SPeter Brune .keywords: SNES, get, right, left, side, preconditioner, flag
5008c40d0f55SPeter Brune 
5009be95d8f1SBarry Smith .seealso: SNESSetNPCSide(), KSPGetPCSide()
5010c40d0f55SPeter Brune @*/
5011be95d8f1SBarry Smith PetscErrorCode  SNESGetNPCSide(SNES snes,PCSide *side)
5012c40d0f55SPeter Brune {
5013c40d0f55SPeter Brune   PetscFunctionBegin;
5014c40d0f55SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5015c40d0f55SPeter Brune   PetscValidPointer(side,2);
5016*efd4aadfSBarry Smith   *side = snes->npcside;
5017c40d0f55SPeter Brune   PetscFunctionReturn(0);
5018c40d0f55SPeter Brune }
5019c40d0f55SPeter Brune 
50209e764e56SPeter Brune /*@
50217601faf0SJed Brown   SNESSetLineSearch - Sets the linesearch on the SNES instance.
50229e764e56SPeter Brune 
50239e764e56SPeter Brune   Collective on SNES
50249e764e56SPeter Brune 
50259e764e56SPeter Brune   Input Parameters:
50269e764e56SPeter Brune + snes - iterative context obtained from SNESCreate()
50279e764e56SPeter Brune - linesearch   - the linesearch object
50289e764e56SPeter Brune 
50299e764e56SPeter Brune   Notes:
50307601faf0SJed Brown   Use SNESGetLineSearch() to retrieve the preconditioner context (for example,
50319e764e56SPeter Brune   to configure it using the API).
50329e764e56SPeter Brune 
50339e764e56SPeter Brune   Level: developer
50349e764e56SPeter Brune 
50359e764e56SPeter Brune .keywords: SNES, set, linesearch
50367601faf0SJed Brown .seealso: SNESGetLineSearch()
50379e764e56SPeter Brune @*/
50387601faf0SJed Brown PetscErrorCode SNESSetLineSearch(SNES snes, SNESLineSearch linesearch)
50399e764e56SPeter Brune {
50409e764e56SPeter Brune   PetscErrorCode ierr;
50419e764e56SPeter Brune 
50429e764e56SPeter Brune   PetscFunctionBegin;
50439e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5044f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2);
50459e764e56SPeter Brune   PetscCheckSameComm(snes, 1, linesearch, 2);
50469e764e56SPeter Brune   ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr);
5047f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr);
5048f5af7f23SKarl Rupp 
50499e764e56SPeter Brune   snes->linesearch = linesearch;
5050f5af7f23SKarl Rupp 
50513bb1ff40SBarry Smith   ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch);CHKERRQ(ierr);
50529e764e56SPeter Brune   PetscFunctionReturn(0);
50539e764e56SPeter Brune }
50549e764e56SPeter Brune 
5055a34ceb2aSJed Brown /*@
50567601faf0SJed Brown   SNESGetLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch()
50578141a3b9SPeter Brune   or creates a default line search instance associated with the SNES and returns it.
50589e764e56SPeter Brune 
50599e764e56SPeter Brune   Not Collective
50609e764e56SPeter Brune 
50619e764e56SPeter Brune   Input Parameter:
50629e764e56SPeter Brune . snes - iterative context obtained from SNESCreate()
50639e764e56SPeter Brune 
50649e764e56SPeter Brune   Output Parameter:
50659e764e56SPeter Brune . linesearch - linesearch context
50669e764e56SPeter Brune 
5067162e0bf5SPeter Brune   Level: beginner
50689e764e56SPeter Brune 
50699e764e56SPeter Brune .keywords: SNES, get, linesearch
5070162e0bf5SPeter Brune .seealso: SNESSetLineSearch(), SNESLineSearchCreate()
50719e764e56SPeter Brune @*/
50727601faf0SJed Brown PetscErrorCode SNESGetLineSearch(SNES snes, SNESLineSearch *linesearch)
50739e764e56SPeter Brune {
50749e764e56SPeter Brune   PetscErrorCode ierr;
50759e764e56SPeter Brune   const char     *optionsprefix;
50769e764e56SPeter Brune 
50779e764e56SPeter Brune   PetscFunctionBegin;
50789e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
50799e764e56SPeter Brune   PetscValidPointer(linesearch, 2);
50809e764e56SPeter Brune   if (!snes->linesearch) {
50819e764e56SPeter Brune     ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
508282f516ccSBarry Smith     ierr = SNESLineSearchCreate(PetscObjectComm((PetscObject)snes), &snes->linesearch);CHKERRQ(ierr);
5083f1c6b773SPeter Brune     ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr);
5084b1dca40bSPeter Brune     ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr);
50859e764e56SPeter Brune     ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr);
50863bb1ff40SBarry Smith     ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch);CHKERRQ(ierr);
50879e764e56SPeter Brune   }
50889e764e56SPeter Brune   *linesearch = snes->linesearch;
50899e764e56SPeter Brune   PetscFunctionReturn(0);
50909e764e56SPeter Brune }
50919e764e56SPeter Brune 
509269b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
5093c6db04a5SJed Brown #include <mex.h>
509469b4f73cSBarry Smith 
50958f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext;
50968f6e6473SBarry Smith 
50970807856dSBarry Smith /*
5098bf388a1fSBarry Smith    SNESComputeFunction_Matlab - Calls the function that has been set with SNESSetFunctionMatlab().
50990807856dSBarry Smith 
51000807856dSBarry Smith    Collective on SNES
51010807856dSBarry Smith 
51020807856dSBarry Smith    Input Parameters:
51030807856dSBarry Smith +  snes - the SNES context
51040807856dSBarry Smith -  x - input vector
51050807856dSBarry Smith 
51060807856dSBarry Smith    Output Parameter:
51070807856dSBarry Smith .  y - function vector, as set by SNESSetFunction()
51080807856dSBarry Smith 
51090807856dSBarry Smith    Notes:
51100807856dSBarry Smith    SNESComputeFunction() is typically used within nonlinear solvers
51110807856dSBarry Smith    implementations, so most users would not generally call this routine
51120807856dSBarry Smith    themselves.
51130807856dSBarry Smith 
51140807856dSBarry Smith    Level: developer
51150807856dSBarry Smith 
51160807856dSBarry Smith .keywords: SNES, nonlinear, compute, function
51170807856dSBarry Smith 
51180807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
511961b2408cSBarry Smith */
51207087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx)
51210807856dSBarry Smith {
5122e650e774SBarry Smith   PetscErrorCode    ierr;
51238f6e6473SBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext*)ctx;
51248f6e6473SBarry Smith   int               nlhs  = 1,nrhs = 5;
51258f6e6473SBarry Smith   mxArray           *plhs[1],*prhs[5];
512691621f2eSBarry Smith   long long int     lx = 0,ly = 0,ls = 0;
5127e650e774SBarry Smith 
51280807856dSBarry Smith   PetscFunctionBegin;
51290807856dSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
51300807856dSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
51310807856dSBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
51320807856dSBarry Smith   PetscCheckSameComm(snes,1,x,2);
51330807856dSBarry Smith   PetscCheckSameComm(snes,1,y,3);
51340807856dSBarry Smith 
51350807856dSBarry Smith   /* call Matlab function in ctx with arguments x and y */
5136e650e774SBarry Smith 
513791621f2eSBarry Smith   ierr    = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
5138e650e774SBarry Smith   ierr    = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
5139e650e774SBarry Smith   ierr    = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr);
514091621f2eSBarry Smith   prhs[0] = mxCreateDoubleScalar((double)ls);
514191621f2eSBarry Smith   prhs[1] = mxCreateDoubleScalar((double)lx);
514291621f2eSBarry Smith   prhs[2] = mxCreateDoubleScalar((double)ly);
51438f6e6473SBarry Smith   prhs[3] = mxCreateString(sctx->funcname);
51448f6e6473SBarry Smith   prhs[4] = sctx->ctx;
5145b807a863SBarry Smith   ierr    = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr);
5146e650e774SBarry Smith   ierr    = mxGetScalar(plhs[0]);CHKERRQ(ierr);
5147e650e774SBarry Smith   mxDestroyArray(prhs[0]);
5148e650e774SBarry Smith   mxDestroyArray(prhs[1]);
5149e650e774SBarry Smith   mxDestroyArray(prhs[2]);
51508f6e6473SBarry Smith   mxDestroyArray(prhs[3]);
5151e650e774SBarry Smith   mxDestroyArray(plhs[0]);
51520807856dSBarry Smith   PetscFunctionReturn(0);
51530807856dSBarry Smith }
51540807856dSBarry Smith 
515561b2408cSBarry Smith /*
51560807856dSBarry Smith    SNESSetFunctionMatlab - Sets the function evaluation routine and function
51570807856dSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
5158e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
51590807856dSBarry Smith 
51600807856dSBarry Smith    Logically Collective on SNES
51610807856dSBarry Smith 
51620807856dSBarry Smith    Input Parameters:
51630807856dSBarry Smith +  snes - the SNES context
51640807856dSBarry Smith .  r - vector to store function value
5165f8b49ee9SBarry Smith -  f - function evaluation routine
51660807856dSBarry Smith 
51670807856dSBarry Smith    Notes:
51680807856dSBarry Smith    The Newton-like methods typically solve linear systems of the form
51690807856dSBarry Smith $      f'(x) x = -f(x),
51700807856dSBarry Smith    where f'(x) denotes the Jacobian matrix and f(x) is the function.
51710807856dSBarry Smith 
51720807856dSBarry Smith    Level: beginner
51730807856dSBarry Smith 
5174c5b75c40SBarry Smith    Developer Note:  This bleeds the allocated memory SNESMatlabContext *sctx;
5175c5b75c40SBarry Smith 
51760807856dSBarry Smith .keywords: SNES, nonlinear, set, function
51770807856dSBarry Smith 
51780807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
517961b2408cSBarry Smith */
5180f8b49ee9SBarry Smith PetscErrorCode  SNESSetFunctionMatlab(SNES snes,Vec r,const char *f,mxArray *ctx)
51810807856dSBarry Smith {
51820807856dSBarry Smith   PetscErrorCode    ierr;
51838f6e6473SBarry Smith   SNESMatlabContext *sctx;
51840807856dSBarry Smith 
51850807856dSBarry Smith   PetscFunctionBegin;
51868f6e6473SBarry Smith   /* currently sctx is memory bleed */
5187854ce69bSBarry Smith   ierr = PetscNew(&sctx);CHKERRQ(ierr);
5188f8b49ee9SBarry Smith   ierr = PetscStrallocpy(f,&sctx->funcname);CHKERRQ(ierr);
51898f6e6473SBarry Smith   /*
51908f6e6473SBarry Smith      This should work, but it doesn't
51918f6e6473SBarry Smith   sctx->ctx = ctx;
51928f6e6473SBarry Smith   mexMakeArrayPersistent(sctx->ctx);
51938f6e6473SBarry Smith   */
51948f6e6473SBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
51958f6e6473SBarry Smith   ierr      = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr);
51960807856dSBarry Smith   PetscFunctionReturn(0);
51970807856dSBarry Smith }
519869b4f73cSBarry Smith 
519961b2408cSBarry Smith /*
5200bf388a1fSBarry Smith    SNESComputeJacobian_Matlab - Calls the function that has been set with SNESSetJacobianMatlab().
520161b2408cSBarry Smith 
520261b2408cSBarry Smith    Collective on SNES
520361b2408cSBarry Smith 
520461b2408cSBarry Smith    Input Parameters:
520561b2408cSBarry Smith +  snes - the SNES context
520661b2408cSBarry Smith .  x - input vector
520761b2408cSBarry Smith .  A, B - the matrices
520861b2408cSBarry Smith -  ctx - user context
520961b2408cSBarry Smith 
521061b2408cSBarry Smith    Level: developer
521161b2408cSBarry Smith 
521261b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function
521361b2408cSBarry Smith 
521461b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
521561b2408cSBarry Smith @*/
5216f3229a78SSatish Balay PetscErrorCode  SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat A,Mat B,void *ctx)
521761b2408cSBarry Smith {
521861b2408cSBarry Smith   PetscErrorCode    ierr;
521961b2408cSBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext*)ctx;
522061b2408cSBarry Smith   int               nlhs  = 2,nrhs = 6;
522161b2408cSBarry Smith   mxArray           *plhs[2],*prhs[6];
522261b2408cSBarry Smith   long long int     lx = 0,lA = 0,ls = 0, lB = 0;
522361b2408cSBarry Smith 
522461b2408cSBarry Smith   PetscFunctionBegin;
522561b2408cSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
522661b2408cSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
522761b2408cSBarry Smith 
522861b2408cSBarry Smith   /* call Matlab function in ctx with arguments x and y */
522961b2408cSBarry Smith 
523061b2408cSBarry Smith   ierr    = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
523161b2408cSBarry Smith   ierr    = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
523261b2408cSBarry Smith   ierr    = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr);
523361b2408cSBarry Smith   ierr    = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr);
523461b2408cSBarry Smith   prhs[0] = mxCreateDoubleScalar((double)ls);
523561b2408cSBarry Smith   prhs[1] = mxCreateDoubleScalar((double)lx);
523661b2408cSBarry Smith   prhs[2] = mxCreateDoubleScalar((double)lA);
523761b2408cSBarry Smith   prhs[3] = mxCreateDoubleScalar((double)lB);
523861b2408cSBarry Smith   prhs[4] = mxCreateString(sctx->funcname);
523961b2408cSBarry Smith   prhs[5] = sctx->ctx;
5240b807a863SBarry Smith   ierr    = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr);
524161b2408cSBarry Smith   ierr    = mxGetScalar(plhs[0]);CHKERRQ(ierr);
524261b2408cSBarry Smith   mxDestroyArray(prhs[0]);
524361b2408cSBarry Smith   mxDestroyArray(prhs[1]);
524461b2408cSBarry Smith   mxDestroyArray(prhs[2]);
524561b2408cSBarry Smith   mxDestroyArray(prhs[3]);
524661b2408cSBarry Smith   mxDestroyArray(prhs[4]);
524761b2408cSBarry Smith   mxDestroyArray(plhs[0]);
524861b2408cSBarry Smith   mxDestroyArray(plhs[1]);
524961b2408cSBarry Smith   PetscFunctionReturn(0);
525061b2408cSBarry Smith }
525161b2408cSBarry Smith 
525261b2408cSBarry Smith /*
525361b2408cSBarry Smith    SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
525461b2408cSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
5255e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
525661b2408cSBarry Smith 
525761b2408cSBarry Smith    Logically Collective on SNES
525861b2408cSBarry Smith 
525961b2408cSBarry Smith    Input Parameters:
526061b2408cSBarry Smith +  snes - the SNES context
526161b2408cSBarry Smith .  A,B - Jacobian matrices
5262f8b49ee9SBarry Smith .  J - function evaluation routine
526361b2408cSBarry Smith -  ctx - user context
526461b2408cSBarry Smith 
526561b2408cSBarry Smith    Level: developer
526661b2408cSBarry Smith 
5267c5b75c40SBarry Smith    Developer Note:  This bleeds the allocated memory SNESMatlabContext *sctx;
5268c5b75c40SBarry Smith 
526961b2408cSBarry Smith .keywords: SNES, nonlinear, set, function
527061b2408cSBarry Smith 
5271f8b49ee9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction(), J
527261b2408cSBarry Smith */
5273f8b49ee9SBarry Smith PetscErrorCode  SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *J,mxArray *ctx)
527461b2408cSBarry Smith {
527561b2408cSBarry Smith   PetscErrorCode    ierr;
527661b2408cSBarry Smith   SNESMatlabContext *sctx;
527761b2408cSBarry Smith 
527861b2408cSBarry Smith   PetscFunctionBegin;
527961b2408cSBarry Smith   /* currently sctx is memory bleed */
5280854ce69bSBarry Smith   ierr = PetscNew(&sctx);CHKERRQ(ierr);
5281f8b49ee9SBarry Smith   ierr = PetscStrallocpy(J,&sctx->funcname);CHKERRQ(ierr);
528261b2408cSBarry Smith   /*
528361b2408cSBarry Smith      This should work, but it doesn't
528461b2408cSBarry Smith   sctx->ctx = ctx;
528561b2408cSBarry Smith   mexMakeArrayPersistent(sctx->ctx);
528661b2408cSBarry Smith   */
528761b2408cSBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
528861b2408cSBarry Smith   ierr      = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
528961b2408cSBarry Smith   PetscFunctionReturn(0);
529061b2408cSBarry Smith }
529169b4f73cSBarry Smith 
5292f9eb7ae2SShri Abhyankar /*
5293f9eb7ae2SShri Abhyankar    SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab().
5294f9eb7ae2SShri Abhyankar 
5295f9eb7ae2SShri Abhyankar    Collective on SNES
5296f9eb7ae2SShri Abhyankar 
5297f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction()
5298f9eb7ae2SShri Abhyankar @*/
52997087cfbeSBarry Smith PetscErrorCode  SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx)
5300f9eb7ae2SShri Abhyankar {
5301f9eb7ae2SShri Abhyankar   PetscErrorCode    ierr;
530248f37e70SShri Abhyankar   SNESMatlabContext *sctx = (SNESMatlabContext*)ctx;
5303f9eb7ae2SShri Abhyankar   int               nlhs  = 1,nrhs = 6;
5304f9eb7ae2SShri Abhyankar   mxArray           *plhs[1],*prhs[6];
5305f9eb7ae2SShri Abhyankar   long long int     lx = 0,ls = 0;
5306f9eb7ae2SShri Abhyankar   Vec               x  = snes->vec_sol;
5307f9eb7ae2SShri Abhyankar 
5308f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
5309f9eb7ae2SShri Abhyankar   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5310f9eb7ae2SShri Abhyankar 
5311f9eb7ae2SShri Abhyankar   ierr    = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
5312f9eb7ae2SShri Abhyankar   ierr    = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
5313f9eb7ae2SShri Abhyankar   prhs[0] = mxCreateDoubleScalar((double)ls);
5314f9eb7ae2SShri Abhyankar   prhs[1] = mxCreateDoubleScalar((double)it);
5315f9eb7ae2SShri Abhyankar   prhs[2] = mxCreateDoubleScalar((double)fnorm);
5316f9eb7ae2SShri Abhyankar   prhs[3] = mxCreateDoubleScalar((double)lx);
5317f9eb7ae2SShri Abhyankar   prhs[4] = mxCreateString(sctx->funcname);
5318f9eb7ae2SShri Abhyankar   prhs[5] = sctx->ctx;
5319f9eb7ae2SShri Abhyankar   ierr    = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr);
5320f9eb7ae2SShri Abhyankar   ierr    = mxGetScalar(plhs[0]);CHKERRQ(ierr);
5321f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[0]);
5322f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[1]);
5323f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[2]);
5324f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[3]);
5325f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[4]);
5326f9eb7ae2SShri Abhyankar   mxDestroyArray(plhs[0]);
5327f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
5328f9eb7ae2SShri Abhyankar }
5329f9eb7ae2SShri Abhyankar 
5330f9eb7ae2SShri Abhyankar /*
5331e3c5b3baSBarry Smith    SNESMonitorSetMatlab - Sets the monitor function from MATLAB
5332f9eb7ae2SShri Abhyankar 
5333f9eb7ae2SShri Abhyankar    Level: developer
5334f9eb7ae2SShri Abhyankar 
5335c5b75c40SBarry Smith    Developer Note:  This bleeds the allocated memory SNESMatlabContext *sctx;
5336c5b75c40SBarry Smith 
5337f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function
5338f9eb7ae2SShri Abhyankar 
5339f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
5340f9eb7ae2SShri Abhyankar */
53416e4dcb14SBarry Smith PetscErrorCode  SNESMonitorSetMatlab(SNES snes,const char *f,mxArray *ctx)
5342f9eb7ae2SShri Abhyankar {
5343f9eb7ae2SShri Abhyankar   PetscErrorCode    ierr;
5344f9eb7ae2SShri Abhyankar   SNESMatlabContext *sctx;
5345f9eb7ae2SShri Abhyankar 
5346f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
5347f9eb7ae2SShri Abhyankar   /* currently sctx is memory bleed */
5348854ce69bSBarry Smith   ierr = PetscNew(&sctx);CHKERRQ(ierr);
53496e4dcb14SBarry Smith   ierr = PetscStrallocpy(f,&sctx->funcname);CHKERRQ(ierr);
5350f9eb7ae2SShri Abhyankar   /*
5351f9eb7ae2SShri Abhyankar      This should work, but it doesn't
5352f9eb7ae2SShri Abhyankar   sctx->ctx = ctx;
5353f9eb7ae2SShri Abhyankar   mexMakeArrayPersistent(sctx->ctx);
5354f9eb7ae2SShri Abhyankar   */
5355f9eb7ae2SShri Abhyankar   sctx->ctx = mxDuplicateArray(ctx);
53560298fd71SBarry Smith   ierr      = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,NULL);CHKERRQ(ierr);
5357f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
5358f9eb7ae2SShri Abhyankar }
5359f9eb7ae2SShri Abhyankar 
536069b4f73cSBarry Smith #endif
5361