xref: /petsc/src/snes/utils/dmsnes.c (revision 48a46eb9bd028bec07ec0f396b1a3abb43f14558)
1af0996ceSBarry Smith #include <petsc/private/snesimpl.h> /*I "petscsnes.h" I*/
2af0996ceSBarry Smith #include <petsc/private/dmimpl.h>   /*I "petscdm.h" I*/
36cab3a1bSJed Brown 
49371c9d4SSatish Balay static PetscErrorCode DMSNESUnsetFunctionContext_DMSNES(DMSNES sdm) {
5800f99ffSJeremy L Thompson   PetscFunctionBegin;
6800f99ffSJeremy L Thompson   PetscCall(PetscObjectCompose((PetscObject)sdm, "function ctx", NULL));
7800f99ffSJeremy L Thompson   sdm->functionctxcontainer = NULL;
8800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
9800f99ffSJeremy L Thompson }
10800f99ffSJeremy L Thompson 
119371c9d4SSatish Balay static PetscErrorCode DMSNESUnsetJacobianContext_DMSNES(DMSNES sdm) {
12800f99ffSJeremy L Thompson   PetscFunctionBegin;
13800f99ffSJeremy L Thompson   PetscCall(PetscObjectCompose((PetscObject)sdm, "jacobian ctx", NULL));
14800f99ffSJeremy L Thompson   sdm->jacobianctxcontainer = NULL;
15800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
16800f99ffSJeremy L Thompson }
17800f99ffSJeremy L Thompson 
189371c9d4SSatish Balay static PetscErrorCode DMSNESDestroy(DMSNES *kdm) {
196cab3a1bSJed Brown   PetscFunctionBegin;
2022c6f798SBarry Smith   if (!*kdm) PetscFunctionReturn(0);
2122c6f798SBarry Smith   PetscValidHeaderSpecific((*kdm), DMSNES_CLASSID, 1);
229371c9d4SSatish Balay   if (--((PetscObject)(*kdm))->refct > 0) {
239371c9d4SSatish Balay     *kdm = NULL;
249371c9d4SSatish Balay     PetscFunctionReturn(0);
259371c9d4SSatish Balay   }
26800f99ffSJeremy L Thompson   PetscCall(DMSNESUnsetFunctionContext_DMSNES(*kdm));
27800f99ffSJeremy L Thompson   PetscCall(DMSNESUnsetJacobianContext_DMSNES(*kdm));
289566063dSJacob Faibussowitsch   if ((*kdm)->ops->destroy) PetscCall(((*kdm)->ops->destroy)(*kdm));
299566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(kdm));
3022c6f798SBarry Smith   PetscFunctionReturn(0);
3122c6f798SBarry Smith }
3222c6f798SBarry Smith 
339371c9d4SSatish Balay PetscErrorCode DMSNESLoad(DMSNES kdm, PetscViewer viewer) {
342d53ad75SBarry Smith   PetscFunctionBegin;
359566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer, &kdm->ops->computefunction, 1, NULL, PETSC_FUNCTION));
369566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer, &kdm->ops->computejacobian, 1, NULL, PETSC_FUNCTION));
372d53ad75SBarry Smith   PetscFunctionReturn(0);
382d53ad75SBarry Smith }
392d53ad75SBarry Smith 
409371c9d4SSatish Balay PetscErrorCode DMSNESView(DMSNES kdm, PetscViewer viewer) {
412d53ad75SBarry Smith   PetscBool isascii, isbinary;
422d53ad75SBarry Smith 
432d53ad75SBarry Smith   PetscFunctionBegin;
449566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
459566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
462d53ad75SBarry Smith   if (isascii) {
474b5d3663SBarry Smith #if defined(PETSC_SERIALIZE_FUNCTIONS) && defined(PETSC_SERIALIZE_FUNCTIONS_VIEW)
482d53ad75SBarry Smith     const char *fname;
492d53ad75SBarry Smith 
509566063dSJacob Faibussowitsch     PetscCall(PetscFPTFind(kdm->ops->computefunction, &fname));
51*48a46eb9SPierre Jolivet     if (fname) PetscCall(PetscViewerASCIIPrintf(viewer, "Function used by SNES: %s\n", fname));
529566063dSJacob Faibussowitsch     PetscCall(PetscFPTFind(kdm->ops->computejacobian, &fname));
53*48a46eb9SPierre Jolivet     if (fname) PetscCall(PetscViewerASCIIPrintf(viewer, "Jacobian function used by SNES: %s\n", fname));
54c7a10e08SBarry Smith #endif
552d53ad75SBarry Smith   } else if (isbinary) {
563964eb88SJed Brown     struct {
573964eb88SJed Brown       PetscErrorCode (*func)(SNES, Vec, Vec, void *);
589200755eSBarry Smith     } funcstruct;
599200755eSBarry Smith     struct {
60d1e9a80fSBarry Smith       PetscErrorCode (*jac)(SNES, Vec, Mat, Mat, void *);
619200755eSBarry Smith     } jacstruct;
629200755eSBarry Smith     funcstruct.func = kdm->ops->computefunction;
639200755eSBarry Smith     jacstruct.jac   = kdm->ops->computejacobian;
649566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWrite(viewer, &funcstruct, 1, PETSC_FUNCTION));
659566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWrite(viewer, &jacstruct, 1, PETSC_FUNCTION));
662d53ad75SBarry Smith   }
672d53ad75SBarry Smith   PetscFunctionReturn(0);
682d53ad75SBarry Smith }
692d53ad75SBarry Smith 
709371c9d4SSatish Balay static PetscErrorCode DMSNESCreate(MPI_Comm comm, DMSNES *kdm) {
7122c6f798SBarry Smith   PetscFunctionBegin;
729566063dSJacob Faibussowitsch   PetscCall(SNESInitializePackage());
739566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(*kdm, DMSNES_CLASSID, "DMSNES", "DMSNES", "DMSNES", comm, DMSNESDestroy, DMSNESView));
746cab3a1bSJed Brown   PetscFunctionReturn(0);
756cab3a1bSJed Brown }
766cab3a1bSJed Brown 
77942e3340SBarry Smith /* Attaches the DMSNES to the coarse level.
786cab3a1bSJed Brown  * Under what conditions should we copy versus duplicate?
796cab3a1bSJed Brown  */
809371c9d4SSatish Balay static PetscErrorCode DMCoarsenHook_DMSNES(DM dm, DM dmc, void *ctx) {
816cab3a1bSJed Brown   PetscFunctionBegin;
829566063dSJacob Faibussowitsch   PetscCall(DMCopyDMSNES(dm, dmc));
836cab3a1bSJed Brown   PetscFunctionReturn(0);
846cab3a1bSJed Brown }
856cab3a1bSJed Brown 
86dfe15315SJed Brown /* This could restrict auxiliary information to the coarse level.
87caa4e7f2SJed Brown  */
889371c9d4SSatish Balay static PetscErrorCode DMRestrictHook_DMSNES(DM dm, Mat Restrict, Vec rscale, Mat Inject, DM dmc, void *ctx) {
89caa4e7f2SJed Brown   PetscFunctionBegin;
90caa4e7f2SJed Brown   PetscFunctionReturn(0);
91caa4e7f2SJed Brown }
92caa4e7f2SJed Brown 
93be081cd6SPeter Brune /* Attaches the DMSNES to the subdomain. */
949371c9d4SSatish Balay static PetscErrorCode DMSubDomainHook_DMSNES(DM dm, DM subdm, void *ctx) {
95be081cd6SPeter Brune   PetscFunctionBegin;
969566063dSJacob Faibussowitsch   PetscCall(DMCopyDMSNES(dm, subdm));
97be081cd6SPeter Brune   PetscFunctionReturn(0);
98be081cd6SPeter Brune }
99be081cd6SPeter Brune 
100be081cd6SPeter Brune /* This could restrict auxiliary information to the coarse level.
101be081cd6SPeter Brune  */
1029371c9d4SSatish Balay static PetscErrorCode DMSubDomainRestrictHook_DMSNES(DM dm, VecScatter gscat, VecScatter lscat, DM subdm, void *ctx) {
103be081cd6SPeter Brune   PetscFunctionBegin;
104be081cd6SPeter Brune   PetscFunctionReturn(0);
105be081cd6SPeter Brune }
106be081cd6SPeter Brune 
1079371c9d4SSatish Balay static PetscErrorCode DMRefineHook_DMSNES(DM dm, DM dmf, void *ctx) {
10803a0fabfSPeter Brune   PetscFunctionBegin;
1099566063dSJacob Faibussowitsch   PetscCall(DMCopyDMSNES(dm, dmf));
11003a0fabfSPeter Brune   PetscFunctionReturn(0);
11103a0fabfSPeter Brune }
11203a0fabfSPeter Brune 
11303a0fabfSPeter Brune /* This could restrict auxiliary information to the coarse level.
11403a0fabfSPeter Brune  */
1159371c9d4SSatish Balay static PetscErrorCode DMInterpolateHook_DMSNES(DM dm, Mat Interp, DM dmf, void *ctx) {
11603a0fabfSPeter Brune   PetscFunctionBegin;
11703a0fabfSPeter Brune   PetscFunctionReturn(0);
11803a0fabfSPeter Brune }
11903a0fabfSPeter Brune 
12022c6f798SBarry Smith /*@C
12122c6f798SBarry Smith    DMSNESCopy - copies the information in a DMSNES to another DMSNES
12222c6f798SBarry Smith 
12322c6f798SBarry Smith    Not Collective
12422c6f798SBarry Smith 
1254165533cSJose E. Roman    Input Parameters:
12622c6f798SBarry Smith +  kdm - Original DMSNES
12722c6f798SBarry Smith -  nkdm - DMSNES to receive the data, should have been created with DMSNESCreate()
12822c6f798SBarry Smith 
12922c6f798SBarry Smith    Level: developer
13022c6f798SBarry Smith 
131db781477SPatrick Sanan .seealso: `DMSNESCreate()`, `DMSNESDestroy()`
13222c6f798SBarry Smith @*/
1339371c9d4SSatish Balay PetscErrorCode DMSNESCopy(DMSNES kdm, DMSNES nkdm) {
13422c6f798SBarry Smith   PetscFunctionBegin;
13522c6f798SBarry Smith   PetscValidHeaderSpecific(kdm, DMSNES_CLASSID, 1);
13622c6f798SBarry Smith   PetscValidHeaderSpecific(nkdm, DMSNES_CLASSID, 2);
13722c6f798SBarry Smith   nkdm->ops->computefunction  = kdm->ops->computefunction;
1382bc4d0c4SPeter Brune   nkdm->ops->computejacobian  = kdm->ops->computejacobian;
13922c6f798SBarry Smith   nkdm->ops->computegs        = kdm->ops->computegs;
14022c6f798SBarry Smith   nkdm->ops->computeobjective = kdm->ops->computeobjective;
14122c6f798SBarry Smith   nkdm->ops->computepjacobian = kdm->ops->computepjacobian;
14222c6f798SBarry Smith   nkdm->ops->computepfunction = kdm->ops->computepfunction;
14322c6f798SBarry Smith   nkdm->ops->destroy          = kdm->ops->destroy;
14422c6f798SBarry Smith   nkdm->ops->duplicate        = kdm->ops->duplicate;
14522c6f798SBarry Smith 
14622c6f798SBarry Smith   nkdm->gsctx                = kdm->gsctx;
14722c6f798SBarry Smith   nkdm->pctx                 = kdm->pctx;
14822c6f798SBarry Smith   nkdm->objectivectx         = kdm->objectivectx;
149af903c1dSJunchao Zhang   nkdm->originaldm           = kdm->originaldm;
150800f99ffSJeremy L Thompson   nkdm->functionctxcontainer = kdm->functionctxcontainer;
151800f99ffSJeremy L Thompson   nkdm->jacobianctxcontainer = kdm->jacobianctxcontainer;
152800f99ffSJeremy L Thompson   if (nkdm->functionctxcontainer) PetscCall(PetscObjectCompose((PetscObject)nkdm, "function ctx", (PetscObject)nkdm->functionctxcontainer));
153800f99ffSJeremy L Thompson   if (nkdm->jacobianctxcontainer) PetscCall(PetscObjectCompose((PetscObject)nkdm, "jacobian ctx", (PetscObject)nkdm->jacobianctxcontainer));
15422c6f798SBarry Smith 
15522c6f798SBarry Smith   /*
15622c6f798SBarry Smith   nkdm->fortran_func_pointers[0] = kdm->fortran_func_pointers[0];
15722c6f798SBarry Smith   nkdm->fortran_func_pointers[1] = kdm->fortran_func_pointers[1];
15822c6f798SBarry Smith   nkdm->fortran_func_pointers[2] = kdm->fortran_func_pointers[2];
15922c6f798SBarry Smith   */
16022c6f798SBarry Smith 
16122c6f798SBarry Smith   /* implementation specific copy hooks */
162dbbe0bcdSBarry Smith   PetscTryTypeMethod(kdm, duplicate, nkdm);
16322c6f798SBarry Smith   PetscFunctionReturn(0);
16422c6f798SBarry Smith }
16522c6f798SBarry Smith 
1666cab3a1bSJed Brown /*@C
167942e3340SBarry Smith    DMGetDMSNES - get read-only private DMSNES context from a DM
1686cab3a1bSJed Brown 
1696cab3a1bSJed Brown    Not Collective
1706cab3a1bSJed Brown 
1714165533cSJose E. Roman    Input Parameter:
1726cab3a1bSJed Brown .  dm - DM to be used with SNES
1736cab3a1bSJed Brown 
1744165533cSJose E. Roman    Output Parameter:
175942e3340SBarry Smith .  snesdm - private DMSNES context
1766cab3a1bSJed Brown 
1776cab3a1bSJed Brown    Level: developer
1786cab3a1bSJed Brown 
1796cab3a1bSJed Brown    Notes:
180942e3340SBarry Smith    Use DMGetDMSNESWrite() if write access is needed. The DMSNESSetXXX API should be used wherever possible.
1816cab3a1bSJed Brown 
182db781477SPatrick Sanan .seealso: `DMGetDMSNESWrite()`
1836cab3a1bSJed Brown @*/
1849371c9d4SSatish Balay PetscErrorCode DMGetDMSNES(DM dm, DMSNES *snesdm) {
1856cab3a1bSJed Brown   PetscFunctionBegin;
1866cab3a1bSJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
187b4615a05SBarry Smith   *snesdm = (DMSNES)dm->dmsnes;
18822c6f798SBarry Smith   if (!*snesdm) {
1899566063dSJacob Faibussowitsch     PetscCall(PetscInfo(dm, "Creating new DMSNES\n"));
1909566063dSJacob Faibussowitsch     PetscCall(DMSNESCreate(PetscObjectComm((PetscObject)dm), snesdm));
1911aa26658SKarl Rupp 
192b4615a05SBarry Smith     dm->dmsnes            = (PetscObject)*snesdm;
193af903c1dSJunchao Zhang     (*snesdm)->originaldm = dm;
1949566063dSJacob Faibussowitsch     PetscCall(DMCoarsenHookAdd(dm, DMCoarsenHook_DMSNES, DMRestrictHook_DMSNES, NULL));
1959566063dSJacob Faibussowitsch     PetscCall(DMRefineHookAdd(dm, DMRefineHook_DMSNES, DMInterpolateHook_DMSNES, NULL));
1969566063dSJacob Faibussowitsch     PetscCall(DMSubDomainHookAdd(dm, DMSubDomainHook_DMSNES, DMSubDomainRestrictHook_DMSNES, NULL));
1976cab3a1bSJed Brown   }
1986cab3a1bSJed Brown   PetscFunctionReturn(0);
1996cab3a1bSJed Brown }
2006cab3a1bSJed Brown 
2016cab3a1bSJed Brown /*@C
202942e3340SBarry Smith    DMGetDMSNESWrite - get write access to private DMSNES context from a DM
2036cab3a1bSJed Brown 
2046cab3a1bSJed Brown    Not Collective
2056cab3a1bSJed Brown 
2064165533cSJose E. Roman    Input Parameter:
2076cab3a1bSJed Brown .  dm - DM to be used with SNES
2086cab3a1bSJed Brown 
2094165533cSJose E. Roman    Output Parameter:
210942e3340SBarry Smith .  snesdm - private DMSNES context
2116cab3a1bSJed Brown 
2126cab3a1bSJed Brown    Level: developer
2136cab3a1bSJed Brown 
214db781477SPatrick Sanan .seealso: `DMGetDMSNES()`
2156cab3a1bSJed Brown @*/
2169371c9d4SSatish Balay PetscErrorCode DMGetDMSNESWrite(DM dm, DMSNES *snesdm) {
217942e3340SBarry Smith   DMSNES sdm;
2186cab3a1bSJed Brown 
2196cab3a1bSJed Brown   PetscFunctionBegin;
2206cab3a1bSJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2219566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(dm, &sdm));
22228b400f6SJacob Faibussowitsch   PetscCheck(sdm->originaldm, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "DMSNES has a NULL originaldm");
2236cab3a1bSJed Brown   if (sdm->originaldm != dm) { /* Copy on write */
224b4615a05SBarry Smith     DMSNES oldsdm = sdm;
2259566063dSJacob Faibussowitsch     PetscCall(PetscInfo(dm, "Copying DMSNES due to write\n"));
2269566063dSJacob Faibussowitsch     PetscCall(DMSNESCreate(PetscObjectComm((PetscObject)dm), &sdm));
2279566063dSJacob Faibussowitsch     PetscCall(DMSNESCopy(oldsdm, sdm));
2289566063dSJacob Faibussowitsch     PetscCall(DMSNESDestroy((DMSNES *)&dm->dmsnes));
229b4615a05SBarry Smith     dm->dmsnes      = (PetscObject)sdm;
230af903c1dSJunchao Zhang     sdm->originaldm = dm;
2316cab3a1bSJed Brown   }
2326cab3a1bSJed Brown   *snesdm = sdm;
2336cab3a1bSJed Brown   PetscFunctionReturn(0);
2346cab3a1bSJed Brown }
2356cab3a1bSJed Brown 
2366cab3a1bSJed Brown /*@C
237942e3340SBarry Smith    DMCopyDMSNES - copies a DM context to a new DM
2386cab3a1bSJed Brown 
2396cab3a1bSJed Brown    Logically Collective
2406cab3a1bSJed Brown 
2414165533cSJose E. Roman    Input Parameters:
2426cab3a1bSJed Brown +  dmsrc - DM to obtain context from
2436cab3a1bSJed Brown -  dmdest - DM to add context to
2446cab3a1bSJed Brown 
2456cab3a1bSJed Brown    Level: developer
2466cab3a1bSJed Brown 
2476cab3a1bSJed Brown    Note:
2486cab3a1bSJed Brown    The context is copied by reference. This function does not ensure that a context exists.
2496cab3a1bSJed Brown 
250db781477SPatrick Sanan .seealso: `DMGetDMSNES()`, `SNESSetDM()`
2516cab3a1bSJed Brown @*/
2529371c9d4SSatish Balay PetscErrorCode DMCopyDMSNES(DM dmsrc, DM dmdest) {
2536cab3a1bSJed Brown   PetscFunctionBegin;
2546cab3a1bSJed Brown   PetscValidHeaderSpecific(dmsrc, DM_CLASSID, 1);
2556cab3a1bSJed Brown   PetscValidHeaderSpecific(dmdest, DM_CLASSID, 2);
2569566063dSJacob Faibussowitsch   if (!dmdest->dmsnes) PetscCall(DMSNESCreate(PetscObjectComm((PetscObject)dmdest), (DMSNES *)&dmdest->dmsnes));
2579566063dSJacob Faibussowitsch   PetscCall(DMSNESCopy((DMSNES)dmsrc->dmsnes, (DMSNES)dmdest->dmsnes));
2589566063dSJacob Faibussowitsch   PetscCall(DMCoarsenHookAdd(dmdest, DMCoarsenHook_DMSNES, NULL, NULL));
2599566063dSJacob Faibussowitsch   PetscCall(DMRefineHookAdd(dmdest, DMRefineHook_DMSNES, NULL, NULL));
2609566063dSJacob Faibussowitsch   PetscCall(DMSubDomainHookAdd(dmdest, DMSubDomainHook_DMSNES, DMSubDomainRestrictHook_DMSNES, NULL));
2616cab3a1bSJed Brown   PetscFunctionReturn(0);
2626cab3a1bSJed Brown }
2636cab3a1bSJed Brown 
2646cab3a1bSJed Brown /*@C
2656cab3a1bSJed Brown    DMSNESSetFunction - set SNES residual evaluation function
2666cab3a1bSJed Brown 
2676cab3a1bSJed Brown    Not Collective
2686cab3a1bSJed Brown 
2694165533cSJose E. Roman    Input Parameters:
2706cab3a1bSJed Brown +  dm - DM to be used with SNES
271f8b49ee9SBarry Smith .  f - residual evaluation function; see SNESFunction for details
2726cab3a1bSJed Brown -  ctx - context for residual evaluation
2736cab3a1bSJed Brown 
2746cab3a1bSJed Brown    Level: advanced
2756cab3a1bSJed Brown 
2766cab3a1bSJed Brown    Note:
2776cab3a1bSJed Brown    SNESSetFunction() is normally used, but it calls this function internally because the user context is actually
2786cab3a1bSJed Brown    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
2796cab3a1bSJed Brown    not. If DM took a more central role at some later date, this could become the primary method of setting the residual.
2806cab3a1bSJed Brown 
281db781477SPatrick Sanan .seealso: `DMSNESSetContext()`, `SNESSetFunction()`, `DMSNESSetJacobian()`, `SNESFunction`
2826cab3a1bSJed Brown @*/
2839371c9d4SSatish Balay PetscErrorCode DMSNESSetFunction(DM dm, PetscErrorCode (*f)(SNES, Vec, Vec, void *), void *ctx) {
284942e3340SBarry Smith   DMSNES sdm;
2856cab3a1bSJed Brown 
2866cab3a1bSJed Brown   PetscFunctionBegin;
2876cab3a1bSJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2889566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNESWrite(dm, &sdm));
289f8b49ee9SBarry Smith   if (f) sdm->ops->computefunction = f;
290800f99ffSJeremy L Thompson   if (ctx) {
291800f99ffSJeremy L Thompson     PetscContainer ctxcontainer;
292800f99ffSJeremy L Thompson     PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)sdm), &ctxcontainer));
293800f99ffSJeremy L Thompson     PetscCall(PetscContainerSetPointer(ctxcontainer, ctx));
294800f99ffSJeremy L Thompson     PetscCall(PetscObjectCompose((PetscObject)sdm, "function ctx", (PetscObject)ctxcontainer));
295800f99ffSJeremy L Thompson     sdm->functionctxcontainer = ctxcontainer;
296800f99ffSJeremy L Thompson     PetscCall(PetscContainerDestroy(&ctxcontainer));
297800f99ffSJeremy L Thompson   }
298800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
299800f99ffSJeremy L Thompson }
300800f99ffSJeremy L Thompson 
301800f99ffSJeremy L Thompson /*@C
3025cb80ecdSBarry Smith    DMSNESSetFunctionContextDestroy - set `SNES` residual evaluation context destroy function
303800f99ffSJeremy L Thompson 
304800f99ffSJeremy L Thompson    Not Collective
305800f99ffSJeremy L Thompson 
306800f99ffSJeremy L Thompson    Input Parameters:
3075cb80ecdSBarry Smith +  dm - `DM` to be used with `SNES`
3085cb80ecdSBarry Smith -  f - residual evaluation context destroy function
309800f99ffSJeremy L Thompson 
310800f99ffSJeremy L Thompson    Level: advanced
311800f99ffSJeremy L Thompson 
312800f99ffSJeremy L Thompson .seealso: `DMSNESSetFunction()`, `SNESSetFunction()`
313800f99ffSJeremy L Thompson @*/
3149371c9d4SSatish Balay PetscErrorCode DMSNESSetFunctionContextDestroy(DM dm, PetscErrorCode (*f)(void *)) {
315800f99ffSJeremy L Thompson   DMSNES sdm;
316800f99ffSJeremy L Thompson 
317800f99ffSJeremy L Thompson   PetscFunctionBegin;
318800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
319800f99ffSJeremy L Thompson   PetscCall(DMGetDMSNESWrite(dm, &sdm));
320800f99ffSJeremy L Thompson   if (sdm->functionctxcontainer) PetscCall(PetscContainerSetUserDestroy(sdm->functionctxcontainer, f));
321800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
322800f99ffSJeremy L Thompson }
323800f99ffSJeremy L Thompson 
3249371c9d4SSatish Balay PetscErrorCode DMSNESUnsetFunctionContext_Internal(DM dm) {
325800f99ffSJeremy L Thompson   DMSNES sdm;
326800f99ffSJeremy L Thompson 
327800f99ffSJeremy L Thompson   PetscFunctionBegin;
328800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
329800f99ffSJeremy L Thompson   PetscCall(DMGetDMSNESWrite(dm, &sdm));
330800f99ffSJeremy L Thompson   PetscCall(DMSNESUnsetFunctionContext_DMSNES(sdm));
3316cab3a1bSJed Brown   PetscFunctionReturn(0);
3326cab3a1bSJed Brown }
3336cab3a1bSJed Brown 
3346cab3a1bSJed Brown /*@C
335bbc1464cSBarry Smith    DMSNESSetMFFunction - set SNES residual evaluation function used in applying the matrix-free Jacobian with -snes_mf_operator
336bbc1464cSBarry Smith 
337bbc1464cSBarry Smith    Logically Collective on dm
338bbc1464cSBarry Smith 
3394165533cSJose E. Roman    Input Parameters:
340bbc1464cSBarry Smith +  dm - DM to be used with SNES
341bbc1464cSBarry Smith -  f - residual evaluation function; see SNESFunction for details
342bbc1464cSBarry Smith 
343bbc1464cSBarry Smith    Level: advanced
344bbc1464cSBarry Smith 
345db781477SPatrick Sanan .seealso: `DMSNESSetContext()`, `SNESSetFunction()`, `DMSNESSetJacobian()`, `SNESFunction`, `DMSNESSetFunction()`
346bbc1464cSBarry Smith @*/
3479371c9d4SSatish Balay PetscErrorCode DMSNESSetMFFunction(DM dm, PetscErrorCode (*f)(SNES, Vec, Vec, void *), void *ctx) {
348bbc1464cSBarry Smith   DMSNES sdm;
349bbc1464cSBarry Smith 
350bbc1464cSBarry Smith   PetscFunctionBegin;
351bbc1464cSBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
352*48a46eb9SPierre Jolivet   if (f || ctx) PetscCall(DMGetDMSNESWrite(dm, &sdm));
353bbc1464cSBarry Smith   if (f) sdm->ops->computemffunction = f;
354bbc1464cSBarry Smith   if (ctx) sdm->mffunctionctx = ctx;
355bbc1464cSBarry Smith   PetscFunctionReturn(0);
356bbc1464cSBarry Smith }
357bbc1464cSBarry Smith 
358bbc1464cSBarry Smith /*@C
3596cab3a1bSJed Brown    DMSNESGetFunction - get SNES residual evaluation function
3606cab3a1bSJed Brown 
3616cab3a1bSJed Brown    Not Collective
3626cab3a1bSJed Brown 
3634165533cSJose E. Roman    Input Parameter:
3646cab3a1bSJed Brown .  dm - DM to be used with SNES
3656cab3a1bSJed Brown 
3664165533cSJose E. Roman    Output Parameters:
367f8b49ee9SBarry Smith +  f - residual evaluation function; see SNESFunction for details
3686cab3a1bSJed Brown -  ctx - context for residual evaluation
3696cab3a1bSJed Brown 
3706cab3a1bSJed Brown    Level: advanced
3716cab3a1bSJed Brown 
3726cab3a1bSJed Brown    Note:
3736cab3a1bSJed Brown    SNESGetFunction() is normally used, but it calls this function internally because the user context is actually
3746cab3a1bSJed Brown    associated with the DM.
3756cab3a1bSJed Brown 
376db781477SPatrick Sanan .seealso: `DMSNESSetContext()`, `DMSNESSetFunction()`, `SNESSetFunction()`, `SNESFunction`
3776cab3a1bSJed Brown @*/
3789371c9d4SSatish Balay PetscErrorCode DMSNESGetFunction(DM dm, PetscErrorCode (**f)(SNES, Vec, Vec, void *), void **ctx) {
379942e3340SBarry Smith   DMSNES sdm;
3806cab3a1bSJed Brown 
3816cab3a1bSJed Brown   PetscFunctionBegin;
3826cab3a1bSJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3839566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(dm, &sdm));
384f8b49ee9SBarry Smith   if (f) *f = sdm->ops->computefunction;
385800f99ffSJeremy L Thompson   if (ctx) {
386800f99ffSJeremy L Thompson     if (sdm->functionctxcontainer) PetscCall(PetscContainerGetPointer(sdm->functionctxcontainer, ctx));
387800f99ffSJeremy L Thompson     else *ctx = NULL;
388800f99ffSJeremy L Thompson   }
3896cab3a1bSJed Brown   PetscFunctionReturn(0);
3906cab3a1bSJed Brown }
3916cab3a1bSJed Brown 
3922a4ee8f2SPeter Brune /*@C
393081a7dcdSPeter Brune    DMSNESSetObjective - set SNES objective evaluation function
3942a4ee8f2SPeter Brune 
3952a4ee8f2SPeter Brune    Not Collective
3962a4ee8f2SPeter Brune 
3974165533cSJose E. Roman    Input Parameters:
3982a4ee8f2SPeter Brune +  dm - DM to be used with SNES
399f8b49ee9SBarry Smith .  obj - objective evaluation function; see SNESObjectiveFunction for details
4002a4ee8f2SPeter Brune -  ctx - context for residual evaluation
4012a4ee8f2SPeter Brune 
4022a4ee8f2SPeter Brune    Level: advanced
4032a4ee8f2SPeter Brune 
404db781477SPatrick Sanan .seealso: `DMSNESSetContext()`, `SNESGetObjective()`, `DMSNESSetFunction()`
4052a4ee8f2SPeter Brune @*/
4069371c9d4SSatish Balay PetscErrorCode DMSNESSetObjective(DM dm, PetscErrorCode (*obj)(SNES, Vec, PetscReal *, void *), void *ctx) {
407942e3340SBarry Smith   DMSNES sdm;
4082a4ee8f2SPeter Brune 
4092a4ee8f2SPeter Brune   PetscFunctionBegin;
4102a4ee8f2SPeter Brune   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
411*48a46eb9SPierre Jolivet   if (obj || ctx) PetscCall(DMGetDMSNESWrite(dm, &sdm));
412f8b49ee9SBarry Smith   if (obj) sdm->ops->computeobjective = obj;
4132a4ee8f2SPeter Brune   if (ctx) sdm->objectivectx = ctx;
4142a4ee8f2SPeter Brune   PetscFunctionReturn(0);
4152a4ee8f2SPeter Brune }
4162a4ee8f2SPeter Brune 
4172a4ee8f2SPeter Brune /*@C
4182a4ee8f2SPeter Brune    DMSNESGetObjective - get SNES objective evaluation function
4192a4ee8f2SPeter Brune 
4202a4ee8f2SPeter Brune    Not Collective
4212a4ee8f2SPeter Brune 
4224165533cSJose E. Roman    Input Parameter:
4232a4ee8f2SPeter Brune .  dm - DM to be used with SNES
4242a4ee8f2SPeter Brune 
4254165533cSJose E. Roman    Output Parameters:
426f8b49ee9SBarry Smith +  obj- residual evaluation function; see SNESObjectiveFunction for details
4272a4ee8f2SPeter Brune -  ctx - context for residual evaluation
4282a4ee8f2SPeter Brune 
4292a4ee8f2SPeter Brune    Level: advanced
4302a4ee8f2SPeter Brune 
4312a4ee8f2SPeter Brune    Note:
4322a4ee8f2SPeter Brune    SNESGetFunction() is normally used, but it calls this function internally because the user context is actually
4332a4ee8f2SPeter Brune    associated with the DM.
4342a4ee8f2SPeter Brune 
435db781477SPatrick Sanan .seealso: `DMSNESSetContext()`, `DMSNESSetObjective()`, `SNESSetFunction()`
4362a4ee8f2SPeter Brune @*/
4379371c9d4SSatish Balay PetscErrorCode DMSNESGetObjective(DM dm, PetscErrorCode (**obj)(SNES, Vec, PetscReal *, void *), void **ctx) {
438942e3340SBarry Smith   DMSNES sdm;
4392a4ee8f2SPeter Brune 
4402a4ee8f2SPeter Brune   PetscFunctionBegin;
4412a4ee8f2SPeter Brune   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4429566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(dm, &sdm));
443f8b49ee9SBarry Smith   if (obj) *obj = sdm->ops->computeobjective;
4442a4ee8f2SPeter Brune   if (ctx) *ctx = sdm->objectivectx;
4452a4ee8f2SPeter Brune   PetscFunctionReturn(0);
4462a4ee8f2SPeter Brune }
4472a4ee8f2SPeter Brune 
4486cab3a1bSJed Brown /*@C
449be95d8f1SBarry Smith    DMSNESSetNGS - set SNES Gauss-Seidel relaxation function
4506cab3a1bSJed Brown 
4516cab3a1bSJed Brown    Not Collective
4526cab3a1bSJed Brown 
4534165533cSJose E. Roman    Input Parameters:
4546cab3a1bSJed Brown +  dm - DM to be used with SNES
455be95d8f1SBarry Smith .  f  - relaxation function, see SNESGSFunction
4566cab3a1bSJed Brown -  ctx - context for residual evaluation
4576cab3a1bSJed Brown 
4586cab3a1bSJed Brown    Level: advanced
4596cab3a1bSJed Brown 
4606cab3a1bSJed Brown    Note:
461be95d8f1SBarry Smith    SNESSetNGS() is normally used, but it calls this function internally because the user context is actually
4626cab3a1bSJed Brown    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
4636cab3a1bSJed Brown    not. If DM took a more central role at some later date, this could become the primary method of setting the residual.
4646cab3a1bSJed Brown 
465db781477SPatrick Sanan .seealso: `DMSNESSetContext()`, `SNESSetFunction()`, `DMSNESSetJacobian()`, `DMSNESSetFunction()`, `SNESGSFunction`
4666cab3a1bSJed Brown @*/
4679371c9d4SSatish Balay PetscErrorCode DMSNESSetNGS(DM dm, PetscErrorCode (*f)(SNES, Vec, Vec, void *), void *ctx) {
468942e3340SBarry Smith   DMSNES sdm;
4696cab3a1bSJed Brown 
4706cab3a1bSJed Brown   PetscFunctionBegin;
4716cab3a1bSJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
472*48a46eb9SPierre Jolivet   if (f || ctx) PetscCall(DMGetDMSNESWrite(dm, &sdm));
473be95d8f1SBarry Smith   if (f) sdm->ops->computegs = f;
4746cab3a1bSJed Brown   if (ctx) sdm->gsctx = ctx;
4756cab3a1bSJed Brown   PetscFunctionReturn(0);
4766cab3a1bSJed Brown }
4776cab3a1bSJed Brown 
4786cab3a1bSJed Brown /*@C
479be95d8f1SBarry Smith    DMSNESGetNGS - get SNES Gauss-Seidel relaxation function
4806cab3a1bSJed Brown 
4816cab3a1bSJed Brown    Not Collective
4826cab3a1bSJed Brown 
4834165533cSJose E. Roman    Input Parameter:
4846cab3a1bSJed Brown .  dm - DM to be used with SNES
4856cab3a1bSJed Brown 
4864165533cSJose E. Roman    Output Parameters:
487be95d8f1SBarry Smith +  f - relaxation function which performs Gauss-Seidel sweeps, see SNESGSFunction
4886cab3a1bSJed Brown -  ctx - context for residual evaluation
4896cab3a1bSJed Brown 
4906cab3a1bSJed Brown    Level: advanced
4916cab3a1bSJed Brown 
4926cab3a1bSJed Brown    Note:
493be95d8f1SBarry Smith    SNESGetNGS() is normally used, but it calls this function internally because the user context is actually
4946cab3a1bSJed Brown    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
4956cab3a1bSJed Brown    not. If DM took a more central role at some later date, this could become the primary method of setting the residual.
4966cab3a1bSJed Brown 
497db781477SPatrick Sanan .seealso: `DMSNESSetContext()`, `SNESGetNGS()`, `DMSNESGetJacobian()`, `DMSNESGetFunction()`, `SNESNGSFunction`
4986cab3a1bSJed Brown @*/
4999371c9d4SSatish Balay PetscErrorCode DMSNESGetNGS(DM dm, PetscErrorCode (**f)(SNES, Vec, Vec, void *), void **ctx) {
500942e3340SBarry Smith   DMSNES sdm;
5016cab3a1bSJed Brown 
5026cab3a1bSJed Brown   PetscFunctionBegin;
5036cab3a1bSJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5049566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(dm, &sdm));
505be95d8f1SBarry Smith   if (f) *f = sdm->ops->computegs;
5066cab3a1bSJed Brown   if (ctx) *ctx = sdm->gsctx;
5076cab3a1bSJed Brown   PetscFunctionReturn(0);
5086cab3a1bSJed Brown }
5096cab3a1bSJed Brown 
5106cab3a1bSJed Brown /*@C
511ecfdb398SPeter Brune    DMSNESSetJacobian - set SNES Jacobian evaluation function
5126cab3a1bSJed Brown 
5136cab3a1bSJed Brown    Not Collective
5146cab3a1bSJed Brown 
5154165533cSJose E. Roman    Input Parameters:
5166cab3a1bSJed Brown +  dm - DM to be used with SNES
517f8b49ee9SBarry Smith .  J - Jacobian evaluation function
5186cab3a1bSJed Brown -  ctx - context for residual evaluation
5196cab3a1bSJed Brown 
5206cab3a1bSJed Brown    Level: advanced
5216cab3a1bSJed Brown 
5226cab3a1bSJed Brown    Note:
5236cab3a1bSJed Brown    SNESSetJacobian() is normally used, but it calls this function internally because the user context is actually
5246cab3a1bSJed Brown    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
5256cab3a1bSJed Brown    not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian.
5266cab3a1bSJed Brown 
527db781477SPatrick Sanan .seealso: `DMSNESSetContext()`, `SNESSetFunction()`, `DMSNESGetJacobian()`, `SNESSetJacobian()`, `SNESJacobianFunction`
5286cab3a1bSJed Brown @*/
5299371c9d4SSatish Balay PetscErrorCode DMSNESSetJacobian(DM dm, PetscErrorCode (*J)(SNES, Vec, Mat, Mat, void *), void *ctx) {
530942e3340SBarry Smith   DMSNES sdm;
5316cab3a1bSJed Brown 
5326cab3a1bSJed Brown   PetscFunctionBegin;
5336cab3a1bSJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
534800f99ffSJeremy L Thompson   if (J || ctx) PetscCall(DMGetDMSNESWrite(dm, &sdm));
535f8b49ee9SBarry Smith   if (J) sdm->ops->computejacobian = J;
536800f99ffSJeremy L Thompson   if (ctx) {
537800f99ffSJeremy L Thompson     PetscContainer ctxcontainer;
538800f99ffSJeremy L Thompson     PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)sdm), &ctxcontainer));
539800f99ffSJeremy L Thompson     PetscCall(PetscContainerSetPointer(ctxcontainer, ctx));
540800f99ffSJeremy L Thompson     PetscCall(PetscObjectCompose((PetscObject)sdm, "jacobian ctx", (PetscObject)ctxcontainer));
541800f99ffSJeremy L Thompson     sdm->jacobianctxcontainer = ctxcontainer;
542800f99ffSJeremy L Thompson     PetscCall(PetscContainerDestroy(&ctxcontainer));
543800f99ffSJeremy L Thompson   }
544800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
545800f99ffSJeremy L Thompson }
546800f99ffSJeremy L Thompson 
547800f99ffSJeremy L Thompson /*@C
5485cb80ecdSBarry Smith    DMSNESSetJacobianContextDestroy - set `SNES` Jacobian evaluation context destroy function
549800f99ffSJeremy L Thompson 
550800f99ffSJeremy L Thompson    Not Collective
551800f99ffSJeremy L Thompson 
552800f99ffSJeremy L Thompson    Input Parameters:
5535cb80ecdSBarry Smith +  dm - `DM` to be used with `SNES`
5545cb80ecdSBarry Smith -  f - Jacobian evaluation contex destroy function
555800f99ffSJeremy L Thompson 
556800f99ffSJeremy L Thompson    Level: advanced
557800f99ffSJeremy L Thompson 
55890f54644SBarry Smith .seealso: `DMSNESSetJacobian()`
559800f99ffSJeremy L Thompson @*/
5609371c9d4SSatish Balay PetscErrorCode DMSNESSetJacobianContextDestroy(DM dm, PetscErrorCode (*f)(void *)) {
561800f99ffSJeremy L Thompson   DMSNES sdm;
562800f99ffSJeremy L Thompson 
563800f99ffSJeremy L Thompson   PetscFunctionBegin;
564800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
565800f99ffSJeremy L Thompson   PetscCall(DMGetDMSNESWrite(dm, &sdm));
566800f99ffSJeremy L Thompson   if (sdm->jacobianctxcontainer) PetscCall(PetscContainerSetUserDestroy(sdm->jacobianctxcontainer, f));
567800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
568800f99ffSJeremy L Thompson }
569800f99ffSJeremy L Thompson 
5709371c9d4SSatish Balay PetscErrorCode DMSNESUnsetJacobianContext_Internal(DM dm) {
571800f99ffSJeremy L Thompson   DMSNES sdm;
572800f99ffSJeremy L Thompson 
573800f99ffSJeremy L Thompson   PetscFunctionBegin;
574800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
575800f99ffSJeremy L Thompson   PetscCall(DMGetDMSNESWrite(dm, &sdm));
576800f99ffSJeremy L Thompson   PetscCall(DMSNESUnsetJacobianContext_DMSNES(sdm));
5776cab3a1bSJed Brown   PetscFunctionReturn(0);
5786cab3a1bSJed Brown }
5796cab3a1bSJed Brown 
5806cab3a1bSJed Brown /*@C
581ecfdb398SPeter Brune    DMSNESGetJacobian - get SNES Jacobian evaluation function
5826cab3a1bSJed Brown 
5836cab3a1bSJed Brown    Not Collective
5846cab3a1bSJed Brown 
5854165533cSJose E. Roman    Input Parameter:
5866cab3a1bSJed Brown .  dm - DM to be used with SNES
5876cab3a1bSJed Brown 
5884165533cSJose E. Roman    Output Parameters:
589f8b49ee9SBarry Smith +  J - Jacobian evaluation function; see SNESJacobianFunction for all calling sequence
5906cab3a1bSJed Brown -  ctx - context for residual evaluation
5916cab3a1bSJed Brown 
5926cab3a1bSJed Brown    Level: advanced
5936cab3a1bSJed Brown 
5946cab3a1bSJed Brown    Note:
5956cab3a1bSJed Brown    SNESGetJacobian() is normally used, but it calls this function internally because the user context is actually
5966cab3a1bSJed Brown    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
5976cab3a1bSJed Brown    not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian.
5986cab3a1bSJed Brown 
599db781477SPatrick Sanan .seealso: `DMSNESSetContext()`, `SNESSetFunction()`, `DMSNESSetJacobian()`, `SNESJacobianFunction`
6006cab3a1bSJed Brown @*/
6019371c9d4SSatish Balay PetscErrorCode DMSNESGetJacobian(DM dm, PetscErrorCode (**J)(SNES, Vec, Mat, Mat, void *), void **ctx) {
602942e3340SBarry Smith   DMSNES sdm;
6036cab3a1bSJed Brown 
6046cab3a1bSJed Brown   PetscFunctionBegin;
6056cab3a1bSJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6069566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(dm, &sdm));
607f8b49ee9SBarry Smith   if (J) *J = sdm->ops->computejacobian;
608800f99ffSJeremy L Thompson   if (ctx) {
609800f99ffSJeremy L Thompson     if (sdm->jacobianctxcontainer) PetscCall(PetscContainerGetPointer(sdm->jacobianctxcontainer, ctx));
610800f99ffSJeremy L Thompson     else *ctx = NULL;
611800f99ffSJeremy L Thompson   }
6126cab3a1bSJed Brown   PetscFunctionReturn(0);
6136cab3a1bSJed Brown }
6146cab3a1bSJed Brown 
615e03ab78fSPeter Brune /*@C
616e03ab78fSPeter Brune    DMSNESSetPicard - set SNES Picard iteration matrix and RHS evaluation functions.
617e03ab78fSPeter Brune 
618e03ab78fSPeter Brune    Not Collective
619e03ab78fSPeter Brune 
6204165533cSJose E. Roman    Input Parameters:
621e03ab78fSPeter Brune +  dm - DM to be used with SNES
622f8b49ee9SBarry Smith .  b - RHS evaluation function
623f8b49ee9SBarry Smith .  J - Picard matrix evaluation function
624e03ab78fSPeter Brune -  ctx - context for residual evaluation
625e03ab78fSPeter Brune 
626e03ab78fSPeter Brune    Level: advanced
627e03ab78fSPeter Brune 
628db781477SPatrick Sanan .seealso: `SNESSetPicard()`, `DMSNESSetFunction()`, `DMSNESSetJacobian()`
629e03ab78fSPeter Brune @*/
6309371c9d4SSatish Balay PetscErrorCode DMSNESSetPicard(DM dm, PetscErrorCode (*b)(SNES, Vec, Vec, void *), PetscErrorCode (*J)(SNES, Vec, Mat, Mat, void *), void *ctx) {
631942e3340SBarry Smith   DMSNES sdm;
632e03ab78fSPeter Brune 
633e03ab78fSPeter Brune   PetscFunctionBegin;
634e03ab78fSPeter Brune   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6359566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(dm, &sdm));
636f8b49ee9SBarry Smith   if (b) sdm->ops->computepfunction = b;
637f8b49ee9SBarry Smith   if (J) sdm->ops->computepjacobian = J;
638e03ab78fSPeter Brune   if (ctx) sdm->pctx = ctx;
639e03ab78fSPeter Brune   PetscFunctionReturn(0);
640e03ab78fSPeter Brune }
641e03ab78fSPeter Brune 
6427971a8bfSPeter Brune /*@C
6437971a8bfSPeter Brune    DMSNESGetPicard - get SNES Picard iteration evaluation functions
6447971a8bfSPeter Brune 
6457971a8bfSPeter Brune    Not Collective
6467971a8bfSPeter Brune 
6474165533cSJose E. Roman    Input Parameter:
6487971a8bfSPeter Brune .  dm - DM to be used with SNES
6497971a8bfSPeter Brune 
6504165533cSJose E. Roman    Output Parameters:
651f8b49ee9SBarry Smith +  b - RHS evaluation function; see SNESFunction for details
652f8b49ee9SBarry Smith .  J  - RHS evaluation function; see SNESJacobianFunction for detailsa
6537971a8bfSPeter Brune -  ctx - context for residual evaluation
6547971a8bfSPeter Brune 
6557971a8bfSPeter Brune    Level: advanced
6567971a8bfSPeter Brune 
657db781477SPatrick Sanan .seealso: `DMSNESSetContext()`, `SNESSetFunction()`, `DMSNESSetJacobian()`
6587971a8bfSPeter Brune @*/
6599371c9d4SSatish Balay PetscErrorCode DMSNESGetPicard(DM dm, PetscErrorCode (**b)(SNES, Vec, Vec, void *), PetscErrorCode (**J)(SNES, Vec, Mat, Mat, void *), void **ctx) {
660942e3340SBarry Smith   DMSNES sdm;
6617971a8bfSPeter Brune 
6627971a8bfSPeter Brune   PetscFunctionBegin;
6637971a8bfSPeter Brune   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6649566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(dm, &sdm));
665f8b49ee9SBarry Smith   if (b) *b = sdm->ops->computepfunction;
666f8b49ee9SBarry Smith   if (J) *J = sdm->ops->computepjacobian;
6677971a8bfSPeter Brune   if (ctx) *ctx = sdm->pctx;
6687971a8bfSPeter Brune   PetscFunctionReturn(0);
6697971a8bfSPeter Brune }
670