xref: /petsc/src/ts/utils/dmts.c (revision 48a46eb9bd028bec07ec0f396b1a3abb43f14558)
1af0996ceSBarry Smith #include <petsc/private/tsimpl.h> /*I "petscts.h" I*/
2af0996ceSBarry Smith #include <petsc/private/dmimpl.h>
324989b8cSPeter Brune 
49371c9d4SSatish Balay static PetscErrorCode DMTSUnsetRHSFunctionContext_DMTS(DMTS tsdm) {
5800f99ffSJeremy L Thompson   PetscFunctionBegin;
6800f99ffSJeremy L Thompson   PetscCall(PetscObjectCompose((PetscObject)tsdm, "rhs function ctx", NULL));
7800f99ffSJeremy L Thompson   tsdm->rhsfunctionctxcontainer = NULL;
8800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
9800f99ffSJeremy L Thompson }
10800f99ffSJeremy L Thompson 
119371c9d4SSatish Balay static PetscErrorCode DMTSUnsetRHSJacobianContext_DMTS(DMTS tsdm) {
12800f99ffSJeremy L Thompson   PetscFunctionBegin;
13800f99ffSJeremy L Thompson   PetscCall(PetscObjectCompose((PetscObject)tsdm, "rhs jacobian ctx", NULL));
14800f99ffSJeremy L Thompson   tsdm->rhsjacobianctxcontainer = NULL;
15800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
16800f99ffSJeremy L Thompson }
17800f99ffSJeremy L Thompson 
189371c9d4SSatish Balay static PetscErrorCode DMTSUnsetIFunctionContext_DMTS(DMTS tsdm) {
19800f99ffSJeremy L Thompson   PetscFunctionBegin;
20800f99ffSJeremy L Thompson   PetscCall(PetscObjectCompose((PetscObject)tsdm, "ifunction ctx", NULL));
21800f99ffSJeremy L Thompson   tsdm->ifunctionctxcontainer = NULL;
22800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
23800f99ffSJeremy L Thompson }
24800f99ffSJeremy L Thompson 
259371c9d4SSatish Balay static PetscErrorCode DMTSUnsetIJacobianContext_DMTS(DMTS tsdm) {
26800f99ffSJeremy L Thompson   PetscFunctionBegin;
27800f99ffSJeremy L Thompson   PetscCall(PetscObjectCompose((PetscObject)tsdm, "ijacobian ctx", NULL));
28800f99ffSJeremy L Thompson   tsdm->ijacobianctxcontainer = NULL;
29800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
30800f99ffSJeremy L Thompson }
31800f99ffSJeremy L Thompson 
329371c9d4SSatish Balay static PetscErrorCode DMTSUnsetI2FunctionContext_DMTS(DMTS tsdm) {
33800f99ffSJeremy L Thompson   PetscFunctionBegin;
34800f99ffSJeremy L Thompson   PetscCall(PetscObjectCompose((PetscObject)tsdm, "i2function ctx", NULL));
35800f99ffSJeremy L Thompson   tsdm->i2functionctxcontainer = NULL;
36800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
37800f99ffSJeremy L Thompson }
38800f99ffSJeremy L Thompson 
399371c9d4SSatish Balay static PetscErrorCode DMTSUnsetI2JacobianContext_DMTS(DMTS tsdm) {
40800f99ffSJeremy L Thompson   PetscFunctionBegin;
41800f99ffSJeremy L Thompson   PetscCall(PetscObjectCompose((PetscObject)tsdm, "i2jacobian ctx", NULL));
42800f99ffSJeremy L Thompson   tsdm->i2jacobianctxcontainer = NULL;
43800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
44800f99ffSJeremy L Thompson }
45800f99ffSJeremy L Thompson 
469371c9d4SSatish Balay static PetscErrorCode DMTSDestroy(DMTS *kdm) {
47d74926cbSBarry Smith   PetscFunctionBegin;
48d74926cbSBarry Smith   if (!*kdm) PetscFunctionReturn(0);
49d74926cbSBarry Smith   PetscValidHeaderSpecific((*kdm), DMTS_CLASSID, 1);
509371c9d4SSatish Balay   if (--((PetscObject)(*kdm))->refct > 0) {
519371c9d4SSatish Balay     *kdm = NULL;
529371c9d4SSatish Balay     PetscFunctionReturn(0);
539371c9d4SSatish Balay   }
54800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetRHSFunctionContext_DMTS(*kdm));
55800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetRHSJacobianContext_DMTS(*kdm));
56800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetIFunctionContext_DMTS(*kdm));
57800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetIJacobianContext_DMTS(*kdm));
58800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetI2FunctionContext_DMTS(*kdm));
59800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetI2JacobianContext_DMTS(*kdm));
60dbbe0bcdSBarry Smith   PetscTryTypeMethod(*kdm, destroy);
619566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(kdm));
62d74926cbSBarry Smith   PetscFunctionReturn(0);
63d74926cbSBarry Smith }
64d74926cbSBarry Smith 
659371c9d4SSatish Balay PetscErrorCode DMTSLoad(DMTS kdm, PetscViewer viewer) {
662d53ad75SBarry Smith   PetscFunctionBegin;
679566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer, &kdm->ops->ifunction, 1, NULL, PETSC_FUNCTION));
689566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer, &kdm->ops->ifunctionview, 1, NULL, PETSC_FUNCTION));
699566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer, &kdm->ops->ifunctionload, 1, NULL, PETSC_FUNCTION));
70ad6bc421SBarry Smith   if (kdm->ops->ifunctionload) {
71800f99ffSJeremy L Thompson     void *ctx;
72800f99ffSJeremy L Thompson 
73800f99ffSJeremy L Thompson     PetscCall(PetscContainerGetPointer(kdm->ifunctionctxcontainer, &ctx));
74800f99ffSJeremy L Thompson     PetscCall((*kdm->ops->ifunctionload)(&ctx, viewer));
75ad6bc421SBarry Smith   }
769566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer, &kdm->ops->ijacobian, 1, NULL, PETSC_FUNCTION));
779566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer, &kdm->ops->ijacobianview, 1, NULL, PETSC_FUNCTION));
789566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer, &kdm->ops->ijacobianload, 1, NULL, PETSC_FUNCTION));
79ad6bc421SBarry Smith   if (kdm->ops->ijacobianload) {
80800f99ffSJeremy L Thompson     void *ctx;
81800f99ffSJeremy L Thompson 
82800f99ffSJeremy L Thompson     PetscCall(PetscContainerGetPointer(kdm->ijacobianctxcontainer, &ctx));
83800f99ffSJeremy L Thompson     PetscCall((*kdm->ops->ijacobianload)(&ctx, viewer));
84ad6bc421SBarry Smith   }
852d53ad75SBarry Smith   PetscFunctionReturn(0);
862d53ad75SBarry Smith }
872d53ad75SBarry Smith 
889371c9d4SSatish Balay PetscErrorCode DMTSView(DMTS kdm, PetscViewer viewer) {
892d53ad75SBarry Smith   PetscBool isascii, isbinary;
902d53ad75SBarry Smith 
912d53ad75SBarry Smith   PetscFunctionBegin;
929566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
939566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
942d53ad75SBarry Smith   if (isascii) {
95c7a10e08SBarry Smith #if defined(PETSC_SERIALIZE_FUNCTIONS)
962d53ad75SBarry Smith     const char *fname;
972d53ad75SBarry Smith 
989566063dSJacob Faibussowitsch     PetscCall(PetscFPTFind(kdm->ops->ifunction, &fname));
99*48a46eb9SPierre Jolivet     if (fname) PetscCall(PetscViewerASCIIPrintf(viewer, "  IFunction used by TS: %s\n", fname));
1009566063dSJacob Faibussowitsch     PetscCall(PetscFPTFind(kdm->ops->ijacobian, &fname));
101*48a46eb9SPierre Jolivet     if (fname) PetscCall(PetscViewerASCIIPrintf(viewer, "  IJacobian function used by TS: %s\n", fname));
102c7a10e08SBarry Smith #endif
1032d53ad75SBarry Smith   } else if (isbinary) {
1043964eb88SJed Brown     struct {
1053964eb88SJed Brown       TSIFunction ifunction;
1069200755eSBarry Smith     } funcstruct;
1079200755eSBarry Smith     struct {
1083964eb88SJed Brown       PetscErrorCode (*ifunctionview)(void *, PetscViewer);
1099200755eSBarry Smith     } funcviewstruct;
1109200755eSBarry Smith     struct {
1113964eb88SJed Brown       PetscErrorCode (*ifunctionload)(void **, PetscViewer);
1129200755eSBarry Smith     } funcloadstruct;
1133964eb88SJed Brown     struct {
1143964eb88SJed Brown       TSIJacobian ijacobian;
1159200755eSBarry Smith     } jacstruct;
1169200755eSBarry Smith     struct {
1173964eb88SJed Brown       PetscErrorCode (*ijacobianview)(void *, PetscViewer);
1189200755eSBarry Smith     } jacviewstruct;
1199200755eSBarry Smith     struct {
1203964eb88SJed Brown       PetscErrorCode (*ijacobianload)(void **, PetscViewer);
1219200755eSBarry Smith     } jacloadstruct;
1223964eb88SJed Brown 
1239200755eSBarry Smith     funcstruct.ifunction         = kdm->ops->ifunction;
1249200755eSBarry Smith     funcviewstruct.ifunctionview = kdm->ops->ifunctionview;
1259200755eSBarry Smith     funcloadstruct.ifunctionload = kdm->ops->ifunctionload;
1269566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWrite(viewer, &funcstruct, 1, PETSC_FUNCTION));
1279566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWrite(viewer, &funcviewstruct, 1, PETSC_FUNCTION));
1289566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWrite(viewer, &funcloadstruct, 1, PETSC_FUNCTION));
129800f99ffSJeremy L Thompson     if (kdm->ops->ifunctionview) {
130800f99ffSJeremy L Thompson       void *ctx;
131800f99ffSJeremy L Thompson 
132800f99ffSJeremy L Thompson       PetscCall(PetscContainerGetPointer(kdm->ifunctionctxcontainer, &ctx));
133800f99ffSJeremy L Thompson       PetscCall((*kdm->ops->ifunctionview)(ctx, viewer));
134800f99ffSJeremy L Thompson     }
1359200755eSBarry Smith     jacstruct.ijacobian         = kdm->ops->ijacobian;
1369200755eSBarry Smith     jacviewstruct.ijacobianview = kdm->ops->ijacobianview;
1379200755eSBarry Smith     jacloadstruct.ijacobianload = kdm->ops->ijacobianload;
1389566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWrite(viewer, &jacstruct, 1, PETSC_FUNCTION));
1399566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWrite(viewer, &jacviewstruct, 1, PETSC_FUNCTION));
1409566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWrite(viewer, &jacloadstruct, 1, PETSC_FUNCTION));
141800f99ffSJeremy L Thompson     if (kdm->ops->ijacobianview) {
142800f99ffSJeremy L Thompson       void *ctx;
143800f99ffSJeremy L Thompson 
144800f99ffSJeremy L Thompson       PetscCall(PetscContainerGetPointer(kdm->ijacobianctxcontainer, &ctx));
145800f99ffSJeremy L Thompson       PetscCall((*kdm->ops->ijacobianview)(ctx, viewer));
146800f99ffSJeremy L Thompson     }
1472d53ad75SBarry Smith   }
1482d53ad75SBarry Smith   PetscFunctionReturn(0);
1492d53ad75SBarry Smith }
1502d53ad75SBarry Smith 
1519371c9d4SSatish Balay static PetscErrorCode DMTSCreate(MPI_Comm comm, DMTS *kdm) {
152d74926cbSBarry Smith   PetscFunctionBegin;
1539566063dSJacob Faibussowitsch   PetscCall(TSInitializePackage());
1549566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(*kdm, DMTS_CLASSID, "DMTS", "DMTS", "DMTS", comm, DMTSDestroy, DMTSView));
155d74926cbSBarry Smith   PetscFunctionReturn(0);
156d74926cbSBarry Smith }
15724989b8cSPeter Brune 
1582a34c10cSBarry Smith /* Attaches the DMTS to the coarse level.
15924989b8cSPeter Brune  * Under what conditions should we copy versus duplicate?
16024989b8cSPeter Brune  */
1619371c9d4SSatish Balay static PetscErrorCode DMCoarsenHook_DMTS(DM dm, DM dmc, void *ctx) {
16224989b8cSPeter Brune   PetscFunctionBegin;
1639566063dSJacob Faibussowitsch   PetscCall(DMCopyDMTS(dm, dmc));
16424989b8cSPeter Brune   PetscFunctionReturn(0);
16524989b8cSPeter Brune }
16624989b8cSPeter Brune 
16724989b8cSPeter Brune /* This could restrict auxiliary information to the coarse level.
16824989b8cSPeter Brune  */
1699371c9d4SSatish Balay static PetscErrorCode DMRestrictHook_DMTS(DM dm, Mat Restrict, Vec rscale, Mat Inject, DM dmc, void *ctx) {
17024989b8cSPeter Brune   PetscFunctionBegin;
17124989b8cSPeter Brune   PetscFunctionReturn(0);
17224989b8cSPeter Brune }
17324989b8cSPeter Brune 
1749371c9d4SSatish Balay static PetscErrorCode DMSubDomainHook_DMTS(DM dm, DM subdm, void *ctx) {
175258e1594SPeter Brune   PetscFunctionBegin;
1769566063dSJacob Faibussowitsch   PetscCall(DMCopyDMTS(dm, subdm));
177258e1594SPeter Brune   PetscFunctionReturn(0);
178258e1594SPeter Brune }
179258e1594SPeter Brune 
180258e1594SPeter Brune /* This could restrict auxiliary information to the coarse level.
181258e1594SPeter Brune  */
1829371c9d4SSatish Balay static PetscErrorCode DMSubDomainRestrictHook_DMTS(DM dm, VecScatter gscat, VecScatter lscat, DM subdm, void *ctx) {
183258e1594SPeter Brune   PetscFunctionBegin;
184258e1594SPeter Brune   PetscFunctionReturn(0);
185258e1594SPeter Brune }
186258e1594SPeter Brune 
187d74926cbSBarry Smith /*@C
188d74926cbSBarry Smith    DMTSCopy - copies the information in a DMTS to another DMTS
189d74926cbSBarry Smith 
190d74926cbSBarry Smith    Not Collective
191d74926cbSBarry Smith 
1924165533cSJose E. Roman    Input Parameters:
193d74926cbSBarry Smith +  kdm - Original DMTS
194d74926cbSBarry Smith -  nkdm - DMTS to receive the data, should have been created with DMTSCreate()
195d74926cbSBarry Smith 
196d74926cbSBarry Smith    Level: developer
197d74926cbSBarry Smith 
198db781477SPatrick Sanan .seealso: `DMTSCreate()`, `DMTSDestroy()`
199d74926cbSBarry Smith @*/
2009371c9d4SSatish Balay PetscErrorCode DMTSCopy(DMTS kdm, DMTS nkdm) {
20124989b8cSPeter Brune   PetscFunctionBegin;
202d74926cbSBarry Smith   PetscValidHeaderSpecific(kdm, DMTS_CLASSID, 1);
203d74926cbSBarry Smith   PetscValidHeaderSpecific(nkdm, DMTS_CLASSID, 2);
204d74926cbSBarry Smith   nkdm->ops->rhsfunction = kdm->ops->rhsfunction;
205d74926cbSBarry Smith   nkdm->ops->rhsjacobian = kdm->ops->rhsjacobian;
206d74926cbSBarry Smith   nkdm->ops->ifunction   = kdm->ops->ifunction;
207d74926cbSBarry Smith   nkdm->ops->ijacobian   = kdm->ops->ijacobian;
208efe9872eSLisandro Dalcin   nkdm->ops->i2function  = kdm->ops->i2function;
209efe9872eSLisandro Dalcin   nkdm->ops->i2jacobian  = kdm->ops->i2jacobian;
210d74926cbSBarry Smith   nkdm->ops->solution    = kdm->ops->solution;
211d74926cbSBarry Smith   nkdm->ops->destroy     = kdm->ops->destroy;
212d74926cbSBarry Smith   nkdm->ops->duplicate   = kdm->ops->duplicate;
213d74926cbSBarry Smith 
214d74926cbSBarry Smith   nkdm->solutionctx             = kdm->solutionctx;
215800f99ffSJeremy L Thompson   nkdm->rhsfunctionctxcontainer = kdm->rhsfunctionctxcontainer;
216800f99ffSJeremy L Thompson   nkdm->rhsjacobianctxcontainer = kdm->rhsjacobianctxcontainer;
217800f99ffSJeremy L Thompson   nkdm->ifunctionctxcontainer   = kdm->ifunctionctxcontainer;
218800f99ffSJeremy L Thompson   nkdm->ijacobianctxcontainer   = kdm->ijacobianctxcontainer;
219800f99ffSJeremy L Thompson   nkdm->i2functionctxcontainer  = kdm->i2functionctxcontainer;
220800f99ffSJeremy L Thompson   nkdm->i2jacobianctxcontainer  = kdm->i2jacobianctxcontainer;
221800f99ffSJeremy L Thompson   if (nkdm->rhsfunctionctxcontainer) PetscCall(PetscObjectCompose((PetscObject)nkdm, "rhs function ctx", (PetscObject)nkdm->rhsfunctionctxcontainer));
222800f99ffSJeremy L Thompson   if (nkdm->rhsjacobianctxcontainer) PetscCall(PetscObjectCompose((PetscObject)nkdm, "rhs jacobian ctx", (PetscObject)nkdm->rhsjacobianctxcontainer));
223800f99ffSJeremy L Thompson   if (nkdm->ifunctionctxcontainer) PetscCall(PetscObjectCompose((PetscObject)nkdm, "ifunction ctx", (PetscObject)nkdm->ifunctionctxcontainer));
224800f99ffSJeremy L Thompson   if (nkdm->ijacobianctxcontainer) PetscCall(PetscObjectCompose((PetscObject)nkdm, "ijacobian ctx", (PetscObject)nkdm->ijacobianctxcontainer));
225800f99ffSJeremy L Thompson   if (nkdm->i2functionctxcontainer) PetscCall(PetscObjectCompose((PetscObject)nkdm, "i2function ctx", (PetscObject)nkdm->i2functionctxcontainer));
226800f99ffSJeremy L Thompson   if (nkdm->i2jacobianctxcontainer) PetscCall(PetscObjectCompose((PetscObject)nkdm, "i2jacobian ctx", (PetscObject)nkdm->i2jacobianctxcontainer));
227d74926cbSBarry Smith 
228d74926cbSBarry Smith   nkdm->data = kdm->data;
229d74926cbSBarry Smith 
230d74926cbSBarry Smith   /*
231d74926cbSBarry Smith   nkdm->fortran_func_pointers[0] = kdm->fortran_func_pointers[0];
232d74926cbSBarry Smith   nkdm->fortran_func_pointers[1] = kdm->fortran_func_pointers[1];
233d74926cbSBarry Smith   nkdm->fortran_func_pointers[2] = kdm->fortran_func_pointers[2];
234d74926cbSBarry Smith   */
235d74926cbSBarry Smith 
236d74926cbSBarry Smith   /* implementation specific copy hooks */
237dbbe0bcdSBarry Smith   PetscTryTypeMethod(kdm, duplicate, nkdm);
23824989b8cSPeter Brune   PetscFunctionReturn(0);
23924989b8cSPeter Brune }
24024989b8cSPeter Brune 
24124989b8cSPeter Brune /*@C
242942e3340SBarry Smith    DMGetDMTS - get read-only private DMTS context from a DM
24324989b8cSPeter Brune 
24424989b8cSPeter Brune    Not Collective
24524989b8cSPeter Brune 
2464165533cSJose E. Roman    Input Parameter:
24724989b8cSPeter Brune .  dm - DM to be used with TS
24824989b8cSPeter Brune 
2494165533cSJose E. Roman    Output Parameter:
250942e3340SBarry Smith .  tsdm - private DMTS context
25124989b8cSPeter Brune 
25224989b8cSPeter Brune    Level: developer
25324989b8cSPeter Brune 
25424989b8cSPeter Brune    Notes:
255942e3340SBarry Smith    Use DMGetDMTSWrite() if write access is needed. The DMTSSetXXX API should be used wherever possible.
25624989b8cSPeter Brune 
257db781477SPatrick Sanan .seealso: `DMGetDMTSWrite()`
25824989b8cSPeter Brune @*/
2599371c9d4SSatish Balay PetscErrorCode DMGetDMTS(DM dm, DMTS *tsdm) {
26024989b8cSPeter Brune   PetscFunctionBegin;
26124989b8cSPeter Brune   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2622a34c10cSBarry Smith   *tsdm = (DMTS)dm->dmts;
263d74926cbSBarry Smith   if (!*tsdm) {
2649566063dSJacob Faibussowitsch     PetscCall(PetscInfo(dm, "Creating new DMTS\n"));
2659566063dSJacob Faibussowitsch     PetscCall(DMTSCreate(PetscObjectComm((PetscObject)dm), tsdm));
2662a34c10cSBarry Smith     dm->dmts            = (PetscObject)*tsdm;
2675c87d4f4SJunchao Zhang     (*tsdm)->originaldm = dm;
2689566063dSJacob Faibussowitsch     PetscCall(DMCoarsenHookAdd(dm, DMCoarsenHook_DMTS, DMRestrictHook_DMTS, NULL));
2699566063dSJacob Faibussowitsch     PetscCall(DMSubDomainHookAdd(dm, DMSubDomainHook_DMTS, DMSubDomainRestrictHook_DMTS, NULL));
27024989b8cSPeter Brune   }
27124989b8cSPeter Brune   PetscFunctionReturn(0);
27224989b8cSPeter Brune }
27324989b8cSPeter Brune 
27424989b8cSPeter Brune /*@C
275942e3340SBarry Smith    DMGetDMTSWrite - get write access to private DMTS context from a DM
27624989b8cSPeter Brune 
27724989b8cSPeter Brune    Not Collective
27824989b8cSPeter Brune 
2794165533cSJose E. Roman    Input Parameter:
28024989b8cSPeter Brune .  dm - DM to be used with TS
28124989b8cSPeter Brune 
2824165533cSJose E. Roman    Output Parameter:
283942e3340SBarry Smith .  tsdm - private DMTS context
28424989b8cSPeter Brune 
28524989b8cSPeter Brune    Level: developer
28624989b8cSPeter Brune 
287db781477SPatrick Sanan .seealso: `DMGetDMTS()`
28824989b8cSPeter Brune @*/
2899371c9d4SSatish Balay PetscErrorCode DMGetDMTSWrite(DM dm, DMTS *tsdm) {
290942e3340SBarry Smith   DMTS sdm;
29124989b8cSPeter Brune 
29224989b8cSPeter Brune   PetscFunctionBegin;
29324989b8cSPeter Brune   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2949566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm, &sdm));
2953c633725SBarry Smith   PetscCheck(sdm->originaldm, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "DMTS has a NULL originaldm");
29624989b8cSPeter Brune   if (sdm->originaldm != dm) { /* Copy on write */
2972a34c10cSBarry Smith     DMTS oldsdm = sdm;
2989566063dSJacob Faibussowitsch     PetscCall(PetscInfo(dm, "Copying DMTS due to write\n"));
2999566063dSJacob Faibussowitsch     PetscCall(DMTSCreate(PetscObjectComm((PetscObject)dm), &sdm));
3009566063dSJacob Faibussowitsch     PetscCall(DMTSCopy(oldsdm, sdm));
3019566063dSJacob Faibussowitsch     PetscCall(DMTSDestroy((DMTS *)&dm->dmts));
3022a34c10cSBarry Smith     dm->dmts        = (PetscObject)sdm;
3035c87d4f4SJunchao Zhang     sdm->originaldm = dm;
30424989b8cSPeter Brune   }
30524989b8cSPeter Brune   *tsdm = sdm;
30624989b8cSPeter Brune   PetscFunctionReturn(0);
30724989b8cSPeter Brune }
30824989b8cSPeter Brune 
30924989b8cSPeter Brune /*@C
310942e3340SBarry Smith    DMCopyDMTS - copies a DM context to a new DM
31124989b8cSPeter Brune 
31224989b8cSPeter Brune    Logically Collective
31324989b8cSPeter Brune 
3144165533cSJose E. Roman    Input Parameters:
31524989b8cSPeter Brune +  dmsrc - DM to obtain context from
31624989b8cSPeter Brune -  dmdest - DM to add context to
31724989b8cSPeter Brune 
31824989b8cSPeter Brune    Level: developer
31924989b8cSPeter Brune 
32024989b8cSPeter Brune    Note:
32124989b8cSPeter Brune    The context is copied by reference. This function does not ensure that a context exists.
32224989b8cSPeter Brune 
323db781477SPatrick Sanan .seealso: `DMGetDMTS()`, `TSSetDM()`
32424989b8cSPeter Brune @*/
3259371c9d4SSatish Balay PetscErrorCode DMCopyDMTS(DM dmsrc, DM dmdest) {
32624989b8cSPeter Brune   PetscFunctionBegin;
32724989b8cSPeter Brune   PetscValidHeaderSpecific(dmsrc, DM_CLASSID, 1);
32824989b8cSPeter Brune   PetscValidHeaderSpecific(dmdest, DM_CLASSID, 2);
3299566063dSJacob Faibussowitsch   PetscCall(DMTSDestroy((DMTS *)&dmdest->dmts));
3302a34c10cSBarry Smith   dmdest->dmts = dmsrc->dmts;
3319566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference(dmdest->dmts));
3329566063dSJacob Faibussowitsch   PetscCall(DMCoarsenHookAdd(dmdest, DMCoarsenHook_DMTS, DMRestrictHook_DMTS, NULL));
3339566063dSJacob Faibussowitsch   PetscCall(DMSubDomainHookAdd(dmdest, DMSubDomainHook_DMTS, DMSubDomainRestrictHook_DMTS, NULL));
33424989b8cSPeter Brune   PetscFunctionReturn(0);
33524989b8cSPeter Brune }
33624989b8cSPeter Brune 
33724989b8cSPeter Brune /*@C
33824989b8cSPeter Brune    DMTSSetIFunction - set TS implicit function evaluation function
33924989b8cSPeter Brune 
34024989b8cSPeter Brune    Not Collective
34124989b8cSPeter Brune 
3424165533cSJose E. Roman    Input Parameters:
34324989b8cSPeter Brune +  dm - DM to be used with TS
344a96d6ef6SBarry Smith .  func - function evaluating f(t,u,u_t)
34524989b8cSPeter Brune -  ctx - context for residual evaluation
34624989b8cSPeter Brune 
347a96d6ef6SBarry Smith    Calling sequence of func:
348a96d6ef6SBarry Smith $     PetscErrorCode func(TS ts,PetscReal t,Vec u,Vec u_t,Vec F,ctx);
349a96d6ef6SBarry Smith 
350a96d6ef6SBarry Smith +  t   - time at step/stage being solved
351a96d6ef6SBarry Smith .  u   - state vector
352a96d6ef6SBarry Smith .  u_t - time derivative of state vector
353a96d6ef6SBarry Smith .  F   - function vector
354a96d6ef6SBarry Smith -  ctx - [optional] user-defined context for matrix evaluation routine
355a96d6ef6SBarry Smith 
35624989b8cSPeter Brune    Level: advanced
35724989b8cSPeter Brune 
35824989b8cSPeter Brune    Note:
35924989b8cSPeter Brune    TSSetFunction() is normally used, but it calls this function internally because the user context is actually
36024989b8cSPeter Brune    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
36124989b8cSPeter Brune    not. If DM took a more central role at some later date, this could become the primary method of setting the residual.
36224989b8cSPeter Brune 
363db781477SPatrick Sanan .seealso: `DMTSSetContext()`, `TSSetIFunction()`, `DMTSSetJacobian()`
36424989b8cSPeter Brune @*/
3659371c9d4SSatish Balay PetscErrorCode DMTSSetIFunction(DM dm, TSIFunction func, void *ctx) {
366942e3340SBarry Smith   DMTS tsdm;
36724989b8cSPeter Brune 
36824989b8cSPeter Brune   PetscFunctionBegin;
36924989b8cSPeter Brune   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3709566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm, &tsdm));
371d74926cbSBarry Smith   if (func) tsdm->ops->ifunction = func;
372800f99ffSJeremy L Thompson   if (ctx) {
373800f99ffSJeremy L Thompson     PetscContainer ctxcontainer;
374800f99ffSJeremy L Thompson     PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)tsdm), &ctxcontainer));
375800f99ffSJeremy L Thompson     PetscCall(PetscContainerSetPointer(ctxcontainer, ctx));
376800f99ffSJeremy L Thompson     PetscCall(PetscObjectCompose((PetscObject)tsdm, "ifunction ctx", (PetscObject)ctxcontainer));
377800f99ffSJeremy L Thompson     tsdm->ifunctionctxcontainer = ctxcontainer;
378800f99ffSJeremy L Thompson     PetscCall(PetscContainerDestroy(&ctxcontainer));
379800f99ffSJeremy L Thompson   }
380800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
381800f99ffSJeremy L Thompson }
382800f99ffSJeremy L Thompson 
383800f99ffSJeremy L Thompson /*@C
3845cb80ecdSBarry Smith    DMTSSetIFunctionContextDestroy - set `TS` implicit evaluation context destroy function
385800f99ffSJeremy L Thompson 
386800f99ffSJeremy L Thompson    Not Collective
387800f99ffSJeremy L Thompson 
388800f99ffSJeremy L Thompson    Input Parameters:
3895cb80ecdSBarry Smith +  dm - `DM` to be used with `TS`
3905cb80ecdSBarry Smith -  f - implicit evaluation context destroy function
391800f99ffSJeremy L Thompson 
392800f99ffSJeremy L Thompson    Level: advanced
393800f99ffSJeremy L Thompson 
39490f54644SBarry Smith .seealso: `DMTSSetIFunction()`, `TSSetIFunction()`
395800f99ffSJeremy L Thompson @*/
3969371c9d4SSatish Balay PetscErrorCode DMTSSetIFunctionContextDestroy(DM dm, PetscErrorCode (*f)(void *)) {
397800f99ffSJeremy L Thompson   DMTS tsdm;
398800f99ffSJeremy L Thompson 
399800f99ffSJeremy L Thompson   PetscFunctionBegin;
400800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
401800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm, &tsdm));
402800f99ffSJeremy L Thompson   if (tsdm->ifunctionctxcontainer) PetscCall(PetscContainerSetUserDestroy(tsdm->ifunctionctxcontainer, f));
403800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
404800f99ffSJeremy L Thompson }
405800f99ffSJeremy L Thompson 
4069371c9d4SSatish Balay PetscErrorCode DMTSUnsetIFunctionContext_Internal(DM dm) {
407800f99ffSJeremy L Thompson   DMTS tsdm;
408800f99ffSJeremy L Thompson 
409800f99ffSJeremy L Thompson   PetscFunctionBegin;
410800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
411800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm, &tsdm));
412800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetIFunctionContext_DMTS(tsdm));
41324989b8cSPeter Brune   PetscFunctionReturn(0);
41424989b8cSPeter Brune }
41524989b8cSPeter Brune 
41624989b8cSPeter Brune /*@C
41724989b8cSPeter Brune    DMTSGetIFunction - get TS implicit residual evaluation function
41824989b8cSPeter Brune 
41924989b8cSPeter Brune    Not Collective
42024989b8cSPeter Brune 
4214165533cSJose E. Roman    Input Parameter:
42224989b8cSPeter Brune .  dm - DM to be used with TS
42324989b8cSPeter Brune 
4244165533cSJose E. Roman    Output Parameters:
42524989b8cSPeter Brune +  func - function evaluation function, see TSSetIFunction() for calling sequence
42624989b8cSPeter Brune -  ctx - context for residual evaluation
42724989b8cSPeter Brune 
42824989b8cSPeter Brune    Level: advanced
42924989b8cSPeter Brune 
43024989b8cSPeter Brune    Note:
43124989b8cSPeter Brune    TSGetFunction() is normally used, but it calls this function internally because the user context is actually
43224989b8cSPeter Brune    associated with the DM.
43324989b8cSPeter Brune 
434db781477SPatrick Sanan .seealso: `DMTSSetContext()`, `DMTSSetFunction()`, `TSSetFunction()`
43524989b8cSPeter Brune @*/
4369371c9d4SSatish Balay PetscErrorCode DMTSGetIFunction(DM dm, TSIFunction *func, void **ctx) {
437942e3340SBarry Smith   DMTS tsdm;
43824989b8cSPeter Brune 
43924989b8cSPeter Brune   PetscFunctionBegin;
44024989b8cSPeter Brune   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4419566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm, &tsdm));
442d74926cbSBarry Smith   if (func) *func = tsdm->ops->ifunction;
443800f99ffSJeremy L Thompson   if (ctx) {
444800f99ffSJeremy L Thompson     if (tsdm->ifunctionctxcontainer) PetscCall(PetscContainerGetPointer(tsdm->ifunctionctxcontainer, ctx));
445800f99ffSJeremy L Thompson     else *ctx = NULL;
446800f99ffSJeremy L Thompson   }
44724989b8cSPeter Brune   PetscFunctionReturn(0);
44824989b8cSPeter Brune }
44924989b8cSPeter Brune 
450efe9872eSLisandro Dalcin /*@C
451efe9872eSLisandro Dalcin    DMTSSetI2Function - set TS implicit function evaluation function for 2nd order systems
452efe9872eSLisandro Dalcin 
453efe9872eSLisandro Dalcin    Not Collective
454efe9872eSLisandro Dalcin 
4554165533cSJose E. Roman    Input Parameters:
456efe9872eSLisandro Dalcin +  dm - DM to be used with TS
457a96d6ef6SBarry Smith .  fun - function evaluation routine
458efe9872eSLisandro Dalcin -  ctx - context for residual evaluation
459efe9872eSLisandro Dalcin 
460a96d6ef6SBarry Smith    Calling sequence of fun:
461a96d6ef6SBarry Smith $     PetscErrorCode fun(TS ts,PetscReal t,Vec U,Vec U_t,Vec U_tt,Vec F,ctx);
462a96d6ef6SBarry Smith 
463a96d6ef6SBarry Smith +  t    - time at step/stage being solved
464a96d6ef6SBarry Smith .  U    - state vector
465a96d6ef6SBarry Smith .  U_t  - time derivative of state vector
466a96d6ef6SBarry Smith .  U_tt - second time derivative of state vector
467a96d6ef6SBarry Smith .  F    - function vector
468a96d6ef6SBarry Smith -  ctx  - [optional] user-defined context for matrix evaluation routine (may be NULL)
469a96d6ef6SBarry Smith 
470efe9872eSLisandro Dalcin    Level: advanced
471efe9872eSLisandro Dalcin 
472efe9872eSLisandro Dalcin    Note:
473efe9872eSLisandro Dalcin    TSSetI2Function() is normally used, but it calls this function internally because the user context is actually
474efe9872eSLisandro Dalcin    associated with the DM.
475efe9872eSLisandro Dalcin 
476db781477SPatrick Sanan .seealso: `TSSetI2Function()`
477efe9872eSLisandro Dalcin @*/
4789371c9d4SSatish Balay PetscErrorCode DMTSSetI2Function(DM dm, TSI2Function fun, void *ctx) {
479efe9872eSLisandro Dalcin   DMTS tsdm;
480efe9872eSLisandro Dalcin 
481efe9872eSLisandro Dalcin   PetscFunctionBegin;
482efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4839566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm, &tsdm));
484efe9872eSLisandro Dalcin   if (fun) tsdm->ops->i2function = fun;
485800f99ffSJeremy L Thompson   if (ctx) {
486800f99ffSJeremy L Thompson     PetscContainer ctxcontainer;
487800f99ffSJeremy L Thompson     PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)tsdm), &ctxcontainer));
488800f99ffSJeremy L Thompson     PetscCall(PetscContainerSetPointer(ctxcontainer, ctx));
489800f99ffSJeremy L Thompson     PetscCall(PetscObjectCompose((PetscObject)tsdm, "i2function ctx", (PetscObject)ctxcontainer));
490800f99ffSJeremy L Thompson     tsdm->i2functionctxcontainer = ctxcontainer;
491800f99ffSJeremy L Thompson     PetscCall(PetscContainerDestroy(&ctxcontainer));
492800f99ffSJeremy L Thompson   }
493800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
494800f99ffSJeremy L Thompson }
495800f99ffSJeremy L Thompson 
496800f99ffSJeremy L Thompson /*@C
4975cb80ecdSBarry Smith    DMTSSetI2FunctionContextDestroy - set `TS` implicit evaluation for 2nd order systems context destroy
498800f99ffSJeremy L Thompson 
499800f99ffSJeremy L Thompson    Not Collective
500800f99ffSJeremy L Thompson 
501800f99ffSJeremy L Thompson    Input Parameters:
5025cb80ecdSBarry Smith +  dm - `DM` to be used with `TS`
5035cb80ecdSBarry Smith -  f - implicit evaluation context destroy function
504800f99ffSJeremy L Thompson 
505800f99ffSJeremy L Thompson    Level: advanced
506800f99ffSJeremy L Thompson 
507800f99ffSJeremy L Thompson    Note:
5085cb80ecdSBarry Smith    `TSSetI2FunctionContextDestroy()` is normally used, but it calls this function internally because the user context is actually
5095cb80ecdSBarry Smith    associated with the `DM`.
510800f99ffSJeremy L Thompson 
511800f99ffSJeremy L Thompson .seealso: `TSSetI2FunctionContextDestroy()`, `DMTSSetI2Function()`, `TSSetI2Function()`
512800f99ffSJeremy L Thompson @*/
5139371c9d4SSatish Balay PetscErrorCode DMTSSetI2FunctionContextDestroy(DM dm, PetscErrorCode (*f)(void *)) {
514800f99ffSJeremy L Thompson   DMTS tsdm;
515800f99ffSJeremy L Thompson 
516800f99ffSJeremy L Thompson   PetscFunctionBegin;
517800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
518800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm, &tsdm));
519800f99ffSJeremy L Thompson   if (tsdm->i2functionctxcontainer) PetscCall(PetscContainerSetUserDestroy(tsdm->i2functionctxcontainer, f));
520800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
521800f99ffSJeremy L Thompson }
522800f99ffSJeremy L Thompson 
5239371c9d4SSatish Balay PetscErrorCode DMTSUnsetI2FunctionContext_Internal(DM dm) {
524800f99ffSJeremy L Thompson   DMTS tsdm;
525800f99ffSJeremy L Thompson 
526800f99ffSJeremy L Thompson   PetscFunctionBegin;
527800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
528800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm, &tsdm));
529800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetI2FunctionContext_DMTS(tsdm));
530efe9872eSLisandro Dalcin   PetscFunctionReturn(0);
531efe9872eSLisandro Dalcin }
532efe9872eSLisandro Dalcin 
533efe9872eSLisandro Dalcin /*@C
534efe9872eSLisandro Dalcin    DMTSGetI2Function - get TS implicit residual evaluation function for 2nd order systems
535efe9872eSLisandro Dalcin 
536efe9872eSLisandro Dalcin    Not Collective
537efe9872eSLisandro Dalcin 
5384165533cSJose E. Roman    Input Parameter:
539efe9872eSLisandro Dalcin .  dm - DM to be used with TS
540efe9872eSLisandro Dalcin 
5414165533cSJose E. Roman    Output Parameters:
542efe9872eSLisandro Dalcin +  fun - function evaluation function, see TSSetI2Function() for calling sequence
543efe9872eSLisandro Dalcin -  ctx - context for residual evaluation
544efe9872eSLisandro Dalcin 
545efe9872eSLisandro Dalcin    Level: advanced
546efe9872eSLisandro Dalcin 
547efe9872eSLisandro Dalcin    Note:
548efe9872eSLisandro Dalcin    TSGetI2Function() is normally used, but it calls this function internally because the user context is actually
549efe9872eSLisandro Dalcin    associated with the DM.
550efe9872eSLisandro Dalcin 
551c2e3fba1SPatrick Sanan .seealso: `DMTSSetI2Function()`, `TSGetI2Function()`
552efe9872eSLisandro Dalcin @*/
5539371c9d4SSatish Balay PetscErrorCode DMTSGetI2Function(DM dm, TSI2Function *fun, void **ctx) {
554efe9872eSLisandro Dalcin   DMTS tsdm;
555efe9872eSLisandro Dalcin 
556efe9872eSLisandro Dalcin   PetscFunctionBegin;
557efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5589566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm, &tsdm));
559efe9872eSLisandro Dalcin   if (fun) *fun = tsdm->ops->i2function;
560800f99ffSJeremy L Thompson   if (ctx) {
561800f99ffSJeremy L Thompson     if (tsdm->i2functionctxcontainer) PetscCall(PetscContainerGetPointer(tsdm->i2functionctxcontainer, ctx));
562800f99ffSJeremy L Thompson     else *ctx = NULL;
563800f99ffSJeremy L Thompson   }
564efe9872eSLisandro Dalcin   PetscFunctionReturn(0);
565efe9872eSLisandro Dalcin }
566efe9872eSLisandro Dalcin 
567efe9872eSLisandro Dalcin /*@C
568efe9872eSLisandro Dalcin    DMTSSetI2Jacobian - set TS implicit Jacobian evaluation function for 2nd order systems
569efe9872eSLisandro Dalcin 
570efe9872eSLisandro Dalcin    Not Collective
571efe9872eSLisandro Dalcin 
5724165533cSJose E. Roman    Input Parameters:
573efe9872eSLisandro Dalcin +  dm - DM to be used with TS
574a96d6ef6SBarry Smith .  fun - Jacobian evaluation routine
575efe9872eSLisandro Dalcin -  ctx - context for Jacobian evaluation
576efe9872eSLisandro Dalcin 
577a96d6ef6SBarry Smith    Calling sequence of jac:
578a96d6ef6SBarry Smith $    PetscErrorCode jac(TS ts,PetscReal t,Vec U,Vec U_t,Vec U_tt,PetscReal v,PetscReal a,Mat J,Mat P,void *ctx);
579a96d6ef6SBarry Smith 
580a96d6ef6SBarry Smith +  t    - time at step/stage being solved
581a96d6ef6SBarry Smith .  U    - state vector
582a96d6ef6SBarry Smith .  U_t  - time derivative of state vector
583a96d6ef6SBarry Smith .  U_tt - second time derivative of state vector
584a96d6ef6SBarry Smith .  v    - shift for U_t
585a96d6ef6SBarry Smith .  a    - shift for U_tt
586a96d6ef6SBarry Smith .  J    - Jacobian of G(U) = F(t,U,W+v*U,W'+a*U), equivalent to dF/dU + v*dF/dU_t  + a*dF/dU_tt
587a96d6ef6SBarry Smith .  P    - preconditioning matrix for J, may be same as J
588a96d6ef6SBarry Smith -  ctx  - [optional] user-defined context for matrix evaluation routine
589a96d6ef6SBarry Smith 
590efe9872eSLisandro Dalcin    Level: advanced
591efe9872eSLisandro Dalcin 
592efe9872eSLisandro Dalcin    Note:
593efe9872eSLisandro Dalcin    TSSetI2Jacobian() is normally used, but it calls this function internally because the user context is actually
594efe9872eSLisandro Dalcin    associated with the DM.
595efe9872eSLisandro Dalcin 
596db781477SPatrick Sanan .seealso: `TSSetI2Jacobian()`
597efe9872eSLisandro Dalcin @*/
5989371c9d4SSatish Balay PetscErrorCode DMTSSetI2Jacobian(DM dm, TSI2Jacobian jac, void *ctx) {
599efe9872eSLisandro Dalcin   DMTS tsdm;
600efe9872eSLisandro Dalcin 
601efe9872eSLisandro Dalcin   PetscFunctionBegin;
602efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6039566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm, &tsdm));
604efe9872eSLisandro Dalcin   if (jac) tsdm->ops->i2jacobian = jac;
605800f99ffSJeremy L Thompson   if (ctx) {
606800f99ffSJeremy L Thompson     PetscContainer ctxcontainer;
607800f99ffSJeremy L Thompson     PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)tsdm), &ctxcontainer));
608800f99ffSJeremy L Thompson     PetscCall(PetscContainerSetPointer(ctxcontainer, ctx));
609800f99ffSJeremy L Thompson     PetscCall(PetscObjectCompose((PetscObject)tsdm, "i2jacobian ctx", (PetscObject)ctxcontainer));
610800f99ffSJeremy L Thompson     tsdm->i2jacobianctxcontainer = ctxcontainer;
611800f99ffSJeremy L Thompson     PetscCall(PetscContainerDestroy(&ctxcontainer));
612800f99ffSJeremy L Thompson   }
613800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
614800f99ffSJeremy L Thompson }
615800f99ffSJeremy L Thompson 
616800f99ffSJeremy L Thompson /*@C
6175cb80ecdSBarry Smith    DMTSSetI2JacobianContextDestroy - set `TS` implicit Jacobian evaluation for 2nd order systems context destroy function
618800f99ffSJeremy L Thompson 
619800f99ffSJeremy L Thompson    Not Collective
620800f99ffSJeremy L Thompson 
621800f99ffSJeremy L Thompson    Input Parameters:
6225cb80ecdSBarry Smith +  dm - `DM` to be used with `TS`
6235cb80ecdSBarry Smith -  f - implicit Jacobian evaluation context destroy function
624800f99ffSJeremy L Thompson 
62587497f52SBarry Smith    Level: advanced
62687497f52SBarry Smith 
627800f99ffSJeremy L Thompson .seealso: `TSSetI2JacobianContextDestroy()`, `DMTSSetI2Jacobian()`, `TSSetI2Jacobian()`
628800f99ffSJeremy L Thompson @*/
6299371c9d4SSatish Balay PetscErrorCode DMTSSetI2JacobianContextDestroy(DM dm, PetscErrorCode (*f)(void *)) {
630800f99ffSJeremy L Thompson   DMTS tsdm;
631800f99ffSJeremy L Thompson 
632800f99ffSJeremy L Thompson   PetscFunctionBegin;
633800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
634800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm, &tsdm));
635800f99ffSJeremy L Thompson   if (tsdm->i2jacobianctxcontainer) PetscCall(PetscContainerSetUserDestroy(tsdm->i2jacobianctxcontainer, f));
636800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
637800f99ffSJeremy L Thompson }
638800f99ffSJeremy L Thompson 
6399371c9d4SSatish Balay PetscErrorCode DMTSUnsetI2JacobianContext_Internal(DM dm) {
640800f99ffSJeremy L Thompson   DMTS tsdm;
641800f99ffSJeremy L Thompson 
642800f99ffSJeremy L Thompson   PetscFunctionBegin;
643800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
644800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm, &tsdm));
645800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetI2JacobianContext_DMTS(tsdm));
646efe9872eSLisandro Dalcin   PetscFunctionReturn(0);
647efe9872eSLisandro Dalcin }
648efe9872eSLisandro Dalcin 
649efe9872eSLisandro Dalcin /*@C
650efe9872eSLisandro Dalcin    DMTSGetI2Jacobian - get TS implicit Jacobian evaluation function for 2nd order systems
651efe9872eSLisandro Dalcin 
652efe9872eSLisandro Dalcin    Not Collective
653efe9872eSLisandro Dalcin 
6544165533cSJose E. Roman    Input Parameter:
655efe9872eSLisandro Dalcin .  dm - DM to be used with TS
656efe9872eSLisandro Dalcin 
6574165533cSJose E. Roman    Output Parameters:
658efe9872eSLisandro Dalcin +  jac - Jacobian evaluation function, see TSSetI2Jacobian() for calling sequence
659efe9872eSLisandro Dalcin -  ctx - context for Jacobian evaluation
660efe9872eSLisandro Dalcin 
661efe9872eSLisandro Dalcin    Level: advanced
662efe9872eSLisandro Dalcin 
663efe9872eSLisandro Dalcin    Note:
664efe9872eSLisandro Dalcin    TSGetI2Jacobian() is normally used, but it calls this function internally because the user context is actually
665efe9872eSLisandro Dalcin    associated with the DM.
666efe9872eSLisandro Dalcin 
667c2e3fba1SPatrick Sanan .seealso: `DMTSSetI2Jacobian()`, `TSGetI2Jacobian()`
668efe9872eSLisandro Dalcin @*/
6699371c9d4SSatish Balay PetscErrorCode DMTSGetI2Jacobian(DM dm, TSI2Jacobian *jac, void **ctx) {
670efe9872eSLisandro Dalcin   DMTS tsdm;
671efe9872eSLisandro Dalcin 
672efe9872eSLisandro Dalcin   PetscFunctionBegin;
673efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6749566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm, &tsdm));
675efe9872eSLisandro Dalcin   if (jac) *jac = tsdm->ops->i2jacobian;
676800f99ffSJeremy L Thompson   if (ctx) {
677800f99ffSJeremy L Thompson     if (tsdm->i2jacobianctxcontainer) PetscCall(PetscContainerGetPointer(tsdm->i2jacobianctxcontainer, ctx));
678800f99ffSJeremy L Thompson     else *ctx = NULL;
679800f99ffSJeremy L Thompson   }
680efe9872eSLisandro Dalcin   PetscFunctionReturn(0);
681efe9872eSLisandro Dalcin }
68224989b8cSPeter Brune 
68324989b8cSPeter Brune /*@C
68424989b8cSPeter Brune    DMTSSetRHSFunction - set TS explicit residual evaluation function
68524989b8cSPeter Brune 
68624989b8cSPeter Brune    Not Collective
68724989b8cSPeter Brune 
6884165533cSJose E. Roman    Input Parameters:
68924989b8cSPeter Brune +  dm - DM to be used with TS
690a96d6ef6SBarry Smith .  func - RHS function evaluation routine
69124989b8cSPeter Brune -  ctx - context for residual evaluation
69224989b8cSPeter Brune 
693a96d6ef6SBarry Smith     Calling sequence of func:
694a96d6ef6SBarry Smith $     PetscErrorCode func(TS ts,PetscReal t,Vec u,Vec F,void *ctx);
695a96d6ef6SBarry Smith 
696a96d6ef6SBarry Smith +   ts - timestep context
697a96d6ef6SBarry Smith .   t - current timestep
698a96d6ef6SBarry Smith .   u - input vector
699a96d6ef6SBarry Smith .   F - function vector
700a96d6ef6SBarry Smith -   ctx - [optional] user-defined function context
701a96d6ef6SBarry Smith 
70224989b8cSPeter Brune    Level: advanced
70324989b8cSPeter Brune 
70424989b8cSPeter Brune    Note:
705800f99ffSJeremy L Thompson    TSSetRHSFunction() is normally used, but it calls this function internally because the user context is actually
70624989b8cSPeter Brune    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
70724989b8cSPeter Brune    not. If DM took a more central role at some later date, this could become the primary method of setting the residual.
70824989b8cSPeter Brune 
709db781477SPatrick Sanan .seealso: `DMTSSetContext()`, `TSSetRHSFunction()`, `DMTSSetJacobian()`
71024989b8cSPeter Brune @*/
7119371c9d4SSatish Balay PetscErrorCode DMTSSetRHSFunction(DM dm, TSRHSFunction func, void *ctx) {
712942e3340SBarry Smith   DMTS tsdm;
71324989b8cSPeter Brune 
71424989b8cSPeter Brune   PetscFunctionBegin;
71524989b8cSPeter Brune   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7169566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm, &tsdm));
717d74926cbSBarry Smith   if (func) tsdm->ops->rhsfunction = func;
718800f99ffSJeremy L Thompson   if (ctx) {
719800f99ffSJeremy L Thompson     PetscContainer ctxcontainer;
720800f99ffSJeremy L Thompson     PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)tsdm), &ctxcontainer));
721800f99ffSJeremy L Thompson     PetscCall(PetscContainerSetPointer(ctxcontainer, ctx));
722800f99ffSJeremy L Thompson     PetscCall(PetscObjectCompose((PetscObject)tsdm, "rhs function ctx", (PetscObject)ctxcontainer));
723800f99ffSJeremy L Thompson     tsdm->rhsfunctionctxcontainer = ctxcontainer;
724800f99ffSJeremy L Thompson     PetscCall(PetscContainerDestroy(&ctxcontainer));
725800f99ffSJeremy L Thompson   }
726800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
727800f99ffSJeremy L Thompson }
728800f99ffSJeremy L Thompson 
729800f99ffSJeremy L Thompson /*@C
7305cb80ecdSBarry Smith    DMTSSetRHSFunctionContextDestroy - set `TS` explicit residual evaluation context destroy function
731800f99ffSJeremy L Thompson 
732800f99ffSJeremy L Thompson    Not Collective
733800f99ffSJeremy L Thompson 
734800f99ffSJeremy L Thompson    Input Parameters:
7355cb80ecdSBarry Smith +  dm - `DM` to be used with `TS`
7365cb80ecdSBarry Smith -  f - explicit evaluation context destroy function
737800f99ffSJeremy L Thompson 
738800f99ffSJeremy L Thompson    Level: advanced
739800f99ffSJeremy L Thompson 
740800f99ffSJeremy L Thompson    Note:
7415cb80ecdSBarry Smith    `TSSetRHSFunctionContextDestroy()` is normally used, but it calls this function internally because the user context is actually
7425cb80ecdSBarry Smith    associated with the `DM`.  This makes the interface consistent regardless of whether the user interacts with a `DM` or
7435cb80ecdSBarry Smith    not.
7445cb80ecdSBarry Smith 
7455cb80ecdSBarry Smith    Developer Note:
7465cb80ecdSBarry Smith    If `DM` took a more central role at some later date, this could become the primary method of setting the residual.
747800f99ffSJeremy L Thompson 
748800f99ffSJeremy L Thompson .seealso: `TSSetRHSFunctionContextDestroy()`, `DMTSSetRHSFunction()`, `TSSetRHSFunction()`
749800f99ffSJeremy L Thompson @*/
7509371c9d4SSatish Balay PetscErrorCode DMTSSetRHSFunctionContextDestroy(DM dm, PetscErrorCode (*f)(void *)) {
751800f99ffSJeremy L Thompson   DMTS tsdm;
752800f99ffSJeremy L Thompson 
753800f99ffSJeremy L Thompson   PetscFunctionBegin;
754800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
755800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm, &tsdm));
756800f99ffSJeremy L Thompson   if (tsdm->rhsfunctionctxcontainer) PetscCall(PetscContainerSetUserDestroy(tsdm->rhsfunctionctxcontainer, f));
757800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
758800f99ffSJeremy L Thompson }
759800f99ffSJeremy L Thompson 
7609371c9d4SSatish Balay PetscErrorCode DMTSUnsetRHSFunctionContext_Internal(DM dm) {
761800f99ffSJeremy L Thompson   DMTS tsdm;
762800f99ffSJeremy L Thompson 
763800f99ffSJeremy L Thompson   PetscFunctionBegin;
764800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
765800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm, &tsdm));
766800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetRHSFunctionContext_DMTS(tsdm));
767800f99ffSJeremy L Thompson   tsdm->rhsfunctionctxcontainer = NULL;
76824989b8cSPeter Brune   PetscFunctionReturn(0);
76924989b8cSPeter Brune }
77024989b8cSPeter Brune 
771ef20d060SBarry Smith /*@C
772e3c11fc1SJed Brown    DMTSSetTransientVariable - sets function to transform from state to transient variables
773e3c11fc1SJed Brown 
774e3c11fc1SJed Brown    Logically Collective
775e3c11fc1SJed Brown 
7764165533cSJose E. Roman    Input Parameters:
777e3c11fc1SJed Brown +  dm - DM to be used with TS
778a96d6ef6SBarry Smith .  tvar - a function that transforms to transient variables
779e3c11fc1SJed Brown -  ctx - a context for tvar
780e3c11fc1SJed Brown 
781a96d6ef6SBarry Smith     Calling sequence of tvar:
782a96d6ef6SBarry Smith $     PetscErrorCode tvar(TS ts,Vec p,Vec c,void *ctx);
783a96d6ef6SBarry Smith 
784a96d6ef6SBarry Smith +   ts - timestep context
7856aad120cSJose E. Roman .   p - input vector (primitive form)
786a96d6ef6SBarry Smith .   c - output vector, transient variables (conservative form)
787a96d6ef6SBarry Smith -   ctx - [optional] user-defined function context
788a96d6ef6SBarry Smith 
789e3c11fc1SJed Brown    Level: advanced
790e3c11fc1SJed Brown 
791e3c11fc1SJed Brown    Notes:
792e3c11fc1SJed Brown    This is typically used to transform from primitive to conservative variables so that a time integrator (e.g., TSBDF)
793e3c11fc1SJed Brown    can be conservative.  In this context, primitive variables P are used to model the state (e.g., because they lead to
794e3c11fc1SJed Brown    well-conditioned formulations even in limiting cases such as low-Mach or zero porosity).  The transient variable is
795e3c11fc1SJed Brown    C(P), specified by calling this function.  An IFunction thus receives arguments (P, Cdot) and the IJacobian must be
796e3c11fc1SJed Brown    evaluated via the chain rule, as in
797e3c11fc1SJed Brown 
798e3c11fc1SJed Brown      dF/dP + shift * dF/dCdot dC/dP.
799e3c11fc1SJed Brown 
800db781477SPatrick Sanan .seealso: `TSSetTransientVariable()`, `DMTSGetTransientVariable()`, `DMTSSetIFunction()`, `DMTSSetIJacobian()`
801e3c11fc1SJed Brown @*/
8029371c9d4SSatish Balay PetscErrorCode DMTSSetTransientVariable(DM dm, TSTransientVariable tvar, void *ctx) {
803e3c11fc1SJed Brown   DMTS dmts;
804e3c11fc1SJed Brown 
805e3c11fc1SJed Brown   PetscFunctionBegin;
806e3c11fc1SJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8079566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm, &dmts));
808e3c11fc1SJed Brown   dmts->ops->transientvar = tvar;
809e3c11fc1SJed Brown   dmts->transientvarctx   = ctx;
810e3c11fc1SJed Brown   PetscFunctionReturn(0);
811e3c11fc1SJed Brown }
812e3c11fc1SJed Brown 
813e3c11fc1SJed Brown /*@C
814e3c11fc1SJed Brown    DMTSGetTransientVariable - gets function to transform from state to transient variables
815e3c11fc1SJed Brown 
816e3c11fc1SJed Brown    Logically Collective
817e3c11fc1SJed Brown 
8184165533cSJose E. Roman    Input Parameter:
819e3c11fc1SJed Brown .  dm - DM to be used with TS
820e3c11fc1SJed Brown 
8214165533cSJose E. Roman    Output Parameters:
822a96d6ef6SBarry Smith +  tvar - a function that transforms to transient variables
823e3c11fc1SJed Brown -  ctx - a context for tvar
824e3c11fc1SJed Brown 
825e3c11fc1SJed Brown    Level: advanced
826e3c11fc1SJed Brown 
827db781477SPatrick Sanan .seealso: `DMTSSetTransientVariable()`, `DMTSGetIFunction()`, `DMTSGetIJacobian()`
828e3c11fc1SJed Brown @*/
8299371c9d4SSatish Balay PetscErrorCode DMTSGetTransientVariable(DM dm, TSTransientVariable *tvar, void *ctx) {
830e3c11fc1SJed Brown   DMTS dmts;
831e3c11fc1SJed Brown 
832e3c11fc1SJed Brown   PetscFunctionBegin;
833e3c11fc1SJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8349566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm, &dmts));
835e3c11fc1SJed Brown   if (tvar) *tvar = dmts->ops->transientvar;
836e3c11fc1SJed Brown   if (ctx) *(void **)ctx = dmts->transientvarctx;
837e3c11fc1SJed Brown   PetscFunctionReturn(0);
838e3c11fc1SJed Brown }
839e3c11fc1SJed Brown 
840e3c11fc1SJed Brown /*@C
841ef20d060SBarry Smith    DMTSGetSolutionFunction - gets the TS solution evaluation function
842ef20d060SBarry Smith 
843ef20d060SBarry Smith    Not Collective
844ef20d060SBarry Smith 
8454165533cSJose E. Roman    Input Parameter:
846ef20d060SBarry Smith .  dm - DM to be used with TS
847ef20d060SBarry Smith 
848ef20d060SBarry Smith    Output Parameters:
849ef20d060SBarry Smith +  func - solution function evaluation function, see TSSetSolution() for calling sequence
850ef20d060SBarry Smith -  ctx - context for solution evaluation
851ef20d060SBarry Smith 
852ef20d060SBarry Smith    Level: advanced
853ef20d060SBarry Smith 
854db781477SPatrick Sanan .seealso: `DMTSSetContext()`, `TSSetFunction()`, `DMTSSetJacobian()`, `DMTSSetSolutionFunction()`
855ef20d060SBarry Smith @*/
8569371c9d4SSatish Balay PetscErrorCode DMTSGetSolutionFunction(DM dm, TSSolutionFunction *func, void **ctx) {
857942e3340SBarry Smith   DMTS tsdm;
858ef20d060SBarry Smith 
859ef20d060SBarry Smith   PetscFunctionBegin;
860ef20d060SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8619566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm, &tsdm));
862d74926cbSBarry Smith   if (func) *func = tsdm->ops->solution;
863ef20d060SBarry Smith   if (ctx) *ctx = tsdm->solutionctx;
864ef20d060SBarry Smith   PetscFunctionReturn(0);
865ef20d060SBarry Smith }
866ef20d060SBarry Smith 
867ef20d060SBarry Smith /*@C
868ef20d060SBarry Smith    DMTSSetSolutionFunction - set TS solution evaluation function
869ef20d060SBarry Smith 
870ef20d060SBarry Smith    Not Collective
871ef20d060SBarry Smith 
8724165533cSJose E. Roman    Input Parameters:
873ef20d060SBarry Smith +  dm - DM to be used with TS
874a96d6ef6SBarry Smith .  func - solution function evaluation routine
875ef20d060SBarry Smith -  ctx - context for solution evaluation
876ef20d060SBarry Smith 
877a96d6ef6SBarry Smith     Calling sequence of f:
878a96d6ef6SBarry Smith $     PetscErrorCode f(TS ts,PetscReal t,Vec u,void *ctx);
879a96d6ef6SBarry Smith 
880a96d6ef6SBarry Smith +   ts - timestep context
881a96d6ef6SBarry Smith .   t - current timestep
882a96d6ef6SBarry Smith .   u - output vector
883a96d6ef6SBarry Smith -   ctx - [optional] user-defined function context
884a96d6ef6SBarry Smith 
885ef20d060SBarry Smith    Level: advanced
886ef20d060SBarry Smith 
887ef20d060SBarry Smith    Note:
888ef20d060SBarry Smith    TSSetSolutionFunction() is normally used, but it calls this function internally because the user context is actually
889ef20d060SBarry Smith    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
890ef20d060SBarry Smith    not. If DM took a more central role at some later date, this could become the primary method of setting the residual.
891ef20d060SBarry Smith 
892db781477SPatrick Sanan .seealso: `DMTSSetContext()`, `TSSetFunction()`, `DMTSSetJacobian()`, `DMTSGetSolutionFunction()`
893ef20d060SBarry Smith @*/
8949371c9d4SSatish Balay PetscErrorCode DMTSSetSolutionFunction(DM dm, TSSolutionFunction func, void *ctx) {
895942e3340SBarry Smith   DMTS tsdm;
896ef20d060SBarry Smith 
897ef20d060SBarry Smith   PetscFunctionBegin;
898ef20d060SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8999566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm, &tsdm));
900d74926cbSBarry Smith   if (func) tsdm->ops->solution = func;
901ef20d060SBarry Smith   if (ctx) tsdm->solutionctx = ctx;
902ef20d060SBarry Smith   PetscFunctionReturn(0);
903ef20d060SBarry Smith }
904ef20d060SBarry Smith 
9059b7cd975SBarry Smith /*@C
9069b7cd975SBarry Smith    DMTSSetForcingFunction - set TS forcing function evaluation function
9079b7cd975SBarry Smith 
9089b7cd975SBarry Smith    Not Collective
9099b7cd975SBarry Smith 
9104165533cSJose E. Roman    Input Parameters:
9119b7cd975SBarry Smith +  dm - DM to be used with TS
912a96d6ef6SBarry Smith .  f - forcing function evaluation routine
9139b7cd975SBarry Smith -  ctx - context for solution evaluation
9149b7cd975SBarry Smith 
915a96d6ef6SBarry Smith     Calling sequence of func:
916a96d6ef6SBarry Smith $     PetscErrorCode func (TS ts,PetscReal t,Vec f,void *ctx);
917a96d6ef6SBarry Smith 
918a96d6ef6SBarry Smith +   ts - timestep context
919a96d6ef6SBarry Smith .   t - current timestep
920a96d6ef6SBarry Smith .   f - output vector
921a96d6ef6SBarry Smith -   ctx - [optional] user-defined function context
922a96d6ef6SBarry Smith 
9239b7cd975SBarry Smith    Level: advanced
9249b7cd975SBarry Smith 
9259b7cd975SBarry Smith    Note:
9269b7cd975SBarry Smith    TSSetForcingFunction() is normally used, but it calls this function internally because the user context is actually
9279b7cd975SBarry Smith    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
9289b7cd975SBarry Smith    not. If DM took a more central role at some later date, this could become the primary method of setting the residual.
9299b7cd975SBarry Smith 
930db781477SPatrick Sanan .seealso: `DMTSSetContext()`, `TSSetFunction()`, `DMTSSetJacobian()`, `TSSetForcingFunction()`, `DMTSGetForcingFunction()`
9319b7cd975SBarry Smith @*/
9329371c9d4SSatish Balay PetscErrorCode DMTSSetForcingFunction(DM dm, TSForcingFunction f, void *ctx) {
9339b7cd975SBarry Smith   DMTS tsdm;
9349b7cd975SBarry Smith 
9359b7cd975SBarry Smith   PetscFunctionBegin;
9369b7cd975SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
9379566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm, &tsdm));
938f8b49ee9SBarry Smith   if (f) tsdm->ops->forcing = f;
9399b7cd975SBarry Smith   if (ctx) tsdm->forcingctx = ctx;
9409b7cd975SBarry Smith   PetscFunctionReturn(0);
9419b7cd975SBarry Smith }
9429b7cd975SBarry Smith 
9439b7cd975SBarry Smith /*@C
9449b7cd975SBarry Smith    DMTSGetForcingFunction - get TS forcing function evaluation function
9459b7cd975SBarry Smith 
9469b7cd975SBarry Smith    Not Collective
9479b7cd975SBarry Smith 
9484165533cSJose E. Roman    Input Parameter:
9499b7cd975SBarry Smith .   dm - DM to be used with TS
9509b7cd975SBarry Smith 
9514165533cSJose E. Roman    Output Parameters:
952f8b49ee9SBarry Smith +  f - forcing function evaluation function; see TSForcingFunction for details
9539b7cd975SBarry Smith -  ctx - context for solution evaluation
9549b7cd975SBarry Smith 
9559b7cd975SBarry Smith    Level: advanced
9569b7cd975SBarry Smith 
9579b7cd975SBarry Smith    Note:
9589b7cd975SBarry Smith    TSSetForcingFunction() is normally used, but it calls this function internally because the user context is actually
9599b7cd975SBarry Smith    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
9609b7cd975SBarry Smith    not. If DM took a more central role at some later date, this could become the primary method of setting the residual.
9619b7cd975SBarry Smith 
962db781477SPatrick Sanan .seealso: `DMTSSetContext()`, `TSSetFunction()`, `DMTSSetJacobian()`, `TSSetForcingFunction()`, `DMTSGetForcingFunction()`
9639b7cd975SBarry Smith @*/
9649371c9d4SSatish Balay PetscErrorCode DMTSGetForcingFunction(DM dm, TSForcingFunction *f, void **ctx) {
9659b7cd975SBarry Smith   DMTS tsdm;
9669b7cd975SBarry Smith 
9679b7cd975SBarry Smith   PetscFunctionBegin;
9689b7cd975SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
9699566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm, &tsdm));
970f8b49ee9SBarry Smith   if (f) *f = tsdm->ops->forcing;
9719b7cd975SBarry Smith   if (ctx) *ctx = tsdm->forcingctx;
9729b7cd975SBarry Smith   PetscFunctionReturn(0);
9739b7cd975SBarry Smith }
9749b7cd975SBarry Smith 
97524989b8cSPeter Brune /*@C
97624989b8cSPeter Brune    DMTSGetRHSFunction - get TS explicit residual evaluation function
97724989b8cSPeter Brune 
97824989b8cSPeter Brune    Not Collective
97924989b8cSPeter Brune 
9804165533cSJose E. Roman    Input Parameter:
98124989b8cSPeter Brune .  dm - DM to be used with TS
98224989b8cSPeter Brune 
9834165533cSJose E. Roman    Output Parameters:
98424989b8cSPeter Brune +  func - residual evaluation function, see TSSetRHSFunction() for calling sequence
98524989b8cSPeter Brune -  ctx - context for residual evaluation
98624989b8cSPeter Brune 
98724989b8cSPeter Brune    Level: advanced
98824989b8cSPeter Brune 
98924989b8cSPeter Brune    Note:
99024989b8cSPeter Brune    TSGetFunction() is normally used, but it calls this function internally because the user context is actually
99124989b8cSPeter Brune    associated with the DM.
99224989b8cSPeter Brune 
993db781477SPatrick Sanan .seealso: `DMTSSetContext()`, `DMTSSetRHSFunction()`, `TSSetRHSFunction()`
99424989b8cSPeter Brune @*/
9959371c9d4SSatish Balay PetscErrorCode DMTSGetRHSFunction(DM dm, TSRHSFunction *func, void **ctx) {
996942e3340SBarry Smith   DMTS tsdm;
99724989b8cSPeter Brune 
99824989b8cSPeter Brune   PetscFunctionBegin;
99924989b8cSPeter Brune   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
10009566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm, &tsdm));
1001d74926cbSBarry Smith   if (func) *func = tsdm->ops->rhsfunction;
1002800f99ffSJeremy L Thompson   if (ctx) {
1003800f99ffSJeremy L Thompson     if (tsdm->rhsfunctionctxcontainer) PetscCall(PetscContainerGetPointer(tsdm->rhsfunctionctxcontainer, ctx));
1004800f99ffSJeremy L Thompson     else *ctx = NULL;
1005800f99ffSJeremy L Thompson   }
100624989b8cSPeter Brune   PetscFunctionReturn(0);
100724989b8cSPeter Brune }
100824989b8cSPeter Brune 
100924989b8cSPeter Brune /*@C
101024989b8cSPeter Brune    DMTSSetIJacobian - set TS Jacobian evaluation function
101124989b8cSPeter Brune 
101224989b8cSPeter Brune    Not Collective
101324989b8cSPeter Brune 
10144165533cSJose E. Roman    Input Parameters:
101524989b8cSPeter Brune +  dm - DM to be used with TS
1016a96d6ef6SBarry Smith .  func - Jacobian evaluation routine
101724989b8cSPeter Brune -  ctx - context for residual evaluation
101824989b8cSPeter Brune 
1019a96d6ef6SBarry Smith    Calling sequence of f:
1020a96d6ef6SBarry Smith $    PetscErrorCode f(TS ts,PetscReal t,Vec U,Vec U_t,PetscReal a,Mat Amat,Mat Pmat,void *ctx);
1021a96d6ef6SBarry Smith 
1022a96d6ef6SBarry Smith +  t    - time at step/stage being solved
1023a96d6ef6SBarry Smith .  U    - state vector
1024a96d6ef6SBarry Smith .  U_t  - time derivative of state vector
1025a96d6ef6SBarry Smith .  a    - shift
1026a96d6ef6SBarry Smith .  Amat - (approximate) Jacobian of F(t,U,W+a*U), equivalent to dF/dU + a*dF/dU_t
1027a96d6ef6SBarry Smith .  Pmat - matrix used for constructing preconditioner, usually the same as Amat
1028a96d6ef6SBarry Smith -  ctx  - [optional] user-defined context for matrix evaluation routine
1029a96d6ef6SBarry Smith 
103024989b8cSPeter Brune    Level: advanced
103124989b8cSPeter Brune 
103224989b8cSPeter Brune    Note:
103324989b8cSPeter Brune    TSSetJacobian() is normally used, but it calls this function internally because the user context is actually
103424989b8cSPeter Brune    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
103524989b8cSPeter Brune    not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian.
103624989b8cSPeter Brune 
1037db781477SPatrick Sanan .seealso: `DMTSSetContext()`, `TSSetRHSFunction()`, `DMTSGetJacobian()`, `TSSetIJacobian()`, `TSSetIFunction()`
103824989b8cSPeter Brune @*/
10399371c9d4SSatish Balay PetscErrorCode DMTSSetIJacobian(DM dm, TSIJacobian func, void *ctx) {
1040800f99ffSJeremy L Thompson   DMTS tsdm;
104124989b8cSPeter Brune 
104224989b8cSPeter Brune   PetscFunctionBegin;
104324989b8cSPeter Brune   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1044800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm, &tsdm));
1045800f99ffSJeremy L Thompson   if (func) tsdm->ops->ijacobian = func;
1046800f99ffSJeremy L Thompson   if (ctx) {
1047800f99ffSJeremy L Thompson     PetscContainer ctxcontainer;
1048800f99ffSJeremy L Thompson     PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)tsdm), &ctxcontainer));
1049800f99ffSJeremy L Thompson     PetscCall(PetscContainerSetPointer(ctxcontainer, ctx));
1050800f99ffSJeremy L Thompson     PetscCall(PetscObjectCompose((PetscObject)tsdm, "ijacobian ctx", (PetscObject)ctxcontainer));
1051800f99ffSJeremy L Thompson     tsdm->ijacobianctxcontainer = ctxcontainer;
1052800f99ffSJeremy L Thompson     PetscCall(PetscContainerDestroy(&ctxcontainer));
1053800f99ffSJeremy L Thompson   }
1054800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
1055800f99ffSJeremy L Thompson }
1056800f99ffSJeremy L Thompson 
1057800f99ffSJeremy L Thompson /*@C
10585cb80ecdSBarry Smith    DMTSSetIJacobianContextDestroy - set `TS` Jacobian evaluation context destroy function
1059800f99ffSJeremy L Thompson 
1060800f99ffSJeremy L Thompson    Not Collective
1061800f99ffSJeremy L Thompson 
1062800f99ffSJeremy L Thompson    Input Parameters:
10635cb80ecdSBarry Smith +  dm - `DM` to be used with `TS`
10645cb80ecdSBarry Smith -  f - Jacobian evaluation context destroy function
1065800f99ffSJeremy L Thompson 
1066800f99ffSJeremy L Thompson    Level: advanced
1067800f99ffSJeremy L Thompson 
1068800f99ffSJeremy L Thompson    Note:
10695cb80ecdSBarry Smith    `TSSetIJacobianContextDestroy()` is normally used, but it calls this function internally because the user context is actually
10705cb80ecdSBarry Smith    associated with the `DM`.  This makes the interface consistent regardless of whether the user interacts with a `DM` or
10715cb80ecdSBarry Smith    not.
1072800f99ffSJeremy L Thompson 
10735cb80ecdSBarry Smith    Developer Note:
10745cb80ecdSBarry Smith    If `DM` took a more central role at some later date, this could become the primary method of setting the Jacobian.
10755cb80ecdSBarry Smith 
10765cb80ecdSBarry Smith .seealso: `TSSetIJacobianContextDestroy()`, `TSSetI2JacobianContextDestroy()`, `DMTSSetIJacobian()`, `TSSetIJacobian()`
1077800f99ffSJeremy L Thompson @*/
10789371c9d4SSatish Balay PetscErrorCode DMTSSetIJacobianContextDestroy(DM dm, PetscErrorCode (*f)(void *)) {
1079800f99ffSJeremy L Thompson   DMTS tsdm;
1080800f99ffSJeremy L Thompson 
1081800f99ffSJeremy L Thompson   PetscFunctionBegin;
1082800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1083800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm, &tsdm));
1084800f99ffSJeremy L Thompson   if (tsdm->ijacobianctxcontainer) PetscCall(PetscContainerSetUserDestroy(tsdm->ijacobianctxcontainer, f));
1085800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
1086800f99ffSJeremy L Thompson }
1087800f99ffSJeremy L Thompson 
10889371c9d4SSatish Balay PetscErrorCode DMTSUnsetIJacobianContext_Internal(DM dm) {
1089800f99ffSJeremy L Thompson   DMTS tsdm;
1090800f99ffSJeremy L Thompson 
1091800f99ffSJeremy L Thompson   PetscFunctionBegin;
1092800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1093800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm, &tsdm));
1094800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetIJacobianContext_DMTS(tsdm));
109524989b8cSPeter Brune   PetscFunctionReturn(0);
109624989b8cSPeter Brune }
109724989b8cSPeter Brune 
109824989b8cSPeter Brune /*@C
109924989b8cSPeter Brune    DMTSGetIJacobian - get TS Jacobian evaluation function
110024989b8cSPeter Brune 
110124989b8cSPeter Brune    Not Collective
110224989b8cSPeter Brune 
11034165533cSJose E. Roman    Input Parameter:
110424989b8cSPeter Brune .  dm - DM to be used with TS
110524989b8cSPeter Brune 
11064165533cSJose E. Roman    Output Parameters:
110724989b8cSPeter Brune +  func - Jacobian evaluation function, see TSSetIJacobian() for calling sequence
110824989b8cSPeter Brune -  ctx - context for residual evaluation
110924989b8cSPeter Brune 
111024989b8cSPeter Brune    Level: advanced
111124989b8cSPeter Brune 
111224989b8cSPeter Brune    Note:
111324989b8cSPeter Brune    TSGetJacobian() is normally used, but it calls this function internally because the user context is actually
111424989b8cSPeter Brune    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
111524989b8cSPeter Brune    not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian.
111624989b8cSPeter Brune 
1117db781477SPatrick Sanan .seealso: `DMTSSetContext()`, `TSSetFunction()`, `DMTSSetJacobian()`
111824989b8cSPeter Brune @*/
11199371c9d4SSatish Balay PetscErrorCode DMTSGetIJacobian(DM dm, TSIJacobian *func, void **ctx) {
1120942e3340SBarry Smith   DMTS tsdm;
112124989b8cSPeter Brune 
112224989b8cSPeter Brune   PetscFunctionBegin;
112324989b8cSPeter Brune   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
11249566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm, &tsdm));
1125d74926cbSBarry Smith   if (func) *func = tsdm->ops->ijacobian;
1126800f99ffSJeremy L Thompson   if (ctx) {
1127800f99ffSJeremy L Thompson     if (tsdm->ijacobianctxcontainer) PetscCall(PetscContainerGetPointer(tsdm->ijacobianctxcontainer, ctx));
1128800f99ffSJeremy L Thompson     else *ctx = NULL;
1129800f99ffSJeremy L Thompson   }
113024989b8cSPeter Brune   PetscFunctionReturn(0);
113124989b8cSPeter Brune }
113224989b8cSPeter Brune 
113324989b8cSPeter Brune /*@C
113424989b8cSPeter Brune    DMTSSetRHSJacobian - set TS Jacobian evaluation function
113524989b8cSPeter Brune 
113624989b8cSPeter Brune    Not Collective
113724989b8cSPeter Brune 
11384165533cSJose E. Roman    Input Parameters:
113924989b8cSPeter Brune +  dm - DM to be used with TS
1140a96d6ef6SBarry Smith .  func - Jacobian evaluation routine
114124989b8cSPeter Brune -  ctx - context for residual evaluation
114224989b8cSPeter Brune 
1143a96d6ef6SBarry Smith    Calling sequence of func:
1144a96d6ef6SBarry Smith $     PetscErrorCode func(TS ts,PetscReal t,Vec u,Mat A,Mat B,void *ctx);
1145a96d6ef6SBarry Smith 
1146a96d6ef6SBarry Smith +  t - current timestep
1147a96d6ef6SBarry Smith .  u - input vector
1148a96d6ef6SBarry Smith .  Amat - (approximate) Jacobian matrix
1149a96d6ef6SBarry Smith .  Pmat - matrix from which preconditioner is to be constructed (usually the same as Amat)
1150a96d6ef6SBarry Smith -  ctx - [optional] user-defined context for matrix evaluation routine
1151a96d6ef6SBarry Smith 
115224989b8cSPeter Brune    Level: advanced
115324989b8cSPeter Brune 
115424989b8cSPeter Brune    Note:
115524989b8cSPeter Brune    TSSetJacobian() is normally used, but it calls this function internally because the user context is actually
115624989b8cSPeter Brune    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
115724989b8cSPeter Brune    not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian.
115824989b8cSPeter Brune 
1159db781477SPatrick Sanan .seealso: `DMTSSetContext()`, `TSSetFunction()`, `DMTSGetJacobian()`, `TSSetRHSJacobian()`
116024989b8cSPeter Brune @*/
11619371c9d4SSatish Balay PetscErrorCode DMTSSetRHSJacobian(DM dm, TSRHSJacobian func, void *ctx) {
1162942e3340SBarry Smith   DMTS tsdm;
116324989b8cSPeter Brune 
116424989b8cSPeter Brune   PetscFunctionBegin;
116524989b8cSPeter Brune   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
11669566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm, &tsdm));
1167d74926cbSBarry Smith   if (func) tsdm->ops->rhsjacobian = func;
1168800f99ffSJeremy L Thompson   if (ctx) {
1169800f99ffSJeremy L Thompson     PetscContainer ctxcontainer;
1170800f99ffSJeremy L Thompson     PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)tsdm), &ctxcontainer));
1171800f99ffSJeremy L Thompson     PetscCall(PetscContainerSetPointer(ctxcontainer, ctx));
1172800f99ffSJeremy L Thompson     PetscCall(PetscObjectCompose((PetscObject)tsdm, "rhs jacobian ctx", (PetscObject)ctxcontainer));
1173800f99ffSJeremy L Thompson     tsdm->rhsjacobianctxcontainer = ctxcontainer;
1174800f99ffSJeremy L Thompson     PetscCall(PetscContainerDestroy(&ctxcontainer));
1175800f99ffSJeremy L Thompson   }
1176800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
1177800f99ffSJeremy L Thompson }
1178800f99ffSJeremy L Thompson 
1179800f99ffSJeremy L Thompson /*@C
11805cb80ecdSBarry Smith    DMTSSetRHSJacobianContextDestroy - set `TS` Jacobian evaluation context destroy function
1181800f99ffSJeremy L Thompson 
1182800f99ffSJeremy L Thompson    Not Collective
1183800f99ffSJeremy L Thompson 
1184800f99ffSJeremy L Thompson    Input Parameters:
11855cb80ecdSBarry Smith +  dm - `DM` to be used with `TS`
11865cb80ecdSBarry Smith -  f - Jacobian evaluation context destroy function
11875cb80ecdSBarry Smith 
11885cb80ecdSBarry Smith    Level: advanced
11895cb80ecdSBarry Smith 
11905cb80ecdSBarry Smith    Note:
11915cb80ecdSBarry Smith    The user usually calls `TSSetRHSJacobianContextDestroy()` which calls this routine
1192800f99ffSJeremy L Thompson 
119387497f52SBarry Smith    Level: advanced
119487497f52SBarry Smith 
1195800f99ffSJeremy L Thompson .seealso: `TSSetRHSJacobianContextDestroy()`, `DMTSSetRHSJacobian()`, `TSSetRHSJacobian()`
1196800f99ffSJeremy L Thompson @*/
11979371c9d4SSatish Balay PetscErrorCode DMTSSetRHSJacobianContextDestroy(DM dm, PetscErrorCode (*f)(void *)) {
1198800f99ffSJeremy L Thompson   DMTS tsdm;
1199800f99ffSJeremy L Thompson 
1200800f99ffSJeremy L Thompson   PetscFunctionBegin;
1201800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1202800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm, &tsdm));
1203800f99ffSJeremy L Thompson   if (tsdm->rhsjacobianctxcontainer) PetscCall(PetscContainerSetUserDestroy(tsdm->rhsjacobianctxcontainer, f));
1204800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
1205800f99ffSJeremy L Thompson }
1206800f99ffSJeremy L Thompson 
12079371c9d4SSatish Balay PetscErrorCode DMTSUnsetRHSJacobianContext_Internal(DM dm) {
1208800f99ffSJeremy L Thompson   DMTS tsdm;
1209800f99ffSJeremy L Thompson 
1210800f99ffSJeremy L Thompson   PetscFunctionBegin;
1211800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1212800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm, &tsdm));
1213800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetRHSJacobianContext_DMTS(tsdm));
121424989b8cSPeter Brune   PetscFunctionReturn(0);
121524989b8cSPeter Brune }
121624989b8cSPeter Brune 
121724989b8cSPeter Brune /*@C
121824989b8cSPeter Brune    DMTSGetRHSJacobian - get TS Jacobian evaluation function
121924989b8cSPeter Brune 
122024989b8cSPeter Brune    Not Collective
122124989b8cSPeter Brune 
12224165533cSJose E. Roman    Input Parameter:
122324989b8cSPeter Brune .  dm - DM to be used with TS
122424989b8cSPeter Brune 
12254165533cSJose E. Roman    Output Parameters:
122624989b8cSPeter Brune +  func - Jacobian evaluation function, see TSSetRHSJacobian() for calling sequence
122724989b8cSPeter Brune -  ctx - context for residual evaluation
122824989b8cSPeter Brune 
122924989b8cSPeter Brune    Level: advanced
123024989b8cSPeter Brune 
123124989b8cSPeter Brune    Note:
123224989b8cSPeter Brune    TSGetJacobian() is normally used, but it calls this function internally because the user context is actually
123324989b8cSPeter Brune    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
123424989b8cSPeter Brune    not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian.
123524989b8cSPeter Brune 
1236db781477SPatrick Sanan .seealso: `DMTSSetContext()`, `TSSetRHSFunction()`, `DMTSSetRHSJacobian()`, `TSSetRHSJacobian()`
123724989b8cSPeter Brune @*/
12389371c9d4SSatish Balay PetscErrorCode DMTSGetRHSJacobian(DM dm, TSRHSJacobian *func, void **ctx) {
1239942e3340SBarry Smith   DMTS tsdm;
124024989b8cSPeter Brune 
124124989b8cSPeter Brune   PetscFunctionBegin;
124224989b8cSPeter Brune   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
12439566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm, &tsdm));
1244d74926cbSBarry Smith   if (func) *func = tsdm->ops->rhsjacobian;
1245800f99ffSJeremy L Thompson   if (ctx) {
1246800f99ffSJeremy L Thompson     if (tsdm->rhsjacobianctxcontainer) PetscCall(PetscContainerGetPointer(tsdm->rhsjacobianctxcontainer, ctx));
1247800f99ffSJeremy L Thompson     else *ctx = NULL;
1248800f99ffSJeremy L Thompson   }
124924989b8cSPeter Brune   PetscFunctionReturn(0);
125024989b8cSPeter Brune }
1251ad6bc421SBarry Smith 
1252ad6bc421SBarry Smith /*@C
1253ad6bc421SBarry Smith    DMTSSetIFunctionSerialize - sets functions used to view and load a IFunction context
1254ad6bc421SBarry Smith 
1255ad6bc421SBarry Smith    Not Collective
1256ad6bc421SBarry Smith 
12574165533cSJose E. Roman    Input Parameters:
1258ad6bc421SBarry Smith +  dm - DM to be used with TS
1259ad6bc421SBarry Smith .  view - viewer function
1260ad6bc421SBarry Smith -  load - loading function
1261ad6bc421SBarry Smith 
1262ad6bc421SBarry Smith    Level: advanced
1263ad6bc421SBarry Smith 
1264db781477SPatrick Sanan .seealso: `DMTSSetContext()`, `TSSetFunction()`, `DMTSSetJacobian()`
1265ad6bc421SBarry Smith @*/
12669371c9d4SSatish Balay PetscErrorCode DMTSSetIFunctionSerialize(DM dm, PetscErrorCode (*view)(void *, PetscViewer), PetscErrorCode (*load)(void **, PetscViewer)) {
1267ad6bc421SBarry Smith   DMTS tsdm;
1268ad6bc421SBarry Smith 
1269ad6bc421SBarry Smith   PetscFunctionBegin;
1270ad6bc421SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
12719566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm, &tsdm));
1272ad6bc421SBarry Smith   tsdm->ops->ifunctionview = view;
1273ad6bc421SBarry Smith   tsdm->ops->ifunctionload = load;
1274ad6bc421SBarry Smith   PetscFunctionReturn(0);
1275ad6bc421SBarry Smith }
1276ad6bc421SBarry Smith 
1277ad6bc421SBarry Smith /*@C
1278ad6bc421SBarry Smith    DMTSSetIJacobianSerialize - sets functions used to view and load a IJacobian context
1279ad6bc421SBarry Smith 
1280ad6bc421SBarry Smith    Not Collective
1281ad6bc421SBarry Smith 
12824165533cSJose E. Roman    Input Parameters:
1283ad6bc421SBarry Smith +  dm - DM to be used with TS
1284ad6bc421SBarry Smith .  view - viewer function
1285ad6bc421SBarry Smith -  load - loading function
1286ad6bc421SBarry Smith 
1287ad6bc421SBarry Smith    Level: advanced
1288ad6bc421SBarry Smith 
1289db781477SPatrick Sanan .seealso: `DMTSSetContext()`, `TSSetFunction()`, `DMTSSetJacobian()`
1290ad6bc421SBarry Smith @*/
12919371c9d4SSatish Balay PetscErrorCode DMTSSetIJacobianSerialize(DM dm, PetscErrorCode (*view)(void *, PetscViewer), PetscErrorCode (*load)(void **, PetscViewer)) {
1292ad6bc421SBarry Smith   DMTS tsdm;
1293ad6bc421SBarry Smith 
1294ad6bc421SBarry Smith   PetscFunctionBegin;
1295ad6bc421SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
12969566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm, &tsdm));
1297ad6bc421SBarry Smith   tsdm->ops->ijacobianview = view;
1298ad6bc421SBarry Smith   tsdm->ops->ijacobianload = load;
1299ad6bc421SBarry Smith   PetscFunctionReturn(0);
1300ad6bc421SBarry Smith }
1301