xref: /petsc/src/snes/utils/dmsnes.c (revision 420bcc1b905230dede3c88f397d1a4e60493adde)
1af0996ceSBarry Smith #include <petsc/private/snesimpl.h> /*I "petscsnes.h" I*/
2af0996ceSBarry Smith #include <petsc/private/dmimpl.h>   /*I "petscdm.h" I*/
36cab3a1bSJed Brown 
4d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMSNESUnsetFunctionContext_DMSNES(DMSNES sdm)
5d71ae5a4SJacob Faibussowitsch {
6800f99ffSJeremy L Thompson   PetscFunctionBegin;
7800f99ffSJeremy L Thompson   PetscCall(PetscObjectCompose((PetscObject)sdm, "function ctx", NULL));
8800f99ffSJeremy L Thompson   sdm->functionctxcontainer = NULL;
93ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10800f99ffSJeremy L Thompson }
11800f99ffSJeremy L Thompson 
12d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMSNESUnsetJacobianContext_DMSNES(DMSNES sdm)
13d71ae5a4SJacob Faibussowitsch {
14800f99ffSJeremy L Thompson   PetscFunctionBegin;
15800f99ffSJeremy L Thompson   PetscCall(PetscObjectCompose((PetscObject)sdm, "jacobian ctx", NULL));
16800f99ffSJeremy L Thompson   sdm->jacobianctxcontainer = NULL;
173ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
18800f99ffSJeremy L Thompson }
19800f99ffSJeremy L Thompson 
20d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMSNESDestroy(DMSNES *kdm)
21d71ae5a4SJacob Faibussowitsch {
226cab3a1bSJed Brown   PetscFunctionBegin;
233ba16761SJacob Faibussowitsch   if (!*kdm) PetscFunctionReturn(PETSC_SUCCESS);
2422c6f798SBarry Smith   PetscValidHeaderSpecific((*kdm), DMSNES_CLASSID, 1);
259371c9d4SSatish Balay   if (--((PetscObject)(*kdm))->refct > 0) {
269371c9d4SSatish Balay     *kdm = NULL;
273ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
289371c9d4SSatish Balay   }
29800f99ffSJeremy L Thompson   PetscCall(DMSNESUnsetFunctionContext_DMSNES(*kdm));
30800f99ffSJeremy L Thompson   PetscCall(DMSNESUnsetJacobianContext_DMSNES(*kdm));
319566063dSJacob Faibussowitsch   if ((*kdm)->ops->destroy) PetscCall(((*kdm)->ops->destroy)(*kdm));
329566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(kdm));
333ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3422c6f798SBarry Smith }
3522c6f798SBarry Smith 
36d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSNESLoad(DMSNES kdm, PetscViewer viewer)
37d71ae5a4SJacob Faibussowitsch {
382d53ad75SBarry Smith   PetscFunctionBegin;
399566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer, &kdm->ops->computefunction, 1, NULL, PETSC_FUNCTION));
409566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer, &kdm->ops->computejacobian, 1, NULL, PETSC_FUNCTION));
413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
422d53ad75SBarry Smith }
432d53ad75SBarry Smith 
44d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSNESView(DMSNES kdm, PetscViewer viewer)
45d71ae5a4SJacob Faibussowitsch {
462d53ad75SBarry Smith   PetscBool isascii, isbinary;
472d53ad75SBarry Smith 
482d53ad75SBarry Smith   PetscFunctionBegin;
499566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
509566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
512d53ad75SBarry Smith   if (isascii) {
52d5bc873cSPierre Jolivet #if defined(PETSC_SERIALIZE_FUNCTIONS)
532d53ad75SBarry Smith     const char *fname;
542d53ad75SBarry Smith 
559566063dSJacob Faibussowitsch     PetscCall(PetscFPTFind(kdm->ops->computefunction, &fname));
5648a46eb9SPierre Jolivet     if (fname) PetscCall(PetscViewerASCIIPrintf(viewer, "Function used by SNES: %s\n", fname));
579566063dSJacob Faibussowitsch     PetscCall(PetscFPTFind(kdm->ops->computejacobian, &fname));
5848a46eb9SPierre Jolivet     if (fname) PetscCall(PetscViewerASCIIPrintf(viewer, "Jacobian function used by SNES: %s\n", fname));
59c7a10e08SBarry Smith #endif
602d53ad75SBarry Smith   } else if (isbinary) {
613964eb88SJed Brown     struct {
623964eb88SJed Brown       PetscErrorCode (*func)(SNES, Vec, Vec, void *);
639200755eSBarry Smith     } funcstruct;
649200755eSBarry Smith     struct {
65d1e9a80fSBarry Smith       PetscErrorCode (*jac)(SNES, Vec, Mat, Mat, void *);
669200755eSBarry Smith     } jacstruct;
679200755eSBarry Smith     funcstruct.func = kdm->ops->computefunction;
689200755eSBarry Smith     jacstruct.jac   = kdm->ops->computejacobian;
699566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWrite(viewer, &funcstruct, 1, PETSC_FUNCTION));
709566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWrite(viewer, &jacstruct, 1, PETSC_FUNCTION));
712d53ad75SBarry Smith   }
723ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
732d53ad75SBarry Smith }
742d53ad75SBarry Smith 
75d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMSNESCreate(MPI_Comm comm, DMSNES *kdm)
76d71ae5a4SJacob Faibussowitsch {
7722c6f798SBarry Smith   PetscFunctionBegin;
789566063dSJacob Faibussowitsch   PetscCall(SNESInitializePackage());
799566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(*kdm, DMSNES_CLASSID, "DMSNES", "DMSNES", "DMSNES", comm, DMSNESDestroy, DMSNESView));
803ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
816cab3a1bSJed Brown }
826cab3a1bSJed Brown 
83942e3340SBarry Smith /* Attaches the DMSNES to the coarse level.
846cab3a1bSJed Brown  * Under what conditions should we copy versus duplicate?
856cab3a1bSJed Brown  */
86d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMCoarsenHook_DMSNES(DM dm, DM dmc, void *ctx)
87d71ae5a4SJacob Faibussowitsch {
886cab3a1bSJed Brown   PetscFunctionBegin;
899566063dSJacob Faibussowitsch   PetscCall(DMCopyDMSNES(dm, dmc));
903ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
916cab3a1bSJed Brown }
926cab3a1bSJed Brown 
93dfe15315SJed Brown /* This could restrict auxiliary information to the coarse level.
94caa4e7f2SJed Brown  */
95d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMRestrictHook_DMSNES(DM dm, Mat Restrict, Vec rscale, Mat Inject, DM dmc, void *ctx)
96d71ae5a4SJacob Faibussowitsch {
97caa4e7f2SJed Brown   PetscFunctionBegin;
983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
99caa4e7f2SJed Brown }
100caa4e7f2SJed Brown 
101be081cd6SPeter Brune /* Attaches the DMSNES to the subdomain. */
102d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMSubDomainHook_DMSNES(DM dm, DM subdm, void *ctx)
103d71ae5a4SJacob Faibussowitsch {
104be081cd6SPeter Brune   PetscFunctionBegin;
1059566063dSJacob Faibussowitsch   PetscCall(DMCopyDMSNES(dm, subdm));
1063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
107be081cd6SPeter Brune }
108be081cd6SPeter Brune 
109be081cd6SPeter Brune /* This could restrict auxiliary information to the coarse level.
110be081cd6SPeter Brune  */
111d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMSubDomainRestrictHook_DMSNES(DM dm, VecScatter gscat, VecScatter lscat, DM subdm, void *ctx)
112d71ae5a4SJacob Faibussowitsch {
113be081cd6SPeter Brune   PetscFunctionBegin;
1143ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
115be081cd6SPeter Brune }
116be081cd6SPeter Brune 
117d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMRefineHook_DMSNES(DM dm, DM dmf, void *ctx)
118d71ae5a4SJacob Faibussowitsch {
11903a0fabfSPeter Brune   PetscFunctionBegin;
1209566063dSJacob Faibussowitsch   PetscCall(DMCopyDMSNES(dm, dmf));
1213ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
12203a0fabfSPeter Brune }
12303a0fabfSPeter Brune 
12403a0fabfSPeter Brune /* This could restrict auxiliary information to the coarse level.
12503a0fabfSPeter Brune  */
126d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMInterpolateHook_DMSNES(DM dm, Mat Interp, DM dmf, void *ctx)
127d71ae5a4SJacob Faibussowitsch {
12803a0fabfSPeter Brune   PetscFunctionBegin;
1293ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
13003a0fabfSPeter Brune }
13103a0fabfSPeter Brune 
13266976f2fSJacob Faibussowitsch /*
133f6dfbefdSBarry Smith   DMSNESCopy - copies the information in a `DMSNES` to another `DMSNES`
13422c6f798SBarry Smith 
13522c6f798SBarry Smith   Not Collective
13622c6f798SBarry Smith 
1374165533cSJose E. Roman   Input Parameters:
138f6dfbefdSBarry Smith + kdm  - Original `DMSNES`
139f6dfbefdSBarry Smith - nkdm - `DMSNES` to receive the data, should have been created with `DMSNESCreate()`
14022c6f798SBarry Smith 
14122c6f798SBarry Smith   Level: developer
14222c6f798SBarry Smith 
143*420bcc1bSBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMSNESCreate()`, `DMSNESDestroy()`
14466976f2fSJacob Faibussowitsch */
14566976f2fSJacob Faibussowitsch static PetscErrorCode DMSNESCopy(DMSNES kdm, DMSNES nkdm)
146d71ae5a4SJacob Faibussowitsch {
14722c6f798SBarry Smith   PetscFunctionBegin;
14822c6f798SBarry Smith   PetscValidHeaderSpecific(kdm, DMSNES_CLASSID, 1);
14922c6f798SBarry Smith   PetscValidHeaderSpecific(nkdm, DMSNES_CLASSID, 2);
15022c6f798SBarry Smith   nkdm->ops->computefunction  = kdm->ops->computefunction;
1512bc4d0c4SPeter Brune   nkdm->ops->computejacobian  = kdm->ops->computejacobian;
15222c6f798SBarry Smith   nkdm->ops->computegs        = kdm->ops->computegs;
15322c6f798SBarry Smith   nkdm->ops->computeobjective = kdm->ops->computeobjective;
15422c6f798SBarry Smith   nkdm->ops->computepjacobian = kdm->ops->computepjacobian;
15522c6f798SBarry Smith   nkdm->ops->computepfunction = kdm->ops->computepfunction;
15622c6f798SBarry Smith   nkdm->ops->destroy          = kdm->ops->destroy;
15722c6f798SBarry Smith   nkdm->ops->duplicate        = kdm->ops->duplicate;
15822c6f798SBarry Smith 
15922c6f798SBarry Smith   nkdm->gsctx                = kdm->gsctx;
16022c6f798SBarry Smith   nkdm->pctx                 = kdm->pctx;
16122c6f798SBarry Smith   nkdm->objectivectx         = kdm->objectivectx;
162af903c1dSJunchao Zhang   nkdm->originaldm           = kdm->originaldm;
163800f99ffSJeremy L Thompson   nkdm->functionctxcontainer = kdm->functionctxcontainer;
164800f99ffSJeremy L Thompson   nkdm->jacobianctxcontainer = kdm->jacobianctxcontainer;
165800f99ffSJeremy L Thompson   if (nkdm->functionctxcontainer) PetscCall(PetscObjectCompose((PetscObject)nkdm, "function ctx", (PetscObject)nkdm->functionctxcontainer));
166800f99ffSJeremy L Thompson   if (nkdm->jacobianctxcontainer) PetscCall(PetscObjectCompose((PetscObject)nkdm, "jacobian ctx", (PetscObject)nkdm->jacobianctxcontainer));
16722c6f798SBarry Smith 
16822c6f798SBarry Smith   /*
16922c6f798SBarry Smith   nkdm->fortran_func_pointers[0] = kdm->fortran_func_pointers[0];
17022c6f798SBarry Smith   nkdm->fortran_func_pointers[1] = kdm->fortran_func_pointers[1];
17122c6f798SBarry Smith   nkdm->fortran_func_pointers[2] = kdm->fortran_func_pointers[2];
17222c6f798SBarry Smith   */
17322c6f798SBarry Smith 
17422c6f798SBarry Smith   /* implementation specific copy hooks */
175dbbe0bcdSBarry Smith   PetscTryTypeMethod(kdm, duplicate, nkdm);
1763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
17722c6f798SBarry Smith }
17822c6f798SBarry Smith 
1796cab3a1bSJed Brown /*@C
180f6dfbefdSBarry Smith   DMGetDMSNES - get read-only private `DMSNES` context from a `DM`
1816cab3a1bSJed Brown 
1826cab3a1bSJed Brown   Not Collective
1836cab3a1bSJed Brown 
1844165533cSJose E. Roman   Input Parameter:
185f6dfbefdSBarry Smith . dm - `DM` to be used with `SNES`
1866cab3a1bSJed Brown 
1874165533cSJose E. Roman   Output Parameter:
188f6dfbefdSBarry Smith . snesdm - private `DMSNES` context
1896cab3a1bSJed Brown 
1906cab3a1bSJed Brown   Level: developer
1916cab3a1bSJed Brown 
192f6dfbefdSBarry Smith   Note:
193f6dfbefdSBarry Smith   Use `DMGetDMSNESWrite()` if write access is needed. The DMSNESSetXXX API should be used wherever possible.
1946cab3a1bSJed Brown 
195*420bcc1bSBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMGetDMSNESWrite()`
1966cab3a1bSJed Brown @*/
197d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetDMSNES(DM dm, DMSNES *snesdm)
198d71ae5a4SJacob Faibussowitsch {
1996cab3a1bSJed Brown   PetscFunctionBegin;
2006cab3a1bSJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
201b4615a05SBarry Smith   *snesdm = (DMSNES)dm->dmsnes;
20222c6f798SBarry Smith   if (!*snesdm) {
2039566063dSJacob Faibussowitsch     PetscCall(PetscInfo(dm, "Creating new DMSNES\n"));
2049566063dSJacob Faibussowitsch     PetscCall(DMSNESCreate(PetscObjectComm((PetscObject)dm), snesdm));
2051aa26658SKarl Rupp 
206b4615a05SBarry Smith     dm->dmsnes            = (PetscObject)*snesdm;
207af903c1dSJunchao Zhang     (*snesdm)->originaldm = dm;
2089566063dSJacob Faibussowitsch     PetscCall(DMCoarsenHookAdd(dm, DMCoarsenHook_DMSNES, DMRestrictHook_DMSNES, NULL));
2099566063dSJacob Faibussowitsch     PetscCall(DMRefineHookAdd(dm, DMRefineHook_DMSNES, DMInterpolateHook_DMSNES, NULL));
2109566063dSJacob Faibussowitsch     PetscCall(DMSubDomainHookAdd(dm, DMSubDomainHook_DMSNES, DMSubDomainRestrictHook_DMSNES, NULL));
2116cab3a1bSJed Brown   }
2123ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2136cab3a1bSJed Brown }
2146cab3a1bSJed Brown 
2156cab3a1bSJed Brown /*@C
216f6dfbefdSBarry Smith   DMGetDMSNESWrite - get write access to private `DMSNES` context from a `DM`
2176cab3a1bSJed Brown 
2186cab3a1bSJed Brown   Not Collective
2196cab3a1bSJed Brown 
2204165533cSJose E. Roman   Input Parameter:
221f6dfbefdSBarry Smith . dm - `DM` to be used with `SNES`
2226cab3a1bSJed Brown 
2234165533cSJose E. Roman   Output Parameter:
224f6dfbefdSBarry Smith . snesdm - private `DMSNES` context
2256cab3a1bSJed Brown 
2266cab3a1bSJed Brown   Level: developer
2276cab3a1bSJed Brown 
228*420bcc1bSBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMGetDMSNES()`
2296cab3a1bSJed Brown @*/
230d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetDMSNESWrite(DM dm, DMSNES *snesdm)
231d71ae5a4SJacob Faibussowitsch {
232942e3340SBarry Smith   DMSNES sdm;
2336cab3a1bSJed Brown 
2346cab3a1bSJed Brown   PetscFunctionBegin;
2356cab3a1bSJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2369566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(dm, &sdm));
23728b400f6SJacob Faibussowitsch   PetscCheck(sdm->originaldm, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "DMSNES has a NULL originaldm");
2386cab3a1bSJed Brown   if (sdm->originaldm != dm) { /* Copy on write */
239b4615a05SBarry Smith     DMSNES oldsdm = sdm;
2409566063dSJacob Faibussowitsch     PetscCall(PetscInfo(dm, "Copying DMSNES due to write\n"));
2419566063dSJacob Faibussowitsch     PetscCall(DMSNESCreate(PetscObjectComm((PetscObject)dm), &sdm));
2429566063dSJacob Faibussowitsch     PetscCall(DMSNESCopy(oldsdm, sdm));
2439566063dSJacob Faibussowitsch     PetscCall(DMSNESDestroy((DMSNES *)&dm->dmsnes));
244b4615a05SBarry Smith     dm->dmsnes      = (PetscObject)sdm;
245af903c1dSJunchao Zhang     sdm->originaldm = dm;
2466cab3a1bSJed Brown   }
2476cab3a1bSJed Brown   *snesdm = sdm;
2483ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2496cab3a1bSJed Brown }
2506cab3a1bSJed Brown 
2516cab3a1bSJed Brown /*@C
252f6dfbefdSBarry Smith   DMCopyDMSNES - copies a `DMSNES` context to a new `DM`
2536cab3a1bSJed Brown 
2546cab3a1bSJed Brown   Logically Collective
2556cab3a1bSJed Brown 
2564165533cSJose E. Roman   Input Parameters:
257f6dfbefdSBarry Smith + dmsrc  - `DM` to obtain context from
258f6dfbefdSBarry Smith - dmdest - `DM` to add context to
2596cab3a1bSJed Brown 
2606cab3a1bSJed Brown   Level: developer
2616cab3a1bSJed Brown 
2626cab3a1bSJed Brown   Note:
2636cab3a1bSJed Brown   The context is copied by reference. This function does not ensure that a context exists.
2646cab3a1bSJed Brown 
265*420bcc1bSBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMGetDMSNES()`, `SNESSetDM()`
2666cab3a1bSJed Brown @*/
267d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCopyDMSNES(DM dmsrc, DM dmdest)
268d71ae5a4SJacob Faibussowitsch {
2696cab3a1bSJed Brown   PetscFunctionBegin;
2706cab3a1bSJed Brown   PetscValidHeaderSpecific(dmsrc, DM_CLASSID, 1);
2716cab3a1bSJed Brown   PetscValidHeaderSpecific(dmdest, DM_CLASSID, 2);
2729566063dSJacob Faibussowitsch   if (!dmdest->dmsnes) PetscCall(DMSNESCreate(PetscObjectComm((PetscObject)dmdest), (DMSNES *)&dmdest->dmsnes));
2739566063dSJacob Faibussowitsch   PetscCall(DMSNESCopy((DMSNES)dmsrc->dmsnes, (DMSNES)dmdest->dmsnes));
2749566063dSJacob Faibussowitsch   PetscCall(DMCoarsenHookAdd(dmdest, DMCoarsenHook_DMSNES, NULL, NULL));
2759566063dSJacob Faibussowitsch   PetscCall(DMRefineHookAdd(dmdest, DMRefineHook_DMSNES, NULL, NULL));
2769566063dSJacob Faibussowitsch   PetscCall(DMSubDomainHookAdd(dmdest, DMSubDomainHook_DMSNES, DMSubDomainRestrictHook_DMSNES, NULL));
2773ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2786cab3a1bSJed Brown }
2796cab3a1bSJed Brown 
2806cab3a1bSJed Brown /*@C
281f6dfbefdSBarry Smith   DMSNESSetFunction - set `SNES` residual evaluation function
2826cab3a1bSJed Brown 
2836cab3a1bSJed Brown   Not Collective
2846cab3a1bSJed Brown 
2854165533cSJose E. Roman   Input Parameters:
286f6dfbefdSBarry Smith + dm  - DM to be used with `SNES`
287f6dfbefdSBarry Smith . f   - residual evaluation function; see `SNESFunction` for details
2886cab3a1bSJed Brown - ctx - context for residual evaluation
2896cab3a1bSJed Brown 
2906cab3a1bSJed Brown   Level: advanced
2916cab3a1bSJed Brown 
2926cab3a1bSJed Brown   Note:
293f6dfbefdSBarry Smith   `SNESSetFunction()` is normally used, but it calls this function internally because the user context is actually
294f6dfbefdSBarry Smith   associated with the `DM`.  This makes the interface consistent regardless of whether the user interacts with a `DM` or
295f6dfbefdSBarry Smith   not.
296f6dfbefdSBarry Smith 
297*420bcc1bSBarry Smith   Developer Note:
298f6dfbefdSBarry Smith   If `DM` took a more central role at some later date, this could become the primary method of setting the residual.
2996cab3a1bSJed Brown 
300*420bcc1bSBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMSNESSetContext()`, `SNESSetFunction()`, `DMSNESSetJacobian()`, `SNESFunction`
3016cab3a1bSJed Brown @*/
302d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSNESSetFunction(DM dm, PetscErrorCode (*f)(SNES, Vec, Vec, void *), void *ctx)
303d71ae5a4SJacob Faibussowitsch {
304942e3340SBarry Smith   DMSNES sdm;
3056cab3a1bSJed Brown 
3066cab3a1bSJed Brown   PetscFunctionBegin;
3076cab3a1bSJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3089566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNESWrite(dm, &sdm));
309f8b49ee9SBarry Smith   if (f) sdm->ops->computefunction = f;
310800f99ffSJeremy L Thompson   if (ctx) {
311800f99ffSJeremy L Thompson     PetscContainer ctxcontainer;
312800f99ffSJeremy L Thompson     PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)sdm), &ctxcontainer));
313800f99ffSJeremy L Thompson     PetscCall(PetscContainerSetPointer(ctxcontainer, ctx));
314800f99ffSJeremy L Thompson     PetscCall(PetscObjectCompose((PetscObject)sdm, "function ctx", (PetscObject)ctxcontainer));
315800f99ffSJeremy L Thompson     sdm->functionctxcontainer = ctxcontainer;
316800f99ffSJeremy L Thompson     PetscCall(PetscContainerDestroy(&ctxcontainer));
317800f99ffSJeremy L Thompson   }
3183ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
319800f99ffSJeremy L Thompson }
320800f99ffSJeremy L Thompson 
321800f99ffSJeremy L Thompson /*@C
3225cb80ecdSBarry Smith   DMSNESSetFunctionContextDestroy - set `SNES` residual evaluation context destroy function
323800f99ffSJeremy L Thompson 
324800f99ffSJeremy L Thompson   Not Collective
325800f99ffSJeremy L Thompson 
326800f99ffSJeremy L Thompson   Input Parameters:
3275cb80ecdSBarry Smith + dm - `DM` to be used with `SNES`
3285cb80ecdSBarry Smith - f  - residual evaluation context destroy function
329800f99ffSJeremy L Thompson 
330800f99ffSJeremy L Thompson   Level: advanced
331800f99ffSJeremy L Thompson 
332*420bcc1bSBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMSNESSetFunction()`, `SNESSetFunction()`
333800f99ffSJeremy L Thompson @*/
334d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSNESSetFunctionContextDestroy(DM dm, PetscErrorCode (*f)(void *))
335d71ae5a4SJacob Faibussowitsch {
336800f99ffSJeremy L Thompson   DMSNES sdm;
337800f99ffSJeremy L Thompson 
338800f99ffSJeremy L Thompson   PetscFunctionBegin;
339800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
340800f99ffSJeremy L Thompson   PetscCall(DMGetDMSNESWrite(dm, &sdm));
341800f99ffSJeremy L Thompson   if (sdm->functionctxcontainer) PetscCall(PetscContainerSetUserDestroy(sdm->functionctxcontainer, f));
3423ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
343800f99ffSJeremy L Thompson }
344800f99ffSJeremy L Thompson 
345d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSNESUnsetFunctionContext_Internal(DM dm)
346d71ae5a4SJacob Faibussowitsch {
347800f99ffSJeremy L Thompson   DMSNES sdm;
348800f99ffSJeremy L Thompson 
349800f99ffSJeremy L Thompson   PetscFunctionBegin;
350800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
351800f99ffSJeremy L Thompson   PetscCall(DMGetDMSNESWrite(dm, &sdm));
352800f99ffSJeremy L Thompson   PetscCall(DMSNESUnsetFunctionContext_DMSNES(sdm));
3533ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3546cab3a1bSJed Brown }
3556cab3a1bSJed Brown 
3566cab3a1bSJed Brown /*@C
357f6dfbefdSBarry Smith   DMSNESSetMFFunction - set `SNES` residual evaluation function used in applying the matrix-free Jacobian with -snes_mf_operator
358bbc1464cSBarry Smith 
359c3339decSBarry Smith   Logically Collective
360bbc1464cSBarry Smith 
3614165533cSJose E. Roman   Input Parameters:
362f6dfbefdSBarry Smith + dm   - `DM` to be used with `SNES`
3630b4db180SJacob Faibussowitsch . func - residual evaluation function; see `SNESFunction` for details
3640b4db180SJacob Faibussowitsch - ctx  - optional function context
3650b4db180SJacob Faibussowitsch 
3660b4db180SJacob Faibussowitsch   Calling sequence of `func`:
3670b4db180SJacob Faibussowitsch + snes - the solver object
3680b4db180SJacob Faibussowitsch . x    - the input vector
3690b4db180SJacob Faibussowitsch . f    - the output vector
3700b4db180SJacob Faibussowitsch - ctx  - the optional function context
371bbc1464cSBarry Smith 
372bbc1464cSBarry Smith   Level: advanced
373bbc1464cSBarry Smith 
374*420bcc1bSBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMSNESSetContext()`, `SNESSetFunction()`, `DMSNESSetJacobian()`, `SNESFunction`, `DMSNESSetFunction()`
375bbc1464cSBarry Smith @*/
3760b4db180SJacob Faibussowitsch PetscErrorCode DMSNESSetMFFunction(DM dm, PetscErrorCode (*func)(SNES snes, Vec x, Vec f, void *ctx), void *ctx)
377d71ae5a4SJacob Faibussowitsch {
378bbc1464cSBarry Smith   DMSNES sdm;
379bbc1464cSBarry Smith 
380bbc1464cSBarry Smith   PetscFunctionBegin;
381bbc1464cSBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3820b4db180SJacob Faibussowitsch   if (func || ctx) PetscCall(DMGetDMSNESWrite(dm, &sdm));
3830b4db180SJacob Faibussowitsch   if (func) sdm->ops->computemffunction = func;
384bbc1464cSBarry Smith   if (ctx) sdm->mffunctionctx = ctx;
3853ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
386bbc1464cSBarry Smith }
387bbc1464cSBarry Smith 
388bbc1464cSBarry Smith /*@C
389f6dfbefdSBarry Smith   DMSNESGetFunction - get `SNES` residual evaluation function
3906cab3a1bSJed Brown 
3916cab3a1bSJed Brown   Not Collective
3926cab3a1bSJed Brown 
3934165533cSJose E. Roman   Input Parameter:
394f6dfbefdSBarry Smith . dm - `DM` to be used with `SNES`
3956cab3a1bSJed Brown 
3964165533cSJose E. Roman   Output Parameters:
397f6dfbefdSBarry Smith + f   - residual evaluation function; see `SNESFunction` for details
3986cab3a1bSJed Brown - ctx - context for residual evaluation
3996cab3a1bSJed Brown 
4006cab3a1bSJed Brown   Level: advanced
4016cab3a1bSJed Brown 
4026cab3a1bSJed Brown   Note:
403f6dfbefdSBarry Smith   `SNESGetFunction()` is normally used, but it calls this function internally because the user context is actually
404f6dfbefdSBarry Smith   associated with the `DM`.
4056cab3a1bSJed Brown 
406*420bcc1bSBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMSNESSetContext()`, `DMSNESSetFunction()`, `SNESSetFunction()`, `SNESFunction`
4076cab3a1bSJed Brown @*/
408d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSNESGetFunction(DM dm, PetscErrorCode (**f)(SNES, Vec, Vec, void *), void **ctx)
409d71ae5a4SJacob Faibussowitsch {
410942e3340SBarry Smith   DMSNES sdm;
4116cab3a1bSJed Brown 
4126cab3a1bSJed Brown   PetscFunctionBegin;
4136cab3a1bSJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4149566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(dm, &sdm));
415f8b49ee9SBarry Smith   if (f) *f = sdm->ops->computefunction;
416800f99ffSJeremy L Thompson   if (ctx) {
417800f99ffSJeremy L Thompson     if (sdm->functionctxcontainer) PetscCall(PetscContainerGetPointer(sdm->functionctxcontainer, ctx));
418800f99ffSJeremy L Thompson     else *ctx = NULL;
419800f99ffSJeremy L Thompson   }
4203ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4216cab3a1bSJed Brown }
4226cab3a1bSJed Brown 
4232a4ee8f2SPeter Brune /*@C
424f6dfbefdSBarry Smith   DMSNESSetObjective - set `SNES` objective evaluation function
4252a4ee8f2SPeter Brune 
4262a4ee8f2SPeter Brune   Not Collective
4272a4ee8f2SPeter Brune 
4284165533cSJose E. Roman   Input Parameters:
429f6dfbefdSBarry Smith + dm  - `DM` to be used with `SNES`
430f6dfbefdSBarry Smith . obj - objective evaluation function; see `SNESObjectiveFunction` for details
4312a4ee8f2SPeter Brune - ctx - context for residual evaluation
4322a4ee8f2SPeter Brune 
4332a4ee8f2SPeter Brune   Level: advanced
4342a4ee8f2SPeter Brune 
435*420bcc1bSBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMSNESSetContext()`, `SNESGetObjective()`, `DMSNESSetFunction()`
4362a4ee8f2SPeter Brune @*/
437d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSNESSetObjective(DM dm, PetscErrorCode (*obj)(SNES, Vec, PetscReal *, void *), void *ctx)
438d71ae5a4SJacob Faibussowitsch {
439942e3340SBarry Smith   DMSNES sdm;
4402a4ee8f2SPeter Brune 
4412a4ee8f2SPeter Brune   PetscFunctionBegin;
4422a4ee8f2SPeter Brune   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
44348a46eb9SPierre Jolivet   if (obj || ctx) PetscCall(DMGetDMSNESWrite(dm, &sdm));
444f8b49ee9SBarry Smith   if (obj) sdm->ops->computeobjective = obj;
4452a4ee8f2SPeter Brune   if (ctx) sdm->objectivectx = ctx;
4463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4472a4ee8f2SPeter Brune }
4482a4ee8f2SPeter Brune 
4492a4ee8f2SPeter Brune /*@C
450f6dfbefdSBarry Smith   DMSNESGetObjective - get `SNES` objective evaluation function
4512a4ee8f2SPeter Brune 
4522a4ee8f2SPeter Brune   Not Collective
4532a4ee8f2SPeter Brune 
4544165533cSJose E. Roman   Input Parameter:
455f6dfbefdSBarry Smith . dm - `DM` to be used with `SNES`
4562a4ee8f2SPeter Brune 
4574165533cSJose E. Roman   Output Parameters:
458f6dfbefdSBarry 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:
464f6dfbefdSBarry Smith   `SNESGetFunction()` is normally used, but it calls this function internally because the user context is actually
465f6dfbefdSBarry Smith   associated with the `DM`.
4662a4ee8f2SPeter Brune 
467*420bcc1bSBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMSNESSetContext()`, `DMSNESSetObjective()`, `SNESSetFunction()`
4682a4ee8f2SPeter Brune @*/
469d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSNESGetObjective(DM dm, PetscErrorCode (**obj)(SNES, Vec, PetscReal *, void *), void **ctx)
470d71ae5a4SJacob Faibussowitsch {
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;
4783ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4792a4ee8f2SPeter Brune }
4802a4ee8f2SPeter Brune 
4816cab3a1bSJed Brown /*@C
482f6dfbefdSBarry Smith   DMSNESSetNGS - set `SNES` Gauss-Seidel relaxation function
4836cab3a1bSJed Brown 
4846cab3a1bSJed Brown   Not Collective
4856cab3a1bSJed Brown 
4864165533cSJose E. Roman   Input Parameters:
487f6dfbefdSBarry Smith + dm  - `DM` to be used with `SNES`
488f6dfbefdSBarry Smith . f   - relaxation function, see `SNESGSFunction`
4896cab3a1bSJed Brown - ctx - context for residual evaluation
4906cab3a1bSJed Brown 
4916cab3a1bSJed Brown   Level: advanced
4926cab3a1bSJed Brown 
4936cab3a1bSJed Brown   Note:
494f6dfbefdSBarry Smith   `SNESSetNGS()` is normally used, but it calls this function internally because the user context is actually
495f6dfbefdSBarry Smith   associated with the `DM`.  This makes the interface consistent regardless of whether the user interacts with a `DM` or
496f6dfbefdSBarry Smith   not.
497f6dfbefdSBarry Smith 
498*420bcc1bSBarry Smith   Developer Note:
499f6dfbefdSBarry Smith   If `DM` took a more central role at some later date, this could become the primary method of supplying the smoother
5006cab3a1bSJed Brown 
501*420bcc1bSBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMSNESSetContext()`, `SNESSetFunction()`, `DMSNESSetJacobian()`, `DMSNESSetFunction()`, `SNESGSFunction`
5026cab3a1bSJed Brown @*/
503d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSNESSetNGS(DM dm, PetscErrorCode (*f)(SNES, Vec, Vec, void *), void *ctx)
504d71ae5a4SJacob Faibussowitsch {
505942e3340SBarry Smith   DMSNES sdm;
5066cab3a1bSJed Brown 
5076cab3a1bSJed Brown   PetscFunctionBegin;
5086cab3a1bSJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
50948a46eb9SPierre Jolivet   if (f || ctx) PetscCall(DMGetDMSNESWrite(dm, &sdm));
510be95d8f1SBarry Smith   if (f) sdm->ops->computegs = f;
5116cab3a1bSJed Brown   if (ctx) sdm->gsctx = ctx;
5123ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5136cab3a1bSJed Brown }
5146cab3a1bSJed Brown 
5156cab3a1bSJed Brown /*@C
516f6dfbefdSBarry Smith   DMSNESGetNGS - get `SNES` Gauss-Seidel relaxation function
5176cab3a1bSJed Brown 
5186cab3a1bSJed Brown   Not Collective
5196cab3a1bSJed Brown 
5204165533cSJose E. Roman   Input Parameter:
521f6dfbefdSBarry Smith . dm - `DM` to be used with `SNES`
5226cab3a1bSJed Brown 
5234165533cSJose E. Roman   Output Parameters:
52437fdd005SBarry Smith + f   - relaxation function which performs Gauss-Seidel sweeps, see `SNESSetNGS()`
5256cab3a1bSJed Brown - ctx - context for residual evaluation
5266cab3a1bSJed Brown 
5276cab3a1bSJed Brown   Level: advanced
5286cab3a1bSJed Brown 
5296cab3a1bSJed Brown   Note:
530f6dfbefdSBarry Smith   `SNESGetNGS()` is normally used, but it calls this function internally because the user context is actually
531f6dfbefdSBarry Smith   associated with the `DM`.
532f6dfbefdSBarry Smith 
533*420bcc1bSBarry Smith   Developer Note:
534f6dfbefdSBarry Smith   This makes the interface consistent regardless of whether the user interacts with a `DM` or
535f6dfbefdSBarry Smith   not. If `DM` took a more central role at some later date, this could become the primary method of setting the residual.
5366cab3a1bSJed Brown 
537*420bcc1bSBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMSNESSetContext()`, `SNESGetNGS()`, `DMSNESGetJacobian()`, `DMSNESGetFunction()`
5386cab3a1bSJed Brown @*/
539d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSNESGetNGS(DM dm, PetscErrorCode (**f)(SNES, Vec, Vec, void *), void **ctx)
540d71ae5a4SJacob Faibussowitsch {
541942e3340SBarry Smith   DMSNES sdm;
5426cab3a1bSJed Brown 
5436cab3a1bSJed Brown   PetscFunctionBegin;
5446cab3a1bSJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5459566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(dm, &sdm));
546be95d8f1SBarry Smith   if (f) *f = sdm->ops->computegs;
5476cab3a1bSJed Brown   if (ctx) *ctx = sdm->gsctx;
5483ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5496cab3a1bSJed Brown }
5506cab3a1bSJed Brown 
5516cab3a1bSJed Brown /*@C
552f6dfbefdSBarry Smith   DMSNESSetJacobian - set `SNES` Jacobian evaluation function
5536cab3a1bSJed Brown 
5546cab3a1bSJed Brown   Not Collective
5556cab3a1bSJed Brown 
5564165533cSJose E. Roman   Input Parameters:
557f6dfbefdSBarry Smith + dm  - `DM` to be used with `SNES`
558f8b49ee9SBarry Smith . J   - Jacobian evaluation function
5596cab3a1bSJed Brown - ctx - context for residual evaluation
5606cab3a1bSJed Brown 
5616cab3a1bSJed Brown   Level: advanced
5626cab3a1bSJed Brown 
5636cab3a1bSJed Brown   Note:
564f6dfbefdSBarry Smith   `SNESSetJacobian()` is normally used, but it calls this function internally because the user context is actually
565f6dfbefdSBarry Smith   associated with the `DM`.
566f6dfbefdSBarry Smith 
567*420bcc1bSBarry Smith   Developer Note:
568f6dfbefdSBarry Smith   This makes the interface consistent regardless of whether the user interacts with a `DM` or
569f6dfbefdSBarry Smith   not. If `DM` took a more central role at some later date, this could become the primary method of setting the Jacobian.
5706cab3a1bSJed Brown 
571*420bcc1bSBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMSNESSetContext()`, `SNESSetFunction()`, `DMSNESGetJacobian()`, `SNESSetJacobian()`, `SNESJacobianFunction`
5726cab3a1bSJed Brown @*/
573d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSNESSetJacobian(DM dm, PetscErrorCode (*J)(SNES, Vec, Mat, Mat, void *), void *ctx)
574d71ae5a4SJacob Faibussowitsch {
575942e3340SBarry Smith   DMSNES sdm;
5766cab3a1bSJed Brown 
5776cab3a1bSJed Brown   PetscFunctionBegin;
5786cab3a1bSJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
579800f99ffSJeremy L Thompson   if (J || ctx) PetscCall(DMGetDMSNESWrite(dm, &sdm));
580f8b49ee9SBarry Smith   if (J) sdm->ops->computejacobian = J;
581800f99ffSJeremy L Thompson   if (ctx) {
582800f99ffSJeremy L Thompson     PetscContainer ctxcontainer;
583800f99ffSJeremy L Thompson     PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)sdm), &ctxcontainer));
584800f99ffSJeremy L Thompson     PetscCall(PetscContainerSetPointer(ctxcontainer, ctx));
585800f99ffSJeremy L Thompson     PetscCall(PetscObjectCompose((PetscObject)sdm, "jacobian ctx", (PetscObject)ctxcontainer));
586800f99ffSJeremy L Thompson     sdm->jacobianctxcontainer = ctxcontainer;
587800f99ffSJeremy L Thompson     PetscCall(PetscContainerDestroy(&ctxcontainer));
588800f99ffSJeremy L Thompson   }
5893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
590800f99ffSJeremy L Thompson }
591800f99ffSJeremy L Thompson 
592800f99ffSJeremy L Thompson /*@C
5935cb80ecdSBarry Smith   DMSNESSetJacobianContextDestroy - set `SNES` Jacobian evaluation context destroy function
594800f99ffSJeremy L Thompson 
595800f99ffSJeremy L Thompson   Not Collective
596800f99ffSJeremy L Thompson 
597800f99ffSJeremy L Thompson   Input Parameters:
5985cb80ecdSBarry Smith + dm - `DM` to be used with `SNES`
59935cb6cd3SPierre Jolivet - f  - Jacobian evaluation context destroy function
600800f99ffSJeremy L Thompson 
601800f99ffSJeremy L Thompson   Level: advanced
602800f99ffSJeremy L Thompson 
603*420bcc1bSBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMSNESSetJacobian()`
604800f99ffSJeremy L Thompson @*/
605d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSNESSetJacobianContextDestroy(DM dm, PetscErrorCode (*f)(void *))
606d71ae5a4SJacob Faibussowitsch {
607800f99ffSJeremy L Thompson   DMSNES sdm;
608800f99ffSJeremy L Thompson 
609800f99ffSJeremy L Thompson   PetscFunctionBegin;
610800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
611800f99ffSJeremy L Thompson   PetscCall(DMGetDMSNESWrite(dm, &sdm));
612800f99ffSJeremy L Thompson   if (sdm->jacobianctxcontainer) PetscCall(PetscContainerSetUserDestroy(sdm->jacobianctxcontainer, f));
6133ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
614800f99ffSJeremy L Thompson }
615800f99ffSJeremy L Thompson 
616d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSNESUnsetJacobianContext_Internal(DM dm)
617d71ae5a4SJacob Faibussowitsch {
618800f99ffSJeremy L Thompson   DMSNES sdm;
619800f99ffSJeremy L Thompson 
620800f99ffSJeremy L Thompson   PetscFunctionBegin;
621800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
622800f99ffSJeremy L Thompson   PetscCall(DMGetDMSNESWrite(dm, &sdm));
623800f99ffSJeremy L Thompson   PetscCall(DMSNESUnsetJacobianContext_DMSNES(sdm));
6243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6256cab3a1bSJed Brown }
6266cab3a1bSJed Brown 
6276cab3a1bSJed Brown /*@C
628f6dfbefdSBarry Smith   DMSNESGetJacobian - get `SNES` Jacobian evaluation function
6296cab3a1bSJed Brown 
6306cab3a1bSJed Brown   Not Collective
6316cab3a1bSJed Brown 
6324165533cSJose E. Roman   Input Parameter:
633f6dfbefdSBarry Smith . dm - `DM` to be used with `SNES`
6346cab3a1bSJed Brown 
6354165533cSJose E. Roman   Output Parameters:
63620f4b53cSBarry Smith + J   - Jacobian evaluation function; for all calling sequence see `SNESJacobianFunction`
6376cab3a1bSJed Brown - ctx - context for residual evaluation
6386cab3a1bSJed Brown 
6396cab3a1bSJed Brown   Level: advanced
6406cab3a1bSJed Brown 
6416cab3a1bSJed Brown   Note:
642f6dfbefdSBarry Smith   `SNESGetJacobian()` is normally used, but it calls this function internally because the user context is actually
643f6dfbefdSBarry Smith   associated with the `DM`.  This makes the interface consistent regardless of whether the user interacts with a `DM` or
644f6dfbefdSBarry Smith   not.
645f6dfbefdSBarry Smith 
646*420bcc1bSBarry Smith   Developer Note:
647f6dfbefdSBarry Smith   If `DM` took a more central role at some later date, this could become the primary method of setting the Jacobian.
6486cab3a1bSJed Brown 
649*420bcc1bSBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMSNESSetContext()`, `SNESSetFunction()`, `DMSNESSetJacobian()`, `SNESJacobianFunction`
6506cab3a1bSJed Brown @*/
651d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSNESGetJacobian(DM dm, PetscErrorCode (**J)(SNES, Vec, Mat, Mat, void *), void **ctx)
652d71ae5a4SJacob Faibussowitsch {
653942e3340SBarry Smith   DMSNES sdm;
6546cab3a1bSJed Brown 
6556cab3a1bSJed Brown   PetscFunctionBegin;
6566cab3a1bSJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6579566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(dm, &sdm));
658f8b49ee9SBarry Smith   if (J) *J = sdm->ops->computejacobian;
659800f99ffSJeremy L Thompson   if (ctx) {
660800f99ffSJeremy L Thompson     if (sdm->jacobianctxcontainer) PetscCall(PetscContainerGetPointer(sdm->jacobianctxcontainer, ctx));
661800f99ffSJeremy L Thompson     else *ctx = NULL;
662800f99ffSJeremy L Thompson   }
6633ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6646cab3a1bSJed Brown }
6656cab3a1bSJed Brown 
666e03ab78fSPeter Brune /*@C
667e03ab78fSPeter Brune   DMSNESSetPicard - set SNES Picard iteration matrix and RHS evaluation functions.
668e03ab78fSPeter Brune 
669e03ab78fSPeter Brune   Not Collective
670e03ab78fSPeter Brune 
6714165533cSJose E. Roman   Input Parameters:
672f6dfbefdSBarry Smith + dm  - `DM` to be used with `SNES`
673*420bcc1bSBarry Smith . b   - RHS evaluation function; see `SNESFunction` for calling sequence
674*420bcc1bSBarry Smith . J   - Picard matrix evaluation function; see `SNESJacobianFunction` for calling sequence
675*420bcc1bSBarry Smith - ctx - context for residual and matrix evaluation
676e03ab78fSPeter Brune 
677e03ab78fSPeter Brune   Level: advanced
678e03ab78fSPeter Brune 
679*420bcc1bSBarry Smith .seealso: [](ch_snes), `DMSNES`, `SNESSetPicard()`, `DMSNESSetFunction()`, `DMSNESSetJacobian()`
680e03ab78fSPeter Brune @*/
681d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSNESSetPicard(DM dm, PetscErrorCode (*b)(SNES, Vec, Vec, void *), PetscErrorCode (*J)(SNES, Vec, Mat, Mat, void *), void *ctx)
682d71ae5a4SJacob Faibussowitsch {
683942e3340SBarry Smith   DMSNES sdm;
684e03ab78fSPeter Brune 
685e03ab78fSPeter Brune   PetscFunctionBegin;
686e03ab78fSPeter Brune   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6879566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(dm, &sdm));
688f8b49ee9SBarry Smith   if (b) sdm->ops->computepfunction = b;
689f8b49ee9SBarry Smith   if (J) sdm->ops->computepjacobian = J;
690e03ab78fSPeter Brune   if (ctx) sdm->pctx = ctx;
6913ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
692e03ab78fSPeter Brune }
693e03ab78fSPeter Brune 
6947971a8bfSPeter Brune /*@C
695f6dfbefdSBarry Smith   DMSNESGetPicard - get `SNES` Picard iteration evaluation functions
6967971a8bfSPeter Brune 
6977971a8bfSPeter Brune   Not Collective
6987971a8bfSPeter Brune 
6994165533cSJose E. Roman   Input Parameter:
700f6dfbefdSBarry Smith . dm - `DM` to be used with `SNES`
7017971a8bfSPeter Brune 
7024165533cSJose E. Roman   Output Parameters:
703*420bcc1bSBarry Smith + b   - RHS evaluation function; see `SNESFunction` for calling sequence
704*420bcc1bSBarry Smith . J   - Jacobian evaluation function; see `SNESJacobianFunction` for calling sequence
705*420bcc1bSBarry Smith - ctx - context for residual and matrix evaluation
7067971a8bfSPeter Brune 
7077971a8bfSPeter Brune   Level: advanced
7087971a8bfSPeter Brune 
709*420bcc1bSBarry Smith .seealso: [](ch_snes), `DMSNES`, `DMSNESSetContext()`, `SNESSetFunction()`, `DMSNESSetJacobian()`
7107971a8bfSPeter Brune @*/
711d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSNESGetPicard(DM dm, PetscErrorCode (**b)(SNES, Vec, Vec, void *), PetscErrorCode (**J)(SNES, Vec, Mat, Mat, void *), void **ctx)
712d71ae5a4SJacob Faibussowitsch {
713942e3340SBarry Smith   DMSNES sdm;
7147971a8bfSPeter Brune 
7157971a8bfSPeter Brune   PetscFunctionBegin;
7167971a8bfSPeter Brune   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7179566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(dm, &sdm));
718f8b49ee9SBarry Smith   if (b) *b = sdm->ops->computepfunction;
719f8b49ee9SBarry Smith   if (J) *J = sdm->ops->computepjacobian;
7207971a8bfSPeter Brune   if (ctx) *ctx = sdm->pctx;
7213ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7227971a8bfSPeter Brune }
723