xref: /petsc/src/snes/utils/dmsnes.c (revision 800f99ff9e85495c69e9e5819c0be0dbd8cbc57c)
1af0996ceSBarry Smith #include <petsc/private/snesimpl.h>   /*I "petscsnes.h" I*/
2af0996ceSBarry Smith #include <petsc/private/dmimpl.h>     /*I "petscdm.h" I*/
36cab3a1bSJed Brown 
4*800f99ffSJeremy L Thompson static PetscErrorCode DMSNESUnsetFunctionContext_DMSNES(DMSNES sdm)
5*800f99ffSJeremy L Thompson {
6*800f99ffSJeremy L Thompson   PetscFunctionBegin;
7*800f99ffSJeremy L Thompson   PetscCall(PetscObjectCompose((PetscObject)sdm,"function ctx",NULL));
8*800f99ffSJeremy L Thompson   sdm->functionctxcontainer = NULL;
9*800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
10*800f99ffSJeremy L Thompson }
11*800f99ffSJeremy L Thompson 
12*800f99ffSJeremy L Thompson static PetscErrorCode DMSNESUnsetJacobianContext_DMSNES(DMSNES sdm)
13*800f99ffSJeremy L Thompson {
14*800f99ffSJeremy L Thompson   PetscFunctionBegin;
15*800f99ffSJeremy L Thompson   PetscCall(PetscObjectCompose((PetscObject)sdm,"jacobian ctx",NULL));
16*800f99ffSJeremy L Thompson   sdm->jacobianctxcontainer = NULL;
17*800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
18*800f99ffSJeremy L Thompson }
19*800f99ffSJeremy L Thompson 
2022c6f798SBarry Smith static PetscErrorCode DMSNESDestroy(DMSNES *kdm)
216cab3a1bSJed Brown {
226cab3a1bSJed Brown   PetscFunctionBegin;
2322c6f798SBarry Smith   if (!*kdm) PetscFunctionReturn(0);
2422c6f798SBarry Smith   PetscValidHeaderSpecific((*kdm),DMSNES_CLASSID,1);
259e5d0892SLisandro Dalcin   if (--((PetscObject)(*kdm))->refct > 0) {*kdm = NULL; PetscFunctionReturn(0);}
26*800f99ffSJeremy L Thompson   PetscCall(DMSNESUnsetFunctionContext_DMSNES(*kdm));
27*800f99ffSJeremy 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 
332d53ad75SBarry Smith PetscErrorCode DMSNESLoad(DMSNES kdm,PetscViewer viewer)
342d53ad75SBarry Smith {
352d53ad75SBarry Smith   PetscFunctionBegin;
369566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer,&kdm->ops->computefunction,1,NULL,PETSC_FUNCTION));
379566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer,&kdm->ops->computejacobian,1,NULL,PETSC_FUNCTION));
382d53ad75SBarry Smith   PetscFunctionReturn(0);
392d53ad75SBarry Smith }
402d53ad75SBarry Smith 
412d53ad75SBarry Smith PetscErrorCode DMSNESView(DMSNES kdm,PetscViewer viewer)
422d53ad75SBarry Smith {
432d53ad75SBarry Smith   PetscBool      isascii,isbinary;
442d53ad75SBarry Smith 
452d53ad75SBarry Smith   PetscFunctionBegin;
469566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii));
479566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary));
482d53ad75SBarry Smith   if (isascii) {
494b5d3663SBarry Smith #if defined(PETSC_SERIALIZE_FUNCTIONS) && defined(PETSC_SERIALIZE_FUNCTIONS_VIEW)
502d53ad75SBarry Smith     const char *fname;
512d53ad75SBarry Smith 
529566063dSJacob Faibussowitsch     PetscCall(PetscFPTFind(kdm->ops->computefunction,&fname));
532d53ad75SBarry Smith     if (fname) {
549566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"Function used by SNES: %s\n",fname));
552d53ad75SBarry Smith     }
569566063dSJacob Faibussowitsch     PetscCall(PetscFPTFind(kdm->ops->computejacobian,&fname));
572d53ad75SBarry Smith     if (fname) {
589566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"Jacobian function used by SNES: %s\n",fname));
592d53ad75SBarry Smith     }
60c7a10e08SBarry Smith #endif
612d53ad75SBarry Smith   } else if (isbinary) {
623964eb88SJed Brown     struct {
633964eb88SJed Brown       PetscErrorCode (*func)(SNES,Vec,Vec,void*);
649200755eSBarry Smith     } funcstruct;
659200755eSBarry Smith     struct {
66d1e9a80fSBarry Smith       PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*);
679200755eSBarry Smith     } jacstruct;
689200755eSBarry Smith     funcstruct.func = kdm->ops->computefunction;
699200755eSBarry Smith     jacstruct.jac   = kdm->ops->computejacobian;
709566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWrite(viewer,&funcstruct,1,PETSC_FUNCTION));
719566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWrite(viewer,&jacstruct,1,PETSC_FUNCTION));
722d53ad75SBarry Smith   }
732d53ad75SBarry Smith   PetscFunctionReturn(0);
742d53ad75SBarry Smith }
752d53ad75SBarry Smith 
7622c6f798SBarry Smith static PetscErrorCode DMSNESCreate(MPI_Comm comm,DMSNES *kdm)
7722c6f798SBarry Smith {
7822c6f798SBarry Smith   PetscFunctionBegin;
799566063dSJacob Faibussowitsch   PetscCall(SNESInitializePackage());
809566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(*kdm, DMSNES_CLASSID,  "DMSNES", "DMSNES", "DMSNES", comm, DMSNESDestroy, DMSNESView));
816cab3a1bSJed Brown   PetscFunctionReturn(0);
826cab3a1bSJed Brown }
836cab3a1bSJed Brown 
84942e3340SBarry Smith /* Attaches the DMSNES to the coarse level.
856cab3a1bSJed Brown  * Under what conditions should we copy versus duplicate?
866cab3a1bSJed Brown  */
87942e3340SBarry Smith static PetscErrorCode DMCoarsenHook_DMSNES(DM dm,DM dmc,void *ctx)
886cab3a1bSJed Brown {
896cab3a1bSJed Brown   PetscFunctionBegin;
909566063dSJacob Faibussowitsch   PetscCall(DMCopyDMSNES(dm,dmc));
916cab3a1bSJed Brown   PetscFunctionReturn(0);
926cab3a1bSJed Brown }
936cab3a1bSJed Brown 
94dfe15315SJed Brown /* This could restrict auxiliary information to the coarse level.
95caa4e7f2SJed Brown  */
96942e3340SBarry Smith static PetscErrorCode DMRestrictHook_DMSNES(DM dm,Mat Restrict,Vec rscale,Mat Inject,DM dmc,void *ctx)
97caa4e7f2SJed Brown {
98caa4e7f2SJed Brown   PetscFunctionBegin;
99caa4e7f2SJed Brown   PetscFunctionReturn(0);
100caa4e7f2SJed Brown }
101caa4e7f2SJed Brown 
102be081cd6SPeter Brune /* Attaches the DMSNES to the subdomain. */
103be081cd6SPeter Brune static PetscErrorCode DMSubDomainHook_DMSNES(DM dm,DM subdm,void *ctx)
104be081cd6SPeter Brune {
105be081cd6SPeter Brune   PetscFunctionBegin;
1069566063dSJacob Faibussowitsch   PetscCall(DMCopyDMSNES(dm,subdm));
107be081cd6SPeter Brune   PetscFunctionReturn(0);
108be081cd6SPeter Brune }
109be081cd6SPeter Brune 
110be081cd6SPeter Brune /* This could restrict auxiliary information to the coarse level.
111be081cd6SPeter Brune  */
112be081cd6SPeter Brune static PetscErrorCode DMSubDomainRestrictHook_DMSNES(DM dm,VecScatter gscat,VecScatter lscat,DM subdm,void *ctx)
113be081cd6SPeter Brune {
114be081cd6SPeter Brune   PetscFunctionBegin;
115be081cd6SPeter Brune   PetscFunctionReturn(0);
116be081cd6SPeter Brune }
117be081cd6SPeter Brune 
118942e3340SBarry Smith static PetscErrorCode DMRefineHook_DMSNES(DM dm,DM dmf,void *ctx)
11903a0fabfSPeter Brune {
12003a0fabfSPeter Brune   PetscFunctionBegin;
1219566063dSJacob Faibussowitsch   PetscCall(DMCopyDMSNES(dm,dmf));
12203a0fabfSPeter Brune   PetscFunctionReturn(0);
12303a0fabfSPeter Brune }
12403a0fabfSPeter Brune 
12503a0fabfSPeter Brune /* This could restrict auxiliary information to the coarse level.
12603a0fabfSPeter Brune  */
127942e3340SBarry Smith static PetscErrorCode DMInterpolateHook_DMSNES(DM dm,Mat Interp,DM dmf,void *ctx)
12803a0fabfSPeter Brune {
12903a0fabfSPeter Brune   PetscFunctionBegin;
13003a0fabfSPeter Brune   PetscFunctionReturn(0);
13103a0fabfSPeter Brune }
13203a0fabfSPeter Brune 
13322c6f798SBarry Smith /*@C
13422c6f798SBarry Smith    DMSNESCopy - copies the information in a DMSNES to another DMSNES
13522c6f798SBarry Smith 
13622c6f798SBarry Smith    Not Collective
13722c6f798SBarry Smith 
1384165533cSJose E. Roman    Input Parameters:
13922c6f798SBarry Smith +  kdm - Original DMSNES
14022c6f798SBarry Smith -  nkdm - DMSNES to receive the data, should have been created with DMSNESCreate()
14122c6f798SBarry Smith 
14222c6f798SBarry Smith    Level: developer
14322c6f798SBarry Smith 
144db781477SPatrick Sanan .seealso: `DMSNESCreate()`, `DMSNESDestroy()`
14522c6f798SBarry Smith @*/
14622c6f798SBarry Smith PetscErrorCode DMSNESCopy(DMSNES kdm,DMSNES nkdm)
14722c6f798SBarry Smith {
14822c6f798SBarry Smith   PetscFunctionBegin;
14922c6f798SBarry Smith   PetscValidHeaderSpecific(kdm,DMSNES_CLASSID,1);
15022c6f798SBarry Smith   PetscValidHeaderSpecific(nkdm,DMSNES_CLASSID,2);
15122c6f798SBarry Smith   nkdm->ops->computefunction  = kdm->ops->computefunction;
1522bc4d0c4SPeter Brune   nkdm->ops->computejacobian  = kdm->ops->computejacobian;
15322c6f798SBarry Smith   nkdm->ops->computegs        = kdm->ops->computegs;
15422c6f798SBarry Smith   nkdm->ops->computeobjective = kdm->ops->computeobjective;
15522c6f798SBarry Smith   nkdm->ops->computepjacobian = kdm->ops->computepjacobian;
15622c6f798SBarry Smith   nkdm->ops->computepfunction = kdm->ops->computepfunction;
15722c6f798SBarry Smith   nkdm->ops->destroy          = kdm->ops->destroy;
15822c6f798SBarry Smith   nkdm->ops->duplicate        = kdm->ops->duplicate;
15922c6f798SBarry Smith 
16022c6f798SBarry Smith   nkdm->gsctx                 = kdm->gsctx;
16122c6f798SBarry Smith   nkdm->pctx                  = kdm->pctx;
16222c6f798SBarry Smith   nkdm->objectivectx          = kdm->objectivectx;
163af903c1dSJunchao Zhang   nkdm->originaldm            = kdm->originaldm;
164*800f99ffSJeremy L Thompson   nkdm->functionctxcontainer  = kdm->functionctxcontainer;
165*800f99ffSJeremy L Thompson   nkdm->jacobianctxcontainer  = kdm->jacobianctxcontainer;
166*800f99ffSJeremy L Thompson   if (nkdm->functionctxcontainer) PetscCall(PetscObjectCompose((PetscObject)nkdm,"function ctx",(PetscObject)nkdm->functionctxcontainer));
167*800f99ffSJeremy L Thompson   if (nkdm->jacobianctxcontainer) PetscCall(PetscObjectCompose((PetscObject)nkdm,"jacobian ctx",(PetscObject)nkdm->jacobianctxcontainer));
16822c6f798SBarry Smith 
16922c6f798SBarry Smith   /*
17022c6f798SBarry Smith   nkdm->fortran_func_pointers[0] = kdm->fortran_func_pointers[0];
17122c6f798SBarry Smith   nkdm->fortran_func_pointers[1] = kdm->fortran_func_pointers[1];
17222c6f798SBarry Smith   nkdm->fortran_func_pointers[2] = kdm->fortran_func_pointers[2];
17322c6f798SBarry Smith   */
17422c6f798SBarry Smith 
17522c6f798SBarry Smith   /* implementation specific copy hooks */
1769566063dSJacob Faibussowitsch   if (kdm->ops->duplicate) PetscCall((*kdm->ops->duplicate)(kdm,nkdm));
17722c6f798SBarry Smith   PetscFunctionReturn(0);
17822c6f798SBarry Smith }
17922c6f798SBarry Smith 
1806cab3a1bSJed Brown /*@C
181942e3340SBarry Smith    DMGetDMSNES - get read-only private DMSNES context from a DM
1826cab3a1bSJed Brown 
1836cab3a1bSJed Brown    Not Collective
1846cab3a1bSJed Brown 
1854165533cSJose E. Roman    Input Parameter:
1866cab3a1bSJed Brown .  dm - DM to be used with SNES
1876cab3a1bSJed Brown 
1884165533cSJose E. Roman    Output Parameter:
189942e3340SBarry Smith .  snesdm - private DMSNES context
1906cab3a1bSJed Brown 
1916cab3a1bSJed Brown    Level: developer
1926cab3a1bSJed Brown 
1936cab3a1bSJed Brown    Notes:
194942e3340SBarry Smith    Use DMGetDMSNESWrite() if write access is needed. The DMSNESSetXXX API should be used wherever possible.
1956cab3a1bSJed Brown 
196db781477SPatrick Sanan .seealso: `DMGetDMSNESWrite()`
1976cab3a1bSJed Brown @*/
198942e3340SBarry Smith PetscErrorCode DMGetDMSNES(DM dm,DMSNES *snesdm)
1996cab3a1bSJed Brown {
2006cab3a1bSJed Brown   PetscFunctionBegin;
2016cab3a1bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
202b4615a05SBarry Smith   *snesdm = (DMSNES) dm->dmsnes;
20322c6f798SBarry Smith   if (!*snesdm) {
2049566063dSJacob Faibussowitsch     PetscCall(PetscInfo(dm,"Creating new DMSNES\n"));
2059566063dSJacob Faibussowitsch     PetscCall(DMSNESCreate(PetscObjectComm((PetscObject)dm),snesdm));
2061aa26658SKarl Rupp 
207b4615a05SBarry Smith     dm->dmsnes            = (PetscObject) *snesdm;
208af903c1dSJunchao Zhang     (*snesdm)->originaldm = dm;
2099566063dSJacob Faibussowitsch     PetscCall(DMCoarsenHookAdd(dm,DMCoarsenHook_DMSNES,DMRestrictHook_DMSNES,NULL));
2109566063dSJacob Faibussowitsch     PetscCall(DMRefineHookAdd(dm,DMRefineHook_DMSNES,DMInterpolateHook_DMSNES,NULL));
2119566063dSJacob Faibussowitsch     PetscCall(DMSubDomainHookAdd(dm,DMSubDomainHook_DMSNES,DMSubDomainRestrictHook_DMSNES,NULL));
2126cab3a1bSJed Brown   }
2136cab3a1bSJed Brown   PetscFunctionReturn(0);
2146cab3a1bSJed Brown }
2156cab3a1bSJed Brown 
2166cab3a1bSJed Brown /*@C
217942e3340SBarry Smith    DMGetDMSNESWrite - get write access to private DMSNES context from a DM
2186cab3a1bSJed Brown 
2196cab3a1bSJed Brown    Not Collective
2206cab3a1bSJed Brown 
2214165533cSJose E. Roman    Input Parameter:
2226cab3a1bSJed Brown .  dm - DM to be used with SNES
2236cab3a1bSJed Brown 
2244165533cSJose E. Roman    Output Parameter:
225942e3340SBarry Smith .  snesdm - private DMSNES context
2266cab3a1bSJed Brown 
2276cab3a1bSJed Brown    Level: developer
2286cab3a1bSJed Brown 
229db781477SPatrick Sanan .seealso: `DMGetDMSNES()`
2306cab3a1bSJed Brown @*/
231942e3340SBarry Smith PetscErrorCode DMGetDMSNESWrite(DM dm,DMSNES *snesdm)
2326cab3a1bSJed Brown {
233942e3340SBarry Smith   DMSNES         sdm;
2346cab3a1bSJed Brown 
2356cab3a1bSJed Brown   PetscFunctionBegin;
2366cab3a1bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2379566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(dm,&sdm));
23828b400f6SJacob Faibussowitsch   PetscCheck(sdm->originaldm,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"DMSNES has a NULL originaldm");
2396cab3a1bSJed Brown   if (sdm->originaldm != dm) {  /* Copy on write */
240b4615a05SBarry Smith     DMSNES oldsdm = sdm;
2419566063dSJacob Faibussowitsch     PetscCall(PetscInfo(dm,"Copying DMSNES due to write\n"));
2429566063dSJacob Faibussowitsch     PetscCall(DMSNESCreate(PetscObjectComm((PetscObject)dm),&sdm));
2439566063dSJacob Faibussowitsch     PetscCall(DMSNESCopy(oldsdm,sdm));
2449566063dSJacob Faibussowitsch     PetscCall(DMSNESDestroy((DMSNES*)&dm->dmsnes));
245b4615a05SBarry Smith     dm->dmsnes = (PetscObject)sdm;
246af903c1dSJunchao Zhang     sdm->originaldm = dm;
2476cab3a1bSJed Brown   }
2486cab3a1bSJed Brown   *snesdm = sdm;
2496cab3a1bSJed Brown   PetscFunctionReturn(0);
2506cab3a1bSJed Brown }
2516cab3a1bSJed Brown 
2526cab3a1bSJed Brown /*@C
253942e3340SBarry Smith    DMCopyDMSNES - copies a DM context to a new DM
2546cab3a1bSJed Brown 
2556cab3a1bSJed Brown    Logically Collective
2566cab3a1bSJed Brown 
2574165533cSJose E. Roman    Input Parameters:
2586cab3a1bSJed Brown +  dmsrc - DM to obtain context from
2596cab3a1bSJed Brown -  dmdest - DM to add context to
2606cab3a1bSJed Brown 
2616cab3a1bSJed Brown    Level: developer
2626cab3a1bSJed Brown 
2636cab3a1bSJed Brown    Note:
2646cab3a1bSJed Brown    The context is copied by reference. This function does not ensure that a context exists.
2656cab3a1bSJed Brown 
266db781477SPatrick Sanan .seealso: `DMGetDMSNES()`, `SNESSetDM()`
2676cab3a1bSJed Brown @*/
268942e3340SBarry Smith PetscErrorCode DMCopyDMSNES(DM dmsrc,DM dmdest)
2696cab3a1bSJed Brown {
2706cab3a1bSJed Brown   PetscFunctionBegin;
2716cab3a1bSJed Brown   PetscValidHeaderSpecific(dmsrc,DM_CLASSID,1);
2726cab3a1bSJed Brown   PetscValidHeaderSpecific(dmdest,DM_CLASSID,2);
2739566063dSJacob Faibussowitsch   if (!dmdest->dmsnes) PetscCall(DMSNESCreate(PetscObjectComm((PetscObject) dmdest), (DMSNES *) &dmdest->dmsnes));
2749566063dSJacob Faibussowitsch   PetscCall(DMSNESCopy((DMSNES) dmsrc->dmsnes, (DMSNES) dmdest->dmsnes));
2759566063dSJacob Faibussowitsch   PetscCall(DMCoarsenHookAdd(dmdest,DMCoarsenHook_DMSNES,NULL,NULL));
2769566063dSJacob Faibussowitsch   PetscCall(DMRefineHookAdd(dmdest,DMRefineHook_DMSNES,NULL,NULL));
2779566063dSJacob Faibussowitsch   PetscCall(DMSubDomainHookAdd(dmdest,DMSubDomainHook_DMSNES,DMSubDomainRestrictHook_DMSNES,NULL));
2786cab3a1bSJed Brown   PetscFunctionReturn(0);
2796cab3a1bSJed Brown }
2806cab3a1bSJed Brown 
2816cab3a1bSJed Brown /*@C
2826cab3a1bSJed Brown    DMSNESSetFunction - set SNES residual evaluation function
2836cab3a1bSJed Brown 
2846cab3a1bSJed Brown    Not Collective
2856cab3a1bSJed Brown 
2864165533cSJose E. Roman    Input Parameters:
2876cab3a1bSJed Brown +  dm - DM to be used with SNES
288f8b49ee9SBarry Smith .  f - residual evaluation function; see SNESFunction for details
2896cab3a1bSJed Brown -  ctx - context for residual evaluation
2906cab3a1bSJed Brown 
2916cab3a1bSJed Brown    Level: advanced
2926cab3a1bSJed Brown 
2936cab3a1bSJed Brown    Note:
2946cab3a1bSJed Brown    SNESSetFunction() is normally used, but it calls this function internally because the user context is actually
2956cab3a1bSJed Brown    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
2966cab3a1bSJed Brown    not. If DM took a more central role at some later date, this could become the primary method of setting the residual.
2976cab3a1bSJed Brown 
298db781477SPatrick Sanan .seealso: `DMSNESSetContext()`, `SNESSetFunction()`, `DMSNESSetJacobian()`, `SNESFunction`
2996cab3a1bSJed Brown @*/
300f8b49ee9SBarry Smith PetscErrorCode DMSNESSetFunction(DM dm,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx)
3016cab3a1bSJed Brown {
302942e3340SBarry Smith   DMSNES         sdm;
3036cab3a1bSJed Brown 
3046cab3a1bSJed Brown   PetscFunctionBegin;
3056cab3a1bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3069566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNESWrite(dm,&sdm));
307f8b49ee9SBarry Smith   if (f) sdm->ops->computefunction = f;
308*800f99ffSJeremy L Thompson   if (ctx) {
309*800f99ffSJeremy L Thompson     PetscContainer ctxcontainer;
310*800f99ffSJeremy L Thompson     PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)sdm),&ctxcontainer));
311*800f99ffSJeremy L Thompson     PetscCall(PetscContainerSetPointer(ctxcontainer,ctx));
312*800f99ffSJeremy L Thompson     PetscCall(PetscObjectCompose((PetscObject)sdm,"function ctx",(PetscObject)ctxcontainer));
313*800f99ffSJeremy L Thompson     sdm->functionctxcontainer = ctxcontainer;
314*800f99ffSJeremy L Thompson     PetscCall(PetscContainerDestroy(&ctxcontainer));
315*800f99ffSJeremy L Thompson   }
316*800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
317*800f99ffSJeremy L Thompson }
318*800f99ffSJeremy L Thompson 
319*800f99ffSJeremy L Thompson /*@C
320*800f99ffSJeremy L Thompson    DMSNESSetFunctionContextDestroy - set SNES residual evaluation context destroy function
321*800f99ffSJeremy L Thompson 
322*800f99ffSJeremy L Thompson    Not Collective
323*800f99ffSJeremy L Thompson 
324*800f99ffSJeremy L Thompson    Input Parameters:
325*800f99ffSJeremy L Thompson +  dm - DM to be used with SNES
326*800f99ffSJeremy L Thompson .  f - residual evaluation context destroy function
327*800f99ffSJeremy L Thompson 
328*800f99ffSJeremy L Thompson    Level: advanced
329*800f99ffSJeremy L Thompson 
330*800f99ffSJeremy L Thompson    Note:
331*800f99ffSJeremy L Thompson    SNESSetFunctionContextDestroy() is normally used, but it calls this function internally because the user context is actually
332*800f99ffSJeremy L Thompson    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
333*800f99ffSJeremy L Thompson    not. If DM took a more central role at some later date, this could become the primary method of setting the residual.
334*800f99ffSJeremy L Thompson 
335*800f99ffSJeremy L Thompson .seealso: `DMSNESSetFunction()`, `SNESSetFunction()`
336*800f99ffSJeremy L Thompson @*/
337*800f99ffSJeremy L Thompson PetscErrorCode DMSNESSetFunctionContextDestroy(DM dm,PetscErrorCode (*f)(void*))
338*800f99ffSJeremy L Thompson {
339*800f99ffSJeremy L Thompson   DMSNES         sdm;
340*800f99ffSJeremy L Thompson 
341*800f99ffSJeremy L Thompson   PetscFunctionBegin;
342*800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
343*800f99ffSJeremy L Thompson   PetscCall(DMGetDMSNESWrite(dm,&sdm));
344*800f99ffSJeremy L Thompson   if (sdm->functionctxcontainer) PetscCall(PetscContainerSetUserDestroy(sdm->functionctxcontainer,f));
345*800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
346*800f99ffSJeremy L Thompson }
347*800f99ffSJeremy L Thompson 
348*800f99ffSJeremy L Thompson PetscErrorCode DMSNESUnsetFunctionContext_Internal(DM dm)
349*800f99ffSJeremy L Thompson {
350*800f99ffSJeremy L Thompson   DMSNES         sdm;
351*800f99ffSJeremy L Thompson 
352*800f99ffSJeremy L Thompson   PetscFunctionBegin;
353*800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
354*800f99ffSJeremy L Thompson   PetscCall(DMGetDMSNESWrite(dm,&sdm));
355*800f99ffSJeremy L Thompson   PetscCall(DMSNESUnsetFunctionContext_DMSNES(sdm));
3566cab3a1bSJed Brown   PetscFunctionReturn(0);
3576cab3a1bSJed Brown }
3586cab3a1bSJed Brown 
3596cab3a1bSJed Brown /*@C
360bbc1464cSBarry Smith    DMSNESSetMFFunction - set SNES residual evaluation function used in applying the matrix-free Jacobian with -snes_mf_operator
361bbc1464cSBarry Smith 
362bbc1464cSBarry Smith    Logically Collective on dm
363bbc1464cSBarry Smith 
3644165533cSJose E. Roman    Input Parameters:
365bbc1464cSBarry Smith +  dm - DM to be used with SNES
366bbc1464cSBarry Smith -  f - residual evaluation function; see SNESFunction for details
367bbc1464cSBarry Smith 
368bbc1464cSBarry Smith    Level: advanced
369bbc1464cSBarry Smith 
370db781477SPatrick Sanan .seealso: `DMSNESSetContext()`, `SNESSetFunction()`, `DMSNESSetJacobian()`, `SNESFunction`, `DMSNESSetFunction()`
371bbc1464cSBarry Smith @*/
372bbc1464cSBarry Smith PetscErrorCode DMSNESSetMFFunction(DM dm,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx)
373bbc1464cSBarry Smith {
374bbc1464cSBarry Smith   DMSNES         sdm;
375bbc1464cSBarry Smith 
376bbc1464cSBarry Smith   PetscFunctionBegin;
377bbc1464cSBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
378bbc1464cSBarry Smith   if (f || ctx) {
3799566063dSJacob Faibussowitsch     PetscCall(DMGetDMSNESWrite(dm,&sdm));
380bbc1464cSBarry Smith   }
381bbc1464cSBarry Smith   if (f) sdm->ops->computemffunction = f;
382bbc1464cSBarry Smith   if (ctx) sdm->mffunctionctx = ctx;
383bbc1464cSBarry Smith   PetscFunctionReturn(0);
384bbc1464cSBarry Smith }
385bbc1464cSBarry Smith 
386bbc1464cSBarry Smith /*@C
3876cab3a1bSJed Brown    DMSNESGetFunction - get SNES residual evaluation function
3886cab3a1bSJed Brown 
3896cab3a1bSJed Brown    Not Collective
3906cab3a1bSJed Brown 
3914165533cSJose E. Roman    Input Parameter:
3926cab3a1bSJed Brown .  dm - DM to be used with SNES
3936cab3a1bSJed Brown 
3944165533cSJose E. Roman    Output Parameters:
395f8b49ee9SBarry Smith +  f - residual evaluation function; see SNESFunction for details
3966cab3a1bSJed Brown -  ctx - context for residual evaluation
3976cab3a1bSJed Brown 
3986cab3a1bSJed Brown    Level: advanced
3996cab3a1bSJed Brown 
4006cab3a1bSJed Brown    Note:
4016cab3a1bSJed Brown    SNESGetFunction() is normally used, but it calls this function internally because the user context is actually
4026cab3a1bSJed Brown    associated with the DM.
4036cab3a1bSJed Brown 
404db781477SPatrick Sanan .seealso: `DMSNESSetContext()`, `DMSNESSetFunction()`, `SNESSetFunction()`, `SNESFunction`
4056cab3a1bSJed Brown @*/
406f8b49ee9SBarry Smith PetscErrorCode DMSNESGetFunction(DM dm,PetscErrorCode (**f)(SNES,Vec,Vec,void*),void **ctx)
4076cab3a1bSJed Brown {
408942e3340SBarry Smith   DMSNES         sdm;
4096cab3a1bSJed Brown 
4106cab3a1bSJed Brown   PetscFunctionBegin;
4116cab3a1bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
4129566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(dm,&sdm));
413f8b49ee9SBarry Smith   if (f) *f = sdm->ops->computefunction;
414*800f99ffSJeremy L Thompson   if (ctx) {
415*800f99ffSJeremy L Thompson     if (sdm->functionctxcontainer) PetscCall(PetscContainerGetPointer(sdm->functionctxcontainer,ctx));
416*800f99ffSJeremy L Thompson     else *ctx = NULL;
417*800f99ffSJeremy L Thompson   }
4186cab3a1bSJed Brown   PetscFunctionReturn(0);
4196cab3a1bSJed Brown }
4206cab3a1bSJed Brown 
4212a4ee8f2SPeter Brune /*@C
422081a7dcdSPeter Brune    DMSNESSetObjective - set SNES objective evaluation function
4232a4ee8f2SPeter Brune 
4242a4ee8f2SPeter Brune    Not Collective
4252a4ee8f2SPeter Brune 
4264165533cSJose E. Roman    Input Parameters:
4272a4ee8f2SPeter Brune +  dm - DM to be used with SNES
428f8b49ee9SBarry Smith .  obj - objective evaluation function; see SNESObjectiveFunction for details
4292a4ee8f2SPeter Brune -  ctx - context for residual evaluation
4302a4ee8f2SPeter Brune 
4312a4ee8f2SPeter Brune    Level: advanced
4322a4ee8f2SPeter Brune 
433db781477SPatrick Sanan .seealso: `DMSNESSetContext()`, `SNESGetObjective()`, `DMSNESSetFunction()`
4342a4ee8f2SPeter Brune @*/
435f8b49ee9SBarry Smith PetscErrorCode DMSNESSetObjective(DM dm,PetscErrorCode (*obj)(SNES,Vec,PetscReal*,void*),void *ctx)
4362a4ee8f2SPeter Brune {
437942e3340SBarry Smith   DMSNES         sdm;
4382a4ee8f2SPeter Brune 
4392a4ee8f2SPeter Brune   PetscFunctionBegin;
4402a4ee8f2SPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
441f8b49ee9SBarry Smith   if (obj || ctx) {
4429566063dSJacob Faibussowitsch     PetscCall(DMGetDMSNESWrite(dm,&sdm));
443fdaff8d6SPeter Brune   }
444f8b49ee9SBarry Smith   if (obj) sdm->ops->computeobjective = obj;
4452a4ee8f2SPeter Brune   if (ctx) sdm->objectivectx = ctx;
4462a4ee8f2SPeter Brune   PetscFunctionReturn(0);
4472a4ee8f2SPeter Brune }
4482a4ee8f2SPeter Brune 
4492a4ee8f2SPeter Brune /*@C
4502a4ee8f2SPeter Brune    DMSNESGetObjective - get SNES objective evaluation function
4512a4ee8f2SPeter Brune 
4522a4ee8f2SPeter Brune    Not Collective
4532a4ee8f2SPeter Brune 
4544165533cSJose E. Roman    Input Parameter:
4552a4ee8f2SPeter Brune .  dm - DM to be used with SNES
4562a4ee8f2SPeter Brune 
4574165533cSJose E. Roman    Output Parameters:
458f8b49ee9SBarry Smith +  obj- residual evaluation function; see SNESObjectiveFunction for details
4592a4ee8f2SPeter Brune -  ctx - context for residual evaluation
4602a4ee8f2SPeter Brune 
4612a4ee8f2SPeter Brune    Level: advanced
4622a4ee8f2SPeter Brune 
4632a4ee8f2SPeter Brune    Note:
4642a4ee8f2SPeter Brune    SNESGetFunction() is normally used, but it calls this function internally because the user context is actually
4652a4ee8f2SPeter Brune    associated with the DM.
4662a4ee8f2SPeter Brune 
467db781477SPatrick Sanan .seealso: `DMSNESSetContext()`, `DMSNESSetObjective()`, `SNESSetFunction()`
4682a4ee8f2SPeter Brune @*/
469f8b49ee9SBarry Smith PetscErrorCode DMSNESGetObjective(DM dm,PetscErrorCode (**obj)(SNES,Vec,PetscReal*,void*),void **ctx)
4702a4ee8f2SPeter Brune {
471942e3340SBarry Smith   DMSNES         sdm;
4722a4ee8f2SPeter Brune 
4732a4ee8f2SPeter Brune   PetscFunctionBegin;
4742a4ee8f2SPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
4759566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(dm,&sdm));
476f8b49ee9SBarry Smith   if (obj) *obj = sdm->ops->computeobjective;
4772a4ee8f2SPeter Brune   if (ctx) *ctx = sdm->objectivectx;
4782a4ee8f2SPeter Brune   PetscFunctionReturn(0);
4792a4ee8f2SPeter Brune }
4802a4ee8f2SPeter Brune 
4816cab3a1bSJed Brown /*@C
482be95d8f1SBarry Smith    DMSNESSetNGS - set SNES Gauss-Seidel relaxation function
4836cab3a1bSJed Brown 
4846cab3a1bSJed Brown    Not Collective
4856cab3a1bSJed Brown 
4864165533cSJose E. Roman    Input Parameters:
4876cab3a1bSJed Brown +  dm - DM to be used with SNES
488be95d8f1SBarry Smith .  f  - relaxation function, see SNESGSFunction
4896cab3a1bSJed Brown -  ctx - context for residual evaluation
4906cab3a1bSJed Brown 
4916cab3a1bSJed Brown    Level: advanced
4926cab3a1bSJed Brown 
4936cab3a1bSJed Brown    Note:
494be95d8f1SBarry Smith    SNESSetNGS() is normally used, but it calls this function internally because the user context is actually
4956cab3a1bSJed Brown    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
4966cab3a1bSJed Brown    not. If DM took a more central role at some later date, this could become the primary method of setting the residual.
4976cab3a1bSJed Brown 
498db781477SPatrick Sanan .seealso: `DMSNESSetContext()`, `SNESSetFunction()`, `DMSNESSetJacobian()`, `DMSNESSetFunction()`, `SNESGSFunction`
4996cab3a1bSJed Brown @*/
500be95d8f1SBarry Smith PetscErrorCode DMSNESSetNGS(DM dm,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx)
5016cab3a1bSJed Brown {
502942e3340SBarry Smith   DMSNES         sdm;
5036cab3a1bSJed Brown 
5046cab3a1bSJed Brown   PetscFunctionBegin;
5056cab3a1bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
506be95d8f1SBarry Smith   if (f || ctx) {
5079566063dSJacob Faibussowitsch     PetscCall(DMGetDMSNESWrite(dm,&sdm));
508fdaff8d6SPeter Brune   }
509be95d8f1SBarry Smith   if (f) sdm->ops->computegs = f;
5106cab3a1bSJed Brown   if (ctx) sdm->gsctx = ctx;
5116cab3a1bSJed Brown   PetscFunctionReturn(0);
5126cab3a1bSJed Brown }
5136cab3a1bSJed Brown 
5146cab3a1bSJed Brown /*@C
515be95d8f1SBarry Smith    DMSNESGetNGS - get SNES Gauss-Seidel relaxation function
5166cab3a1bSJed Brown 
5176cab3a1bSJed Brown    Not Collective
5186cab3a1bSJed Brown 
5194165533cSJose E. Roman    Input Parameter:
5206cab3a1bSJed Brown .  dm - DM to be used with SNES
5216cab3a1bSJed Brown 
5224165533cSJose E. Roman    Output Parameters:
523be95d8f1SBarry Smith +  f - relaxation function which performs Gauss-Seidel sweeps, see SNESGSFunction
5246cab3a1bSJed Brown -  ctx - context for residual evaluation
5256cab3a1bSJed Brown 
5266cab3a1bSJed Brown    Level: advanced
5276cab3a1bSJed Brown 
5286cab3a1bSJed Brown    Note:
529be95d8f1SBarry Smith    SNESGetNGS() is normally used, but it calls this function internally because the user context is actually
5306cab3a1bSJed Brown    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
5316cab3a1bSJed Brown    not. If DM took a more central role at some later date, this could become the primary method of setting the residual.
5326cab3a1bSJed Brown 
533db781477SPatrick Sanan .seealso: `DMSNESSetContext()`, `SNESGetNGS()`, `DMSNESGetJacobian()`, `DMSNESGetFunction()`, `SNESNGSFunction`
5346cab3a1bSJed Brown @*/
535be95d8f1SBarry Smith PetscErrorCode DMSNESGetNGS(DM dm,PetscErrorCode (**f)(SNES,Vec,Vec,void*),void **ctx)
5366cab3a1bSJed Brown {
537942e3340SBarry Smith   DMSNES         sdm;
5386cab3a1bSJed Brown 
5396cab3a1bSJed Brown   PetscFunctionBegin;
5406cab3a1bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5419566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(dm,&sdm));
542be95d8f1SBarry Smith   if (f) *f = sdm->ops->computegs;
5436cab3a1bSJed Brown   if (ctx) *ctx = sdm->gsctx;
5446cab3a1bSJed Brown   PetscFunctionReturn(0);
5456cab3a1bSJed Brown }
5466cab3a1bSJed Brown 
5476cab3a1bSJed Brown /*@C
548ecfdb398SPeter Brune    DMSNESSetJacobian - set SNES Jacobian evaluation function
5496cab3a1bSJed Brown 
5506cab3a1bSJed Brown    Not Collective
5516cab3a1bSJed Brown 
5524165533cSJose E. Roman    Input Parameters:
5536cab3a1bSJed Brown +  dm - DM to be used with SNES
554f8b49ee9SBarry Smith .  J - Jacobian evaluation function
5556cab3a1bSJed Brown -  ctx - context for residual evaluation
5566cab3a1bSJed Brown 
5576cab3a1bSJed Brown    Level: advanced
5586cab3a1bSJed Brown 
5596cab3a1bSJed Brown    Note:
5606cab3a1bSJed Brown    SNESSetJacobian() is normally used, but it calls this function internally because the user context is actually
5616cab3a1bSJed Brown    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
5626cab3a1bSJed Brown    not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian.
5636cab3a1bSJed Brown 
564db781477SPatrick Sanan .seealso: `DMSNESSetContext()`, `SNESSetFunction()`, `DMSNESGetJacobian()`, `SNESSetJacobian()`, `SNESJacobianFunction`
5656cab3a1bSJed Brown @*/
566d1e9a80fSBarry Smith PetscErrorCode DMSNESSetJacobian(DM dm,PetscErrorCode (*J)(SNES,Vec,Mat,Mat,void*),void *ctx)
5676cab3a1bSJed Brown {
568942e3340SBarry Smith   DMSNES         sdm;
5696cab3a1bSJed Brown 
5706cab3a1bSJed Brown   PetscFunctionBegin;
5716cab3a1bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
572*800f99ffSJeremy L Thompson   if (J || ctx) PetscCall(DMGetDMSNESWrite(dm,&sdm));
573f8b49ee9SBarry Smith   if (J) sdm->ops->computejacobian = J;
574*800f99ffSJeremy L Thompson   if (ctx) {
575*800f99ffSJeremy L Thompson     PetscContainer ctxcontainer;
576*800f99ffSJeremy L Thompson     PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)sdm),&ctxcontainer));
577*800f99ffSJeremy L Thompson     PetscCall(PetscContainerSetPointer(ctxcontainer,ctx));
578*800f99ffSJeremy L Thompson     PetscCall(PetscObjectCompose((PetscObject)sdm,"jacobian ctx",(PetscObject)ctxcontainer));
579*800f99ffSJeremy L Thompson     sdm->jacobianctxcontainer = ctxcontainer;
580*800f99ffSJeremy L Thompson     PetscCall(PetscContainerDestroy(&ctxcontainer));
581*800f99ffSJeremy L Thompson   }
582*800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
583*800f99ffSJeremy L Thompson }
584*800f99ffSJeremy L Thompson 
585*800f99ffSJeremy L Thompson /*@C
586*800f99ffSJeremy L Thompson    DMSNESSetJacobianContextDestroy - set SNES Jacobian evaluation context destroy function
587*800f99ffSJeremy L Thompson 
588*800f99ffSJeremy L Thompson    Not Collective
589*800f99ffSJeremy L Thompson 
590*800f99ffSJeremy L Thompson    Input Parameters:
591*800f99ffSJeremy L Thompson +  dm - DM to be used with SNES
592*800f99ffSJeremy L Thompson .  f - Jacobian evaluation contex destroy function
593*800f99ffSJeremy L Thompson 
594*800f99ffSJeremy L Thompson    Level: advanced
595*800f99ffSJeremy L Thompson 
596*800f99ffSJeremy L Thompson    Note:
597*800f99ffSJeremy L Thompson    SNESSetJacobianContextDestroy() is normally used, but it calls this function internally because the user context is actually
598*800f99ffSJeremy L Thompson    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
599*800f99ffSJeremy L Thompson    not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian.
600*800f99ffSJeremy L Thompson 
601*800f99ffSJeremy L Thompson .seealso: `DMSNESSetJacobian()`, `SNESSetJacobianContextDestroyFunction()`
602*800f99ffSJeremy L Thompson @*/
603*800f99ffSJeremy L Thompson PetscErrorCode DMSNESSetJacobianContextDestroy(DM dm,PetscErrorCode (*f)(void*))
604*800f99ffSJeremy L Thompson {
605*800f99ffSJeremy L Thompson   DMSNES         sdm;
606*800f99ffSJeremy L Thompson 
607*800f99ffSJeremy L Thompson   PetscFunctionBegin;
608*800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
609*800f99ffSJeremy L Thompson   PetscCall(DMGetDMSNESWrite(dm,&sdm));
610*800f99ffSJeremy L Thompson   if (sdm->jacobianctxcontainer) PetscCall(PetscContainerSetUserDestroy(sdm->jacobianctxcontainer,f));
611*800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
612*800f99ffSJeremy L Thompson }
613*800f99ffSJeremy L Thompson 
614*800f99ffSJeremy L Thompson PetscErrorCode DMSNESUnsetJacobianContext_Internal(DM dm)
615*800f99ffSJeremy L Thompson {
616*800f99ffSJeremy L Thompson   DMSNES         sdm;
617*800f99ffSJeremy L Thompson 
618*800f99ffSJeremy L Thompson   PetscFunctionBegin;
619*800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
620*800f99ffSJeremy L Thompson   PetscCall(DMGetDMSNESWrite(dm,&sdm));
621*800f99ffSJeremy L Thompson   PetscCall(DMSNESUnsetJacobianContext_DMSNES(sdm));
6226cab3a1bSJed Brown   PetscFunctionReturn(0);
6236cab3a1bSJed Brown }
6246cab3a1bSJed Brown 
6256cab3a1bSJed Brown /*@C
626ecfdb398SPeter Brune    DMSNESGetJacobian - get SNES Jacobian evaluation function
6276cab3a1bSJed Brown 
6286cab3a1bSJed Brown    Not Collective
6296cab3a1bSJed Brown 
6304165533cSJose E. Roman    Input Parameter:
6316cab3a1bSJed Brown .  dm - DM to be used with SNES
6326cab3a1bSJed Brown 
6334165533cSJose E. Roman    Output Parameters:
634f8b49ee9SBarry Smith +  J - Jacobian evaluation function; see SNESJacobianFunction for all calling sequence
6356cab3a1bSJed Brown -  ctx - context for residual evaluation
6366cab3a1bSJed Brown 
6376cab3a1bSJed Brown    Level: advanced
6386cab3a1bSJed Brown 
6396cab3a1bSJed Brown    Note:
6406cab3a1bSJed Brown    SNESGetJacobian() is normally used, but it calls this function internally because the user context is actually
6416cab3a1bSJed Brown    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
6426cab3a1bSJed Brown    not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian.
6436cab3a1bSJed Brown 
644db781477SPatrick Sanan .seealso: `DMSNESSetContext()`, `SNESSetFunction()`, `DMSNESSetJacobian()`, `SNESJacobianFunction`
6456cab3a1bSJed Brown @*/
646d1e9a80fSBarry Smith PetscErrorCode DMSNESGetJacobian(DM dm,PetscErrorCode (**J)(SNES,Vec,Mat,Mat,void*),void **ctx)
6476cab3a1bSJed Brown {
648942e3340SBarry Smith   DMSNES         sdm;
6496cab3a1bSJed Brown 
6506cab3a1bSJed Brown   PetscFunctionBegin;
6516cab3a1bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6529566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(dm,&sdm));
653f8b49ee9SBarry Smith   if (J) *J = sdm->ops->computejacobian;
654*800f99ffSJeremy L Thompson   if (ctx) {
655*800f99ffSJeremy L Thompson     if (sdm->jacobianctxcontainer) PetscCall(PetscContainerGetPointer(sdm->jacobianctxcontainer,ctx));
656*800f99ffSJeremy L Thompson     else *ctx = NULL;
657*800f99ffSJeremy L Thompson   }
6586cab3a1bSJed Brown   PetscFunctionReturn(0);
6596cab3a1bSJed Brown }
6606cab3a1bSJed Brown 
661e03ab78fSPeter Brune /*@C
662e03ab78fSPeter Brune    DMSNESSetPicard - set SNES Picard iteration matrix and RHS evaluation functions.
663e03ab78fSPeter Brune 
664e03ab78fSPeter Brune    Not Collective
665e03ab78fSPeter Brune 
6664165533cSJose E. Roman    Input Parameters:
667e03ab78fSPeter Brune +  dm - DM to be used with SNES
668f8b49ee9SBarry Smith .  b - RHS evaluation function
669f8b49ee9SBarry Smith .  J - Picard matrix evaluation function
670e03ab78fSPeter Brune -  ctx - context for residual evaluation
671e03ab78fSPeter Brune 
672e03ab78fSPeter Brune    Level: advanced
673e03ab78fSPeter Brune 
674db781477SPatrick Sanan .seealso: `SNESSetPicard()`, `DMSNESSetFunction()`, `DMSNESSetJacobian()`
675e03ab78fSPeter Brune @*/
676d1e9a80fSBarry Smith PetscErrorCode DMSNESSetPicard(DM dm,PetscErrorCode (*b)(SNES,Vec,Vec,void*),PetscErrorCode (*J)(SNES,Vec,Mat,Mat,void*),void *ctx)
677e03ab78fSPeter Brune {
678942e3340SBarry Smith   DMSNES         sdm;
679e03ab78fSPeter Brune 
680e03ab78fSPeter Brune   PetscFunctionBegin;
681e03ab78fSPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6829566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(dm,&sdm));
683f8b49ee9SBarry Smith   if (b) sdm->ops->computepfunction = b;
684f8b49ee9SBarry Smith   if (J) sdm->ops->computepjacobian = J;
685e03ab78fSPeter Brune   if (ctx) sdm->pctx = ctx;
686e03ab78fSPeter Brune   PetscFunctionReturn(0);
687e03ab78fSPeter Brune }
688e03ab78fSPeter Brune 
6897971a8bfSPeter Brune /*@C
6907971a8bfSPeter Brune    DMSNESGetPicard - get SNES Picard iteration evaluation functions
6917971a8bfSPeter Brune 
6927971a8bfSPeter Brune    Not Collective
6937971a8bfSPeter Brune 
6944165533cSJose E. Roman    Input Parameter:
6957971a8bfSPeter Brune .  dm - DM to be used with SNES
6967971a8bfSPeter Brune 
6974165533cSJose E. Roman    Output Parameters:
698f8b49ee9SBarry Smith +  b - RHS evaluation function; see SNESFunction for details
699f8b49ee9SBarry Smith .  J  - RHS evaluation function; see SNESJacobianFunction for detailsa
7007971a8bfSPeter Brune -  ctx - context for residual evaluation
7017971a8bfSPeter Brune 
7027971a8bfSPeter Brune    Level: advanced
7037971a8bfSPeter Brune 
704db781477SPatrick Sanan .seealso: `DMSNESSetContext()`, `SNESSetFunction()`, `DMSNESSetJacobian()`
7057971a8bfSPeter Brune @*/
706d1e9a80fSBarry Smith PetscErrorCode DMSNESGetPicard(DM dm,PetscErrorCode (**b)(SNES,Vec,Vec,void*),PetscErrorCode (**J)(SNES,Vec,Mat,Mat,void*),void **ctx)
7077971a8bfSPeter Brune {
708942e3340SBarry Smith   DMSNES         sdm;
7097971a8bfSPeter Brune 
7107971a8bfSPeter Brune   PetscFunctionBegin;
7117971a8bfSPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
7129566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(dm,&sdm));
713f8b49ee9SBarry Smith   if (b) *b = sdm->ops->computepfunction;
714f8b49ee9SBarry Smith   if (J) *J = sdm->ops->computepjacobian;
7157971a8bfSPeter Brune   if (ctx) *ctx = sdm->pctx;
7167971a8bfSPeter Brune   PetscFunctionReturn(0);
7177971a8bfSPeter Brune }
718