xref: /petsc/src/ts/utils/dmts.c (revision 346ce6207071b1ad0fb329bdcfa352bf4cdf5769)
1af0996ceSBarry Smith #include <petsc/private/tsimpl.h> /*I "petscts.h" I*/
2af0996ceSBarry Smith #include <petsc/private/dmimpl.h>
324989b8cSPeter Brune 
4d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMTSUnsetRHSFunctionContext_DMTS(DMTS tsdm)
5d71ae5a4SJacob Faibussowitsch {
6800f99ffSJeremy L Thompson   PetscFunctionBegin;
7800f99ffSJeremy L Thompson   PetscCall(PetscObjectCompose((PetscObject)tsdm, "rhs function ctx", NULL));
8800f99ffSJeremy L Thompson   tsdm->rhsfunctionctxcontainer = NULL;
93ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10800f99ffSJeremy L Thompson }
11800f99ffSJeremy L Thompson 
12d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMTSUnsetRHSJacobianContext_DMTS(DMTS tsdm)
13d71ae5a4SJacob Faibussowitsch {
14800f99ffSJeremy L Thompson   PetscFunctionBegin;
15800f99ffSJeremy L Thompson   PetscCall(PetscObjectCompose((PetscObject)tsdm, "rhs jacobian ctx", NULL));
16800f99ffSJeremy L Thompson   tsdm->rhsjacobianctxcontainer = NULL;
173ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
18800f99ffSJeremy L Thompson }
19800f99ffSJeremy L Thompson 
20d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMTSUnsetIFunctionContext_DMTS(DMTS tsdm)
21d71ae5a4SJacob Faibussowitsch {
22800f99ffSJeremy L Thompson   PetscFunctionBegin;
23800f99ffSJeremy L Thompson   PetscCall(PetscObjectCompose((PetscObject)tsdm, "ifunction ctx", NULL));
24800f99ffSJeremy L Thompson   tsdm->ifunctionctxcontainer = NULL;
253ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
26800f99ffSJeremy L Thompson }
27800f99ffSJeremy L Thompson 
28d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMTSUnsetIJacobianContext_DMTS(DMTS tsdm)
29d71ae5a4SJacob Faibussowitsch {
30800f99ffSJeremy L Thompson   PetscFunctionBegin;
31800f99ffSJeremy L Thompson   PetscCall(PetscObjectCompose((PetscObject)tsdm, "ijacobian ctx", NULL));
32800f99ffSJeremy L Thompson   tsdm->ijacobianctxcontainer = NULL;
333ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
34800f99ffSJeremy L Thompson }
35800f99ffSJeremy L Thompson 
36d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMTSUnsetI2FunctionContext_DMTS(DMTS tsdm)
37d71ae5a4SJacob Faibussowitsch {
38800f99ffSJeremy L Thompson   PetscFunctionBegin;
39800f99ffSJeremy L Thompson   PetscCall(PetscObjectCompose((PetscObject)tsdm, "i2function ctx", NULL));
40800f99ffSJeremy L Thompson   tsdm->i2functionctxcontainer = NULL;
413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
42800f99ffSJeremy L Thompson }
43800f99ffSJeremy L Thompson 
44d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMTSUnsetI2JacobianContext_DMTS(DMTS tsdm)
45d71ae5a4SJacob Faibussowitsch {
46800f99ffSJeremy L Thompson   PetscFunctionBegin;
47800f99ffSJeremy L Thompson   PetscCall(PetscObjectCompose((PetscObject)tsdm, "i2jacobian ctx", NULL));
48800f99ffSJeremy L Thompson   tsdm->i2jacobianctxcontainer = NULL;
493ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
50800f99ffSJeremy L Thompson }
51800f99ffSJeremy L Thompson 
52d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMTSDestroy(DMTS *kdm)
53d71ae5a4SJacob Faibussowitsch {
54d74926cbSBarry Smith   PetscFunctionBegin;
553ba16761SJacob Faibussowitsch   if (!*kdm) PetscFunctionReturn(PETSC_SUCCESS);
56d74926cbSBarry Smith   PetscValidHeaderSpecific((*kdm), DMTS_CLASSID, 1);
579371c9d4SSatish Balay   if (--((PetscObject)(*kdm))->refct > 0) {
589371c9d4SSatish Balay     *kdm = NULL;
593ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
609371c9d4SSatish Balay   }
61800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetRHSFunctionContext_DMTS(*kdm));
62800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetRHSJacobianContext_DMTS(*kdm));
63800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetIFunctionContext_DMTS(*kdm));
64800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetIJacobianContext_DMTS(*kdm));
65800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetI2FunctionContext_DMTS(*kdm));
66800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetI2JacobianContext_DMTS(*kdm));
67dbbe0bcdSBarry Smith   PetscTryTypeMethod(*kdm, destroy);
689566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(kdm));
693ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
70d74926cbSBarry Smith }
71d74926cbSBarry Smith 
72d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSLoad(DMTS kdm, PetscViewer viewer)
73d71ae5a4SJacob Faibussowitsch {
742d53ad75SBarry Smith   PetscFunctionBegin;
759566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer, &kdm->ops->ifunction, 1, NULL, PETSC_FUNCTION));
769566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer, &kdm->ops->ifunctionview, 1, NULL, PETSC_FUNCTION));
779566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer, &kdm->ops->ifunctionload, 1, NULL, PETSC_FUNCTION));
78ad6bc421SBarry Smith   if (kdm->ops->ifunctionload) {
79800f99ffSJeremy L Thompson     void *ctx;
80800f99ffSJeremy L Thompson 
81800f99ffSJeremy L Thompson     PetscCall(PetscContainerGetPointer(kdm->ifunctionctxcontainer, &ctx));
82800f99ffSJeremy L Thompson     PetscCall((*kdm->ops->ifunctionload)(&ctx, viewer));
83ad6bc421SBarry Smith   }
849566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer, &kdm->ops->ijacobian, 1, NULL, PETSC_FUNCTION));
859566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer, &kdm->ops->ijacobianview, 1, NULL, PETSC_FUNCTION));
869566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer, &kdm->ops->ijacobianload, 1, NULL, PETSC_FUNCTION));
87ad6bc421SBarry Smith   if (kdm->ops->ijacobianload) {
88800f99ffSJeremy L Thompson     void *ctx;
89800f99ffSJeremy L Thompson 
90800f99ffSJeremy L Thompson     PetscCall(PetscContainerGetPointer(kdm->ijacobianctxcontainer, &ctx));
91800f99ffSJeremy L Thompson     PetscCall((*kdm->ops->ijacobianload)(&ctx, viewer));
92ad6bc421SBarry Smith   }
933ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
942d53ad75SBarry Smith }
952d53ad75SBarry Smith 
96d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSView(DMTS kdm, PetscViewer viewer)
97d71ae5a4SJacob Faibussowitsch {
982d53ad75SBarry Smith   PetscBool isascii, isbinary;
992d53ad75SBarry Smith 
1002d53ad75SBarry Smith   PetscFunctionBegin;
1019566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
1029566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
1032d53ad75SBarry Smith   if (isascii) {
104c7a10e08SBarry Smith #if defined(PETSC_SERIALIZE_FUNCTIONS)
1052d53ad75SBarry Smith     const char *fname;
1062d53ad75SBarry Smith 
1079566063dSJacob Faibussowitsch     PetscCall(PetscFPTFind(kdm->ops->ifunction, &fname));
10848a46eb9SPierre Jolivet     if (fname) PetscCall(PetscViewerASCIIPrintf(viewer, "  IFunction used by TS: %s\n", fname));
1099566063dSJacob Faibussowitsch     PetscCall(PetscFPTFind(kdm->ops->ijacobian, &fname));
11048a46eb9SPierre Jolivet     if (fname) PetscCall(PetscViewerASCIIPrintf(viewer, "  IJacobian function used by TS: %s\n", fname));
111c7a10e08SBarry Smith #endif
1122d53ad75SBarry Smith   } else if (isbinary) {
1133964eb88SJed Brown     struct {
1143964eb88SJed Brown       TSIFunction ifunction;
1159200755eSBarry Smith     } funcstruct;
1169200755eSBarry Smith     struct {
1173964eb88SJed Brown       PetscErrorCode (*ifunctionview)(void *, PetscViewer);
1189200755eSBarry Smith     } funcviewstruct;
1199200755eSBarry Smith     struct {
1203964eb88SJed Brown       PetscErrorCode (*ifunctionload)(void **, PetscViewer);
1219200755eSBarry Smith     } funcloadstruct;
1223964eb88SJed Brown     struct {
1233964eb88SJed Brown       TSIJacobian ijacobian;
1249200755eSBarry Smith     } jacstruct;
1259200755eSBarry Smith     struct {
1263964eb88SJed Brown       PetscErrorCode (*ijacobianview)(void *, PetscViewer);
1279200755eSBarry Smith     } jacviewstruct;
1289200755eSBarry Smith     struct {
1293964eb88SJed Brown       PetscErrorCode (*ijacobianload)(void **, PetscViewer);
1309200755eSBarry Smith     } jacloadstruct;
1313964eb88SJed Brown 
1329200755eSBarry Smith     funcstruct.ifunction         = kdm->ops->ifunction;
1339200755eSBarry Smith     funcviewstruct.ifunctionview = kdm->ops->ifunctionview;
1349200755eSBarry Smith     funcloadstruct.ifunctionload = kdm->ops->ifunctionload;
1359566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWrite(viewer, &funcstruct, 1, PETSC_FUNCTION));
1369566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWrite(viewer, &funcviewstruct, 1, PETSC_FUNCTION));
1379566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWrite(viewer, &funcloadstruct, 1, PETSC_FUNCTION));
138800f99ffSJeremy L Thompson     if (kdm->ops->ifunctionview) {
139800f99ffSJeremy L Thompson       void *ctx;
140800f99ffSJeremy L Thompson 
141800f99ffSJeremy L Thompson       PetscCall(PetscContainerGetPointer(kdm->ifunctionctxcontainer, &ctx));
142800f99ffSJeremy L Thompson       PetscCall((*kdm->ops->ifunctionview)(ctx, viewer));
143800f99ffSJeremy L Thompson     }
1449200755eSBarry Smith     jacstruct.ijacobian         = kdm->ops->ijacobian;
1459200755eSBarry Smith     jacviewstruct.ijacobianview = kdm->ops->ijacobianview;
1469200755eSBarry Smith     jacloadstruct.ijacobianload = kdm->ops->ijacobianload;
1479566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWrite(viewer, &jacstruct, 1, PETSC_FUNCTION));
1489566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWrite(viewer, &jacviewstruct, 1, PETSC_FUNCTION));
1499566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWrite(viewer, &jacloadstruct, 1, PETSC_FUNCTION));
150800f99ffSJeremy L Thompson     if (kdm->ops->ijacobianview) {
151800f99ffSJeremy L Thompson       void *ctx;
152800f99ffSJeremy L Thompson 
153800f99ffSJeremy L Thompson       PetscCall(PetscContainerGetPointer(kdm->ijacobianctxcontainer, &ctx));
154800f99ffSJeremy L Thompson       PetscCall((*kdm->ops->ijacobianview)(ctx, viewer));
155800f99ffSJeremy L Thompson     }
1562d53ad75SBarry Smith   }
1573ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1582d53ad75SBarry Smith }
1592d53ad75SBarry Smith 
160d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMTSCreate(MPI_Comm comm, DMTS *kdm)
161d71ae5a4SJacob Faibussowitsch {
162d74926cbSBarry Smith   PetscFunctionBegin;
1639566063dSJacob Faibussowitsch   PetscCall(TSInitializePackage());
1649566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(*kdm, DMTS_CLASSID, "DMTS", "DMTS", "DMTS", comm, DMTSDestroy, DMTSView));
1653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
166d74926cbSBarry Smith }
16724989b8cSPeter Brune 
1682a34c10cSBarry Smith /* Attaches the DMTS to the coarse level.
16924989b8cSPeter Brune  * Under what conditions should we copy versus duplicate?
17024989b8cSPeter Brune  */
171d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMCoarsenHook_DMTS(DM dm, DM dmc, void *ctx)
172d71ae5a4SJacob Faibussowitsch {
17324989b8cSPeter Brune   PetscFunctionBegin;
1749566063dSJacob Faibussowitsch   PetscCall(DMCopyDMTS(dm, dmc));
1753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
17624989b8cSPeter Brune }
17724989b8cSPeter Brune 
17824989b8cSPeter Brune /* This could restrict auxiliary information to the coarse level.
17924989b8cSPeter Brune  */
180d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMRestrictHook_DMTS(DM dm, Mat Restrict, Vec rscale, Mat Inject, DM dmc, void *ctx)
181d71ae5a4SJacob Faibussowitsch {
18224989b8cSPeter Brune   PetscFunctionBegin;
1833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
18424989b8cSPeter Brune }
18524989b8cSPeter Brune 
186d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMSubDomainHook_DMTS(DM dm, DM subdm, void *ctx)
187d71ae5a4SJacob Faibussowitsch {
188258e1594SPeter Brune   PetscFunctionBegin;
1899566063dSJacob Faibussowitsch   PetscCall(DMCopyDMTS(dm, subdm));
1903ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
191258e1594SPeter Brune }
192258e1594SPeter Brune 
193258e1594SPeter Brune /* This could restrict auxiliary information to the coarse level.
194258e1594SPeter Brune  */
195d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMSubDomainRestrictHook_DMTS(DM dm, VecScatter gscat, VecScatter lscat, DM subdm, void *ctx)
196d71ae5a4SJacob Faibussowitsch {
197258e1594SPeter Brune   PetscFunctionBegin;
1983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
199258e1594SPeter Brune }
200258e1594SPeter Brune 
201d74926cbSBarry Smith /*@C
202bcf0153eSBarry Smith   DMTSCopy - copies the information in a `DMTS` to another `DMTS`
203d74926cbSBarry Smith 
204d74926cbSBarry Smith   Not Collective
205d74926cbSBarry Smith 
2064165533cSJose E. Roman   Input Parameters:
207bcf0153eSBarry Smith + kdm  - Original `DMTS`
208bcf0153eSBarry Smith - nkdm - `DMTS` to receive the data, should have been created with `DMTSCreate()`
209d74926cbSBarry Smith 
210d74926cbSBarry Smith   Level: developer
211d74926cbSBarry Smith 
2121cc06b55SBarry Smith .seealso: [](ch_ts), `DMTSCreate()`, `DMTSDestroy()`
213d74926cbSBarry Smith @*/
214d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSCopy(DMTS kdm, DMTS nkdm)
215d71ae5a4SJacob Faibussowitsch {
21624989b8cSPeter Brune   PetscFunctionBegin;
217d74926cbSBarry Smith   PetscValidHeaderSpecific(kdm, DMTS_CLASSID, 1);
218d74926cbSBarry Smith   PetscValidHeaderSpecific(nkdm, DMTS_CLASSID, 2);
219d74926cbSBarry Smith   nkdm->ops->rhsfunction = kdm->ops->rhsfunction;
220d74926cbSBarry Smith   nkdm->ops->rhsjacobian = kdm->ops->rhsjacobian;
221d74926cbSBarry Smith   nkdm->ops->ifunction   = kdm->ops->ifunction;
222d74926cbSBarry Smith   nkdm->ops->ijacobian   = kdm->ops->ijacobian;
223efe9872eSLisandro Dalcin   nkdm->ops->i2function  = kdm->ops->i2function;
224efe9872eSLisandro Dalcin   nkdm->ops->i2jacobian  = kdm->ops->i2jacobian;
225d74926cbSBarry Smith   nkdm->ops->solution    = kdm->ops->solution;
226d74926cbSBarry Smith   nkdm->ops->destroy     = kdm->ops->destroy;
227d74926cbSBarry Smith   nkdm->ops->duplicate   = kdm->ops->duplicate;
228d74926cbSBarry Smith 
229d74926cbSBarry Smith   nkdm->solutionctx             = kdm->solutionctx;
230800f99ffSJeremy L Thompson   nkdm->rhsfunctionctxcontainer = kdm->rhsfunctionctxcontainer;
231800f99ffSJeremy L Thompson   nkdm->rhsjacobianctxcontainer = kdm->rhsjacobianctxcontainer;
232800f99ffSJeremy L Thompson   nkdm->ifunctionctxcontainer   = kdm->ifunctionctxcontainer;
233800f99ffSJeremy L Thompson   nkdm->ijacobianctxcontainer   = kdm->ijacobianctxcontainer;
234800f99ffSJeremy L Thompson   nkdm->i2functionctxcontainer  = kdm->i2functionctxcontainer;
235800f99ffSJeremy L Thompson   nkdm->i2jacobianctxcontainer  = kdm->i2jacobianctxcontainer;
236800f99ffSJeremy L Thompson   if (nkdm->rhsfunctionctxcontainer) PetscCall(PetscObjectCompose((PetscObject)nkdm, "rhs function ctx", (PetscObject)nkdm->rhsfunctionctxcontainer));
237800f99ffSJeremy L Thompson   if (nkdm->rhsjacobianctxcontainer) PetscCall(PetscObjectCompose((PetscObject)nkdm, "rhs jacobian ctx", (PetscObject)nkdm->rhsjacobianctxcontainer));
238800f99ffSJeremy L Thompson   if (nkdm->ifunctionctxcontainer) PetscCall(PetscObjectCompose((PetscObject)nkdm, "ifunction ctx", (PetscObject)nkdm->ifunctionctxcontainer));
239800f99ffSJeremy L Thompson   if (nkdm->ijacobianctxcontainer) PetscCall(PetscObjectCompose((PetscObject)nkdm, "ijacobian ctx", (PetscObject)nkdm->ijacobianctxcontainer));
240800f99ffSJeremy L Thompson   if (nkdm->i2functionctxcontainer) PetscCall(PetscObjectCompose((PetscObject)nkdm, "i2function ctx", (PetscObject)nkdm->i2functionctxcontainer));
241800f99ffSJeremy L Thompson   if (nkdm->i2jacobianctxcontainer) PetscCall(PetscObjectCompose((PetscObject)nkdm, "i2jacobian ctx", (PetscObject)nkdm->i2jacobianctxcontainer));
242d74926cbSBarry Smith 
243d74926cbSBarry Smith   nkdm->data = kdm->data;
244d74926cbSBarry Smith 
245d74926cbSBarry Smith   /*
246d74926cbSBarry Smith   nkdm->fortran_func_pointers[0] = kdm->fortran_func_pointers[0];
247d74926cbSBarry Smith   nkdm->fortran_func_pointers[1] = kdm->fortran_func_pointers[1];
248d74926cbSBarry Smith   nkdm->fortran_func_pointers[2] = kdm->fortran_func_pointers[2];
249d74926cbSBarry Smith   */
250d74926cbSBarry Smith 
251d74926cbSBarry Smith   /* implementation specific copy hooks */
252dbbe0bcdSBarry Smith   PetscTryTypeMethod(kdm, duplicate, nkdm);
2533ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
25424989b8cSPeter Brune }
25524989b8cSPeter Brune 
25624989b8cSPeter Brune /*@C
257bcf0153eSBarry Smith   DMGetDMTS - get read-only private `DMTS` context from a `DM`
25824989b8cSPeter Brune 
25924989b8cSPeter Brune   Not Collective
26024989b8cSPeter Brune 
2614165533cSJose E. Roman   Input Parameter:
262bcf0153eSBarry Smith . dm - `DM` to be used with `TS`
26324989b8cSPeter Brune 
2644165533cSJose E. Roman   Output Parameter:
265bcf0153eSBarry Smith . tsdm - private `DMTS` context
26624989b8cSPeter Brune 
26724989b8cSPeter Brune   Level: developer
26824989b8cSPeter Brune 
26924989b8cSPeter Brune   Notes:
270bcf0153eSBarry Smith   Use `DMGetDMTSWrite()` if write access is needed. The `DMTSSetXXX()` API should be used wherever possible.
27124989b8cSPeter Brune 
2721cc06b55SBarry Smith .seealso: [](ch_ts), `DMTS`, `DMGetDMTSWrite()`
27324989b8cSPeter Brune @*/
274d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetDMTS(DM dm, DMTS *tsdm)
275d71ae5a4SJacob Faibussowitsch {
27624989b8cSPeter Brune   PetscFunctionBegin;
27724989b8cSPeter Brune   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2782a34c10cSBarry Smith   *tsdm = (DMTS)dm->dmts;
279d74926cbSBarry Smith   if (!*tsdm) {
2809566063dSJacob Faibussowitsch     PetscCall(PetscInfo(dm, "Creating new DMTS\n"));
2819566063dSJacob Faibussowitsch     PetscCall(DMTSCreate(PetscObjectComm((PetscObject)dm), tsdm));
2822a34c10cSBarry Smith     dm->dmts            = (PetscObject)*tsdm;
2835c87d4f4SJunchao Zhang     (*tsdm)->originaldm = dm;
2849566063dSJacob Faibussowitsch     PetscCall(DMCoarsenHookAdd(dm, DMCoarsenHook_DMTS, DMRestrictHook_DMTS, NULL));
2859566063dSJacob Faibussowitsch     PetscCall(DMSubDomainHookAdd(dm, DMSubDomainHook_DMTS, DMSubDomainRestrictHook_DMTS, NULL));
28624989b8cSPeter Brune   }
2873ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
28824989b8cSPeter Brune }
28924989b8cSPeter Brune 
29024989b8cSPeter Brune /*@C
291bcf0153eSBarry Smith   DMGetDMTSWrite - get write access to private `DMTS` context from a `DM`
29224989b8cSPeter Brune 
29324989b8cSPeter Brune   Not Collective
29424989b8cSPeter Brune 
2954165533cSJose E. Roman   Input Parameter:
296bcf0153eSBarry Smith . dm - `DM` to be used with `TS`
29724989b8cSPeter Brune 
2984165533cSJose E. Roman   Output Parameter:
299bcf0153eSBarry Smith . tsdm - private `DMTS` context
30024989b8cSPeter Brune 
30124989b8cSPeter Brune   Level: developer
30224989b8cSPeter Brune 
3031cc06b55SBarry Smith .seealso: [](ch_ts), `DMTS`, `DMGetDMTS()`
30424989b8cSPeter Brune @*/
305d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetDMTSWrite(DM dm, DMTS *tsdm)
306d71ae5a4SJacob Faibussowitsch {
307942e3340SBarry Smith   DMTS sdm;
30824989b8cSPeter Brune 
30924989b8cSPeter Brune   PetscFunctionBegin;
31024989b8cSPeter Brune   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3119566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm, &sdm));
3123c633725SBarry Smith   PetscCheck(sdm->originaldm, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "DMTS has a NULL originaldm");
31324989b8cSPeter Brune   if (sdm->originaldm != dm) { /* Copy on write */
3142a34c10cSBarry Smith     DMTS oldsdm = sdm;
3159566063dSJacob Faibussowitsch     PetscCall(PetscInfo(dm, "Copying DMTS due to write\n"));
3169566063dSJacob Faibussowitsch     PetscCall(DMTSCreate(PetscObjectComm((PetscObject)dm), &sdm));
3179566063dSJacob Faibussowitsch     PetscCall(DMTSCopy(oldsdm, sdm));
3189566063dSJacob Faibussowitsch     PetscCall(DMTSDestroy((DMTS *)&dm->dmts));
3192a34c10cSBarry Smith     dm->dmts        = (PetscObject)sdm;
3205c87d4f4SJunchao Zhang     sdm->originaldm = dm;
32124989b8cSPeter Brune   }
32224989b8cSPeter Brune   *tsdm = sdm;
3233ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32424989b8cSPeter Brune }
32524989b8cSPeter Brune 
32624989b8cSPeter Brune /*@C
327bcf0153eSBarry Smith   DMCopyDMTS - copies a `DM` context to a new `DM`
32824989b8cSPeter Brune 
32924989b8cSPeter Brune   Logically Collective
33024989b8cSPeter Brune 
3314165533cSJose E. Roman   Input Parameters:
332bcf0153eSBarry Smith + dmsrc  - `DM` to obtain context from
333bcf0153eSBarry Smith - dmdest - `DM` to add context to
33424989b8cSPeter Brune 
33524989b8cSPeter Brune   Level: developer
33624989b8cSPeter Brune 
33724989b8cSPeter Brune   Note:
33824989b8cSPeter Brune   The context is copied by reference. This function does not ensure that a context exists.
33924989b8cSPeter Brune 
3401cc06b55SBarry Smith .seealso: [](ch_ts), `DMTS`, `DMGetDMTS()`, `TSSetDM()`
34124989b8cSPeter Brune @*/
342d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCopyDMTS(DM dmsrc, DM dmdest)
343d71ae5a4SJacob Faibussowitsch {
34424989b8cSPeter Brune   PetscFunctionBegin;
34524989b8cSPeter Brune   PetscValidHeaderSpecific(dmsrc, DM_CLASSID, 1);
34624989b8cSPeter Brune   PetscValidHeaderSpecific(dmdest, DM_CLASSID, 2);
3479566063dSJacob Faibussowitsch   PetscCall(DMTSDestroy((DMTS *)&dmdest->dmts));
3482a34c10cSBarry Smith   dmdest->dmts = dmsrc->dmts;
3499566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference(dmdest->dmts));
3509566063dSJacob Faibussowitsch   PetscCall(DMCoarsenHookAdd(dmdest, DMCoarsenHook_DMTS, DMRestrictHook_DMTS, NULL));
3519566063dSJacob Faibussowitsch   PetscCall(DMSubDomainHookAdd(dmdest, DMSubDomainHook_DMTS, DMSubDomainRestrictHook_DMTS, NULL));
3523ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
35324989b8cSPeter Brune }
35424989b8cSPeter Brune 
35524989b8cSPeter Brune /*@C
356bcf0153eSBarry Smith   DMTSSetIFunction - set `TS` implicit function evaluation function
35724989b8cSPeter Brune 
35824989b8cSPeter Brune   Not Collective
35924989b8cSPeter Brune 
3604165533cSJose E. Roman   Input Parameters:
361bcf0153eSBarry Smith + dm   - `DM` to be used with `TS`
362a96d6ef6SBarry Smith . func - function evaluating f(t,u,u_t)
36324989b8cSPeter Brune - ctx  - context for residual evaluation
36424989b8cSPeter Brune 
36524989b8cSPeter Brune   Level: advanced
36624989b8cSPeter Brune 
36724989b8cSPeter Brune   Note:
368*346ce620SStefano Zampini   `TSSetIFunction()` is normally used, but it calls this function internally because the user context is actually
369bcf0153eSBarry Smith   associated with the `DM`.  This makes the interface consistent regardless of whether the user interacts with a `DM` or
37014d0ab18SJacob Faibussowitsch   not. If `DM` took a more central role at some later date, this could become the primary method of setting the residual.
37124989b8cSPeter Brune 
372*346ce620SStefano Zampini .seealso: [](ch_ts), `TS`, `DM`, `TSIFunction`
37324989b8cSPeter Brune @*/
374d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetIFunction(DM dm, TSIFunction func, void *ctx)
375d71ae5a4SJacob Faibussowitsch {
376942e3340SBarry Smith   DMTS tsdm;
37724989b8cSPeter Brune 
37824989b8cSPeter Brune   PetscFunctionBegin;
37924989b8cSPeter Brune   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3809566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm, &tsdm));
381d74926cbSBarry Smith   if (func) tsdm->ops->ifunction = func;
382800f99ffSJeremy L Thompson   if (ctx) {
383800f99ffSJeremy L Thompson     PetscContainer ctxcontainer;
384800f99ffSJeremy L Thompson     PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)tsdm), &ctxcontainer));
385800f99ffSJeremy L Thompson     PetscCall(PetscContainerSetPointer(ctxcontainer, ctx));
386800f99ffSJeremy L Thompson     PetscCall(PetscObjectCompose((PetscObject)tsdm, "ifunction ctx", (PetscObject)ctxcontainer));
387800f99ffSJeremy L Thompson     tsdm->ifunctionctxcontainer = ctxcontainer;
388800f99ffSJeremy L Thompson     PetscCall(PetscContainerDestroy(&ctxcontainer));
389800f99ffSJeremy L Thompson   }
3903ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
391800f99ffSJeremy L Thompson }
392800f99ffSJeremy L Thompson 
393800f99ffSJeremy L Thompson /*@C
3945cb80ecdSBarry Smith   DMTSSetIFunctionContextDestroy - set `TS` implicit evaluation context destroy function
395800f99ffSJeremy L Thompson 
396800f99ffSJeremy L Thompson   Not Collective
397800f99ffSJeremy L Thompson 
398800f99ffSJeremy L Thompson   Input Parameters:
3995cb80ecdSBarry Smith + dm - `DM` to be used with `TS`
4005cb80ecdSBarry Smith - f  - implicit evaluation context destroy function
401800f99ffSJeremy L Thompson 
402800f99ffSJeremy L Thompson   Level: advanced
403800f99ffSJeremy L Thompson 
4041cc06b55SBarry Smith .seealso: [](ch_ts), `DM`, `TS`, `DMTSSetIFunction()`, `TSSetIFunction()`
405800f99ffSJeremy L Thompson @*/
406d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetIFunctionContextDestroy(DM dm, PetscErrorCode (*f)(void *))
407d71ae5a4SJacob Faibussowitsch {
408800f99ffSJeremy L Thompson   DMTS tsdm;
409800f99ffSJeremy L Thompson 
410800f99ffSJeremy L Thompson   PetscFunctionBegin;
411800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
412800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm, &tsdm));
413800f99ffSJeremy L Thompson   if (tsdm->ifunctionctxcontainer) PetscCall(PetscContainerSetUserDestroy(tsdm->ifunctionctxcontainer, f));
4143ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
415800f99ffSJeremy L Thompson }
416800f99ffSJeremy L Thompson 
417d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSUnsetIFunctionContext_Internal(DM dm)
418d71ae5a4SJacob Faibussowitsch {
419800f99ffSJeremy L Thompson   DMTS tsdm;
420800f99ffSJeremy L Thompson 
421800f99ffSJeremy L Thompson   PetscFunctionBegin;
422800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
423800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm, &tsdm));
424800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetIFunctionContext_DMTS(tsdm));
4253ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
42624989b8cSPeter Brune }
42724989b8cSPeter Brune 
42824989b8cSPeter Brune /*@C
429bcf0153eSBarry Smith   DMTSGetIFunction - get `TS` implicit residual evaluation function
43024989b8cSPeter Brune 
43124989b8cSPeter Brune   Not Collective
43224989b8cSPeter Brune 
4334165533cSJose E. Roman   Input Parameter:
434bcf0153eSBarry Smith . dm - `DM` to be used with `TS`
43524989b8cSPeter Brune 
4364165533cSJose E. Roman   Output Parameters:
43720f4b53cSBarry Smith + func - function evaluation function, for calling sequence see `TSSetIFunction()`
43824989b8cSPeter Brune - ctx  - context for residual evaluation
43924989b8cSPeter Brune 
44024989b8cSPeter Brune   Level: advanced
44124989b8cSPeter Brune 
44224989b8cSPeter Brune   Note:
443*346ce620SStefano Zampini   `TSGetIFunction()` is normally used, but it calls this function internally because the user context is actually
444bcf0153eSBarry Smith   associated with the `DM`.
44524989b8cSPeter Brune 
446*346ce620SStefano Zampini .seealso: [](ch_ts), `TS`, `DM`, `DMTSSetIFunction()`
44724989b8cSPeter Brune @*/
448d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSGetIFunction(DM dm, TSIFunction *func, void **ctx)
449d71ae5a4SJacob Faibussowitsch {
450942e3340SBarry Smith   DMTS tsdm;
45124989b8cSPeter Brune 
45224989b8cSPeter Brune   PetscFunctionBegin;
45324989b8cSPeter Brune   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4549566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm, &tsdm));
455d74926cbSBarry Smith   if (func) *func = tsdm->ops->ifunction;
456800f99ffSJeremy L Thompson   if (ctx) {
457800f99ffSJeremy L Thompson     if (tsdm->ifunctionctxcontainer) PetscCall(PetscContainerGetPointer(tsdm->ifunctionctxcontainer, ctx));
458800f99ffSJeremy L Thompson     else *ctx = NULL;
459800f99ffSJeremy L Thompson   }
4603ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
46124989b8cSPeter Brune }
46224989b8cSPeter Brune 
463efe9872eSLisandro Dalcin /*@C
464bcf0153eSBarry Smith   DMTSSetI2Function - set `TS` implicit function evaluation function for 2nd order systems
465efe9872eSLisandro Dalcin 
466efe9872eSLisandro Dalcin   Not Collective
467efe9872eSLisandro Dalcin 
4684165533cSJose E. Roman   Input Parameters:
469bcf0153eSBarry Smith + dm  - `DM` to be used with `TS`
470a96d6ef6SBarry Smith . fun - function evaluation routine
471efe9872eSLisandro Dalcin - ctx - context for residual evaluation
472efe9872eSLisandro Dalcin 
473efe9872eSLisandro Dalcin   Level: advanced
474efe9872eSLisandro Dalcin 
475efe9872eSLisandro Dalcin   Note:
476bcf0153eSBarry Smith   `TSSetI2Function()` is normally used, but it calls this function internally because the user context is actually
477bcf0153eSBarry Smith   associated with the `DM`.
478efe9872eSLisandro Dalcin 
4791cc06b55SBarry Smith .seealso: [](ch_ts), `DM`, `TS`, `TSSetI2Function()`
480efe9872eSLisandro Dalcin @*/
481d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetI2Function(DM dm, TSI2Function fun, void *ctx)
482d71ae5a4SJacob Faibussowitsch {
483efe9872eSLisandro Dalcin   DMTS tsdm;
484efe9872eSLisandro Dalcin 
485efe9872eSLisandro Dalcin   PetscFunctionBegin;
486efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4879566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm, &tsdm));
488efe9872eSLisandro Dalcin   if (fun) tsdm->ops->i2function = fun;
489800f99ffSJeremy L Thompson   if (ctx) {
490800f99ffSJeremy L Thompson     PetscContainer ctxcontainer;
491800f99ffSJeremy L Thompson     PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)tsdm), &ctxcontainer));
492800f99ffSJeremy L Thompson     PetscCall(PetscContainerSetPointer(ctxcontainer, ctx));
493800f99ffSJeremy L Thompson     PetscCall(PetscObjectCompose((PetscObject)tsdm, "i2function ctx", (PetscObject)ctxcontainer));
494800f99ffSJeremy L Thompson     tsdm->i2functionctxcontainer = ctxcontainer;
495800f99ffSJeremy L Thompson     PetscCall(PetscContainerDestroy(&ctxcontainer));
496800f99ffSJeremy L Thompson   }
4973ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
498800f99ffSJeremy L Thompson }
499800f99ffSJeremy L Thompson 
500800f99ffSJeremy L Thompson /*@C
5015cb80ecdSBarry Smith   DMTSSetI2FunctionContextDestroy - set `TS` implicit evaluation for 2nd order systems context destroy
502800f99ffSJeremy L Thompson 
503800f99ffSJeremy L Thompson   Not Collective
504800f99ffSJeremy L Thompson 
505800f99ffSJeremy L Thompson   Input Parameters:
5065cb80ecdSBarry Smith + dm - `DM` to be used with `TS`
5075cb80ecdSBarry Smith - f  - implicit evaluation context destroy function
508800f99ffSJeremy L Thompson 
509800f99ffSJeremy L Thompson   Level: advanced
510800f99ffSJeremy L Thompson 
511800f99ffSJeremy L Thompson   Note:
5125cb80ecdSBarry Smith   `TSSetI2FunctionContextDestroy()` is normally used, but it calls this function internally because the user context is actually
5135cb80ecdSBarry Smith   associated with the `DM`.
514800f99ffSJeremy L Thompson 
5151cc06b55SBarry Smith .seealso: [](ch_ts), `TSSetI2FunctionContextDestroy()`, `DMTSSetI2Function()`, `TSSetI2Function()`
516800f99ffSJeremy L Thompson @*/
517d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetI2FunctionContextDestroy(DM dm, PetscErrorCode (*f)(void *))
518d71ae5a4SJacob Faibussowitsch {
519800f99ffSJeremy L Thompson   DMTS tsdm;
520800f99ffSJeremy L Thompson 
521800f99ffSJeremy L Thompson   PetscFunctionBegin;
522800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
523800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm, &tsdm));
524800f99ffSJeremy L Thompson   if (tsdm->i2functionctxcontainer) PetscCall(PetscContainerSetUserDestroy(tsdm->i2functionctxcontainer, f));
5253ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
526800f99ffSJeremy L Thompson }
527800f99ffSJeremy L Thompson 
528d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSUnsetI2FunctionContext_Internal(DM dm)
529d71ae5a4SJacob Faibussowitsch {
530800f99ffSJeremy L Thompson   DMTS tsdm;
531800f99ffSJeremy L Thompson 
532800f99ffSJeremy L Thompson   PetscFunctionBegin;
533800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
534800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm, &tsdm));
535800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetI2FunctionContext_DMTS(tsdm));
5363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
537efe9872eSLisandro Dalcin }
538efe9872eSLisandro Dalcin 
539efe9872eSLisandro Dalcin /*@C
540bcf0153eSBarry Smith   DMTSGetI2Function - get `TS` implicit residual evaluation function for 2nd order systems
541efe9872eSLisandro Dalcin 
542efe9872eSLisandro Dalcin   Not Collective
543efe9872eSLisandro Dalcin 
5444165533cSJose E. Roman   Input Parameter:
545bcf0153eSBarry Smith . dm - `DM` to be used with `TS`
546efe9872eSLisandro Dalcin 
5474165533cSJose E. Roman   Output Parameters:
54820f4b53cSBarry Smith + fun - function evaluation function, for calling sequence see `TSSetI2Function()`
549efe9872eSLisandro Dalcin - ctx - context for residual evaluation
550efe9872eSLisandro Dalcin 
551efe9872eSLisandro Dalcin   Level: advanced
552efe9872eSLisandro Dalcin 
553efe9872eSLisandro Dalcin   Note:
554bcf0153eSBarry Smith   `TSGetI2Function()` is normally used, but it calls this function internally because the user context is actually
555bcf0153eSBarry Smith   associated with the `DM`.
556efe9872eSLisandro Dalcin 
5571cc06b55SBarry Smith .seealso: [](ch_ts), `DM`, `TS`, `DMTSSetI2Function()`, `TSGetI2Function()`
558efe9872eSLisandro Dalcin @*/
559d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSGetI2Function(DM dm, TSI2Function *fun, void **ctx)
560d71ae5a4SJacob Faibussowitsch {
561efe9872eSLisandro Dalcin   DMTS tsdm;
562efe9872eSLisandro Dalcin 
563efe9872eSLisandro Dalcin   PetscFunctionBegin;
564efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5659566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm, &tsdm));
566efe9872eSLisandro Dalcin   if (fun) *fun = tsdm->ops->i2function;
567800f99ffSJeremy L Thompson   if (ctx) {
568800f99ffSJeremy L Thompson     if (tsdm->i2functionctxcontainer) PetscCall(PetscContainerGetPointer(tsdm->i2functionctxcontainer, ctx));
569800f99ffSJeremy L Thompson     else *ctx = NULL;
570800f99ffSJeremy L Thompson   }
5713ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
572efe9872eSLisandro Dalcin }
573efe9872eSLisandro Dalcin 
574efe9872eSLisandro Dalcin /*@C
575bcf0153eSBarry Smith   DMTSSetI2Jacobian - set `TS` implicit Jacobian evaluation function for 2nd order systems
576efe9872eSLisandro Dalcin 
577efe9872eSLisandro Dalcin   Not Collective
578efe9872eSLisandro Dalcin 
5794165533cSJose E. Roman   Input Parameters:
580bcf0153eSBarry Smith + dm  - `DM` to be used with `TS`
58114d0ab18SJacob Faibussowitsch . jac - Jacobian evaluation routine
582efe9872eSLisandro Dalcin - ctx - context for Jacobian evaluation
583efe9872eSLisandro Dalcin 
584efe9872eSLisandro Dalcin   Level: advanced
585efe9872eSLisandro Dalcin 
586efe9872eSLisandro Dalcin   Note:
587bcf0153eSBarry Smith   `TSSetI2Jacobian()` is normally used, but it calls this function internally because the user context is actually
588bcf0153eSBarry Smith   associated with the `DM`.
589efe9872eSLisandro Dalcin 
59014d0ab18SJacob Faibussowitsch .seealso: [](ch_ts), `DM`, `TS`, `TSI2Jacobian`, `TSSetI2Jacobian()`
591efe9872eSLisandro Dalcin @*/
592d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetI2Jacobian(DM dm, TSI2Jacobian jac, void *ctx)
593d71ae5a4SJacob Faibussowitsch {
594efe9872eSLisandro Dalcin   DMTS tsdm;
595efe9872eSLisandro Dalcin 
596efe9872eSLisandro Dalcin   PetscFunctionBegin;
597efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5989566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm, &tsdm));
599efe9872eSLisandro Dalcin   if (jac) tsdm->ops->i2jacobian = jac;
600800f99ffSJeremy L Thompson   if (ctx) {
601800f99ffSJeremy L Thompson     PetscContainer ctxcontainer;
602800f99ffSJeremy L Thompson     PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)tsdm), &ctxcontainer));
603800f99ffSJeremy L Thompson     PetscCall(PetscContainerSetPointer(ctxcontainer, ctx));
604800f99ffSJeremy L Thompson     PetscCall(PetscObjectCompose((PetscObject)tsdm, "i2jacobian ctx", (PetscObject)ctxcontainer));
605800f99ffSJeremy L Thompson     tsdm->i2jacobianctxcontainer = ctxcontainer;
606800f99ffSJeremy L Thompson     PetscCall(PetscContainerDestroy(&ctxcontainer));
607800f99ffSJeremy L Thompson   }
6083ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
609800f99ffSJeremy L Thompson }
610800f99ffSJeremy L Thompson 
611800f99ffSJeremy L Thompson /*@C
6125cb80ecdSBarry Smith   DMTSSetI2JacobianContextDestroy - set `TS` implicit Jacobian evaluation for 2nd order systems context destroy function
613800f99ffSJeremy L Thompson 
614800f99ffSJeremy L Thompson   Not Collective
615800f99ffSJeremy L Thompson 
616800f99ffSJeremy L Thompson   Input Parameters:
6175cb80ecdSBarry Smith + dm - `DM` to be used with `TS`
6185cb80ecdSBarry Smith - f  - implicit Jacobian evaluation context destroy function
619800f99ffSJeremy L Thompson 
62087497f52SBarry Smith   Level: advanced
62187497f52SBarry Smith 
6221cc06b55SBarry Smith .seealso: [](ch_ts), `DM`, `TS`, `TSSetI2JacobianContextDestroy()`, `DMTSSetI2Jacobian()`, `TSSetI2Jacobian()`
623800f99ffSJeremy L Thompson @*/
624d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetI2JacobianContextDestroy(DM dm, PetscErrorCode (*f)(void *))
625d71ae5a4SJacob Faibussowitsch {
626800f99ffSJeremy L Thompson   DMTS tsdm;
627800f99ffSJeremy L Thompson 
628800f99ffSJeremy L Thompson   PetscFunctionBegin;
629800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
630800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm, &tsdm));
631800f99ffSJeremy L Thompson   if (tsdm->i2jacobianctxcontainer) PetscCall(PetscContainerSetUserDestroy(tsdm->i2jacobianctxcontainer, f));
6323ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
633800f99ffSJeremy L Thompson }
634800f99ffSJeremy L Thompson 
635d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSUnsetI2JacobianContext_Internal(DM dm)
636d71ae5a4SJacob Faibussowitsch {
637800f99ffSJeremy L Thompson   DMTS tsdm;
638800f99ffSJeremy L Thompson 
639800f99ffSJeremy L Thompson   PetscFunctionBegin;
640800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
641800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm, &tsdm));
642800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetI2JacobianContext_DMTS(tsdm));
6433ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
644efe9872eSLisandro Dalcin }
645efe9872eSLisandro Dalcin 
646efe9872eSLisandro Dalcin /*@C
647bcf0153eSBarry Smith   DMTSGetI2Jacobian - get `TS` implicit Jacobian evaluation function for 2nd order systems
648efe9872eSLisandro Dalcin 
649efe9872eSLisandro Dalcin   Not Collective
650efe9872eSLisandro Dalcin 
6514165533cSJose E. Roman   Input Parameter:
652bcf0153eSBarry Smith . dm - `DM` to be used with `TS`
653efe9872eSLisandro Dalcin 
6544165533cSJose E. Roman   Output Parameters:
65520f4b53cSBarry Smith + jac - Jacobian evaluation function,  for calling sequence see `TSSetI2Jacobian()`
656efe9872eSLisandro Dalcin - ctx - context for Jacobian evaluation
657efe9872eSLisandro Dalcin 
658efe9872eSLisandro Dalcin   Level: advanced
659efe9872eSLisandro Dalcin 
660efe9872eSLisandro Dalcin   Note:
661bcf0153eSBarry Smith   `TSGetI2Jacobian()` is normally used, but it calls this function internally because the user context is actually
662bcf0153eSBarry Smith   associated with the `DM`.
663efe9872eSLisandro Dalcin 
6641cc06b55SBarry Smith .seealso: [](ch_ts), `DM`, `TS`, `DMTSSetI2Jacobian()`, `TSGetI2Jacobian()`
665efe9872eSLisandro Dalcin @*/
666d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSGetI2Jacobian(DM dm, TSI2Jacobian *jac, void **ctx)
667d71ae5a4SJacob Faibussowitsch {
668efe9872eSLisandro Dalcin   DMTS tsdm;
669efe9872eSLisandro Dalcin 
670efe9872eSLisandro Dalcin   PetscFunctionBegin;
671efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6729566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm, &tsdm));
673efe9872eSLisandro Dalcin   if (jac) *jac = tsdm->ops->i2jacobian;
674800f99ffSJeremy L Thompson   if (ctx) {
675800f99ffSJeremy L Thompson     if (tsdm->i2jacobianctxcontainer) PetscCall(PetscContainerGetPointer(tsdm->i2jacobianctxcontainer, ctx));
676800f99ffSJeremy L Thompson     else *ctx = NULL;
677800f99ffSJeremy L Thompson   }
6783ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
679efe9872eSLisandro Dalcin }
68024989b8cSPeter Brune 
68124989b8cSPeter Brune /*@C
682bcf0153eSBarry Smith   DMTSSetRHSFunction - set `TS` explicit residual evaluation function
68324989b8cSPeter Brune 
68424989b8cSPeter Brune   Not Collective
68524989b8cSPeter Brune 
6864165533cSJose E. Roman   Input Parameters:
687bcf0153eSBarry Smith + dm   - `DM` to be used with `TS`
688a96d6ef6SBarry Smith . func - RHS function evaluation routine
68924989b8cSPeter Brune - ctx  - context for residual evaluation
69024989b8cSPeter Brune 
69124989b8cSPeter Brune   Level: advanced
69224989b8cSPeter Brune 
69324989b8cSPeter Brune   Note:
694bcf0153eSBarry Smith   `TSSetRHSFunction()` is normally used, but it calls this function internally because the user context is actually
695bcf0153eSBarry Smith   associated with the `DM`.  This makes the interface consistent regardless of whether the user interacts with a `DM` or
696bcf0153eSBarry Smith   not. If `DM` took a more central role at some later date, this could become the primary method of setting the residual.
69724989b8cSPeter Brune 
698*346ce620SStefano Zampini .seealso: [](ch_ts), `DM`, `TS`, `TSRHSFunction`
69924989b8cSPeter Brune @*/
700d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetRHSFunction(DM dm, TSRHSFunction func, void *ctx)
701d71ae5a4SJacob Faibussowitsch {
702942e3340SBarry Smith   DMTS tsdm;
70324989b8cSPeter Brune 
70424989b8cSPeter Brune   PetscFunctionBegin;
70524989b8cSPeter Brune   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7069566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm, &tsdm));
707d74926cbSBarry Smith   if (func) tsdm->ops->rhsfunction = func;
708800f99ffSJeremy L Thompson   if (ctx) {
709800f99ffSJeremy L Thompson     PetscContainer ctxcontainer;
710800f99ffSJeremy L Thompson     PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)tsdm), &ctxcontainer));
711800f99ffSJeremy L Thompson     PetscCall(PetscContainerSetPointer(ctxcontainer, ctx));
712800f99ffSJeremy L Thompson     PetscCall(PetscObjectCompose((PetscObject)tsdm, "rhs function ctx", (PetscObject)ctxcontainer));
713800f99ffSJeremy L Thompson     tsdm->rhsfunctionctxcontainer = ctxcontainer;
714800f99ffSJeremy L Thompson     PetscCall(PetscContainerDestroy(&ctxcontainer));
715800f99ffSJeremy L Thompson   }
7163ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
717800f99ffSJeremy L Thompson }
718800f99ffSJeremy L Thompson 
719800f99ffSJeremy L Thompson /*@C
7205cb80ecdSBarry Smith   DMTSSetRHSFunctionContextDestroy - set `TS` explicit residual evaluation context destroy function
721800f99ffSJeremy L Thompson 
722800f99ffSJeremy L Thompson   Not Collective
723800f99ffSJeremy L Thompson 
724800f99ffSJeremy L Thompson   Input Parameters:
7255cb80ecdSBarry Smith + dm - `DM` to be used with `TS`
7265cb80ecdSBarry Smith - f  - explicit evaluation context destroy function
727800f99ffSJeremy L Thompson 
728800f99ffSJeremy L Thompson   Level: advanced
729800f99ffSJeremy L Thompson 
730800f99ffSJeremy L Thompson   Note:
7315cb80ecdSBarry Smith   `TSSetRHSFunctionContextDestroy()` is normally used, but it calls this function internally because the user context is actually
7325cb80ecdSBarry Smith   associated with the `DM`.  This makes the interface consistent regardless of whether the user interacts with a `DM` or
7335cb80ecdSBarry Smith   not.
7345cb80ecdSBarry Smith 
735b43aa488SJacob Faibussowitsch   Developer Notes:
7365cb80ecdSBarry Smith   If `DM` took a more central role at some later date, this could become the primary method of setting the residual.
737800f99ffSJeremy L Thompson 
7381cc06b55SBarry Smith .seealso: [](ch_ts), `TSSetRHSFunctionContextDestroy()`, `DMTSSetRHSFunction()`, `TSSetRHSFunction()`
739800f99ffSJeremy L Thompson @*/
740d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetRHSFunctionContextDestroy(DM dm, PetscErrorCode (*f)(void *))
741d71ae5a4SJacob Faibussowitsch {
742800f99ffSJeremy L Thompson   DMTS tsdm;
743800f99ffSJeremy L Thompson 
744800f99ffSJeremy L Thompson   PetscFunctionBegin;
745800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
746800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm, &tsdm));
747800f99ffSJeremy L Thompson   if (tsdm->rhsfunctionctxcontainer) PetscCall(PetscContainerSetUserDestroy(tsdm->rhsfunctionctxcontainer, f));
7483ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
749800f99ffSJeremy L Thompson }
750800f99ffSJeremy L Thompson 
751d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSUnsetRHSFunctionContext_Internal(DM dm)
752d71ae5a4SJacob Faibussowitsch {
753800f99ffSJeremy L Thompson   DMTS tsdm;
754800f99ffSJeremy L Thompson 
755800f99ffSJeremy L Thompson   PetscFunctionBegin;
756800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
757800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm, &tsdm));
758800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetRHSFunctionContext_DMTS(tsdm));
759800f99ffSJeremy L Thompson   tsdm->rhsfunctionctxcontainer = NULL;
7603ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
76124989b8cSPeter Brune }
76224989b8cSPeter Brune 
763ef20d060SBarry Smith /*@C
764e3c11fc1SJed Brown   DMTSSetTransientVariable - sets function to transform from state to transient variables
765e3c11fc1SJed Brown 
766e3c11fc1SJed Brown   Logically Collective
767e3c11fc1SJed Brown 
7684165533cSJose E. Roman   Input Parameters:
769bcf0153eSBarry Smith + dm   - `DM` to be used with `TS`
770a96d6ef6SBarry Smith . tvar - a function that transforms to transient variables
771e3c11fc1SJed Brown - ctx  - a context for tvar
772e3c11fc1SJed Brown 
773e3c11fc1SJed Brown   Level: advanced
774e3c11fc1SJed Brown 
775e3c11fc1SJed Brown   Notes:
776bcf0153eSBarry Smith   This is typically used to transform from primitive to conservative variables so that a time integrator (e.g., `TSBDF`)
777e3c11fc1SJed Brown   can be conservative.  In this context, primitive variables P are used to model the state (e.g., because they lead to
778e3c11fc1SJed Brown   well-conditioned formulations even in limiting cases such as low-Mach or zero porosity).  The transient variable is
779e3c11fc1SJed Brown   C(P), specified by calling this function.  An IFunction thus receives arguments (P, Cdot) and the IJacobian must be
780e3c11fc1SJed Brown   evaluated via the chain rule, as in
781e3c11fc1SJed Brown 
782e3c11fc1SJed Brown   dF/dP + shift * dF/dCdot dC/dP.
783e3c11fc1SJed Brown 
7841cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSBDF`, `TSSetTransientVariable()`, `DMTSGetTransientVariable()`, `DMTSSetIFunction()`, `DMTSSetIJacobian()`
785e3c11fc1SJed Brown @*/
786d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetTransientVariable(DM dm, TSTransientVariable tvar, void *ctx)
787d71ae5a4SJacob Faibussowitsch {
788e3c11fc1SJed Brown   DMTS dmts;
789e3c11fc1SJed Brown 
790e3c11fc1SJed Brown   PetscFunctionBegin;
791e3c11fc1SJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7929566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm, &dmts));
793e3c11fc1SJed Brown   dmts->ops->transientvar = tvar;
794e3c11fc1SJed Brown   dmts->transientvarctx   = ctx;
7953ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
796e3c11fc1SJed Brown }
797e3c11fc1SJed Brown 
798e3c11fc1SJed Brown /*@C
799bcf0153eSBarry Smith   DMTSGetTransientVariable - gets function to transform from state to transient variables set with `DMTSSetTransientVariable()`
800e3c11fc1SJed Brown 
801e3c11fc1SJed Brown   Logically Collective
802e3c11fc1SJed Brown 
8034165533cSJose E. Roman   Input Parameter:
804bcf0153eSBarry Smith . dm - `DM` to be used with `TS`
805e3c11fc1SJed Brown 
8064165533cSJose E. Roman   Output Parameters:
807a96d6ef6SBarry Smith + tvar - a function that transforms to transient variables
808e3c11fc1SJed Brown - ctx  - a context for tvar
809e3c11fc1SJed Brown 
810e3c11fc1SJed Brown   Level: advanced
811e3c11fc1SJed Brown 
8121cc06b55SBarry Smith .seealso: [](ch_ts), `DM`, `DMTSSetTransientVariable()`, `DMTSGetIFunction()`, `DMTSGetIJacobian()`
813e3c11fc1SJed Brown @*/
814d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSGetTransientVariable(DM dm, TSTransientVariable *tvar, void *ctx)
815d71ae5a4SJacob Faibussowitsch {
816e3c11fc1SJed Brown   DMTS dmts;
817e3c11fc1SJed Brown 
818e3c11fc1SJed Brown   PetscFunctionBegin;
819e3c11fc1SJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8209566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm, &dmts));
821e3c11fc1SJed Brown   if (tvar) *tvar = dmts->ops->transientvar;
822e3c11fc1SJed Brown   if (ctx) *(void **)ctx = dmts->transientvarctx;
8233ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
824e3c11fc1SJed Brown }
825e3c11fc1SJed Brown 
826e3c11fc1SJed Brown /*@C
827bcf0153eSBarry Smith   DMTSGetSolutionFunction - gets the `TS` solution evaluation function
828ef20d060SBarry Smith 
829ef20d060SBarry Smith   Not Collective
830ef20d060SBarry Smith 
8314165533cSJose E. Roman   Input Parameter:
832bcf0153eSBarry Smith . dm - `DM` to be used with `TS`
833ef20d060SBarry Smith 
834ef20d060SBarry Smith   Output Parameters:
83520f4b53cSBarry Smith + func - solution function evaluation function, for calling sequence see `TSSetSolution()`
836ef20d060SBarry Smith - ctx  - context for solution evaluation
837ef20d060SBarry Smith 
838ef20d060SBarry Smith   Level: advanced
839ef20d060SBarry Smith 
840*346ce620SStefano Zampini .seealso: [](ch_ts), `TS`, `DM`, `DMTSSetSolutionFunction()`
841ef20d060SBarry Smith @*/
842d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSGetSolutionFunction(DM dm, TSSolutionFunction *func, void **ctx)
843d71ae5a4SJacob Faibussowitsch {
844942e3340SBarry Smith   DMTS tsdm;
845ef20d060SBarry Smith 
846ef20d060SBarry Smith   PetscFunctionBegin;
847ef20d060SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8489566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm, &tsdm));
849d74926cbSBarry Smith   if (func) *func = tsdm->ops->solution;
850ef20d060SBarry Smith   if (ctx) *ctx = tsdm->solutionctx;
8513ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
852ef20d060SBarry Smith }
853ef20d060SBarry Smith 
854ef20d060SBarry Smith /*@C
855bcf0153eSBarry Smith   DMTSSetSolutionFunction - set `TS` solution evaluation function
856ef20d060SBarry Smith 
857ef20d060SBarry Smith   Not Collective
858ef20d060SBarry Smith 
8594165533cSJose E. Roman   Input Parameters:
860bcf0153eSBarry Smith + dm   - `DM` to be used with `TS`
861a96d6ef6SBarry Smith . func - solution function evaluation routine
862ef20d060SBarry Smith - ctx  - context for solution evaluation
863ef20d060SBarry Smith 
864ef20d060SBarry Smith   Level: advanced
865ef20d060SBarry Smith 
866ef20d060SBarry Smith   Note:
867bcf0153eSBarry Smith   `TSSetSolutionFunction()` is normally used, but it calls this function internally because the user context is actually
868bcf0153eSBarry Smith   associated with the `DM`.  This makes the interface consistent regardless of whether the user interacts with a `DM` or
869bcf0153eSBarry Smith   not. If `DM` took a more central role at some later date, this could become the primary method of setting the residual.
870ef20d060SBarry Smith 
871*346ce620SStefano Zampini .seealso: [](ch_ts), `DM`, `TS`, `DMTSGetSolutionFunction()`
872ef20d060SBarry Smith @*/
873d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetSolutionFunction(DM dm, TSSolutionFunction func, void *ctx)
874d71ae5a4SJacob Faibussowitsch {
875942e3340SBarry Smith   DMTS tsdm;
876ef20d060SBarry Smith 
877ef20d060SBarry Smith   PetscFunctionBegin;
878ef20d060SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8799566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm, &tsdm));
880d74926cbSBarry Smith   if (func) tsdm->ops->solution = func;
881ef20d060SBarry Smith   if (ctx) tsdm->solutionctx = ctx;
8823ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
883ef20d060SBarry Smith }
884ef20d060SBarry Smith 
8859b7cd975SBarry Smith /*@C
886bcf0153eSBarry Smith   DMTSSetForcingFunction - set `TS` forcing function evaluation function
8879b7cd975SBarry Smith 
8889b7cd975SBarry Smith   Not Collective
8899b7cd975SBarry Smith 
8904165533cSJose E. Roman   Input Parameters:
891bcf0153eSBarry Smith + dm   - `DM` to be used with `TS`
8922fe279fdSBarry Smith . func - forcing function evaluation routine
8939b7cd975SBarry Smith - ctx  - context for solution evaluation
8949b7cd975SBarry Smith 
8959b7cd975SBarry Smith   Level: advanced
8969b7cd975SBarry Smith 
8979b7cd975SBarry Smith   Note:
898bcf0153eSBarry Smith   `TSSetForcingFunction()` is normally used, but it calls this function internally because the user context is actually
899bcf0153eSBarry Smith   associated with the `DM`.  This makes the interface consistent regardless of whether the user interacts with a `DM` or
900bcf0153eSBarry Smith   not. If `DM` took a more central role at some later date, this could become the primary method of setting the residual.
9019b7cd975SBarry Smith 
902*346ce620SStefano Zampini .seealso: [](ch_ts), `DM`, `TS`, `TSForcingFunction`, `TSSetForcingFunction()`, `DMTSGetForcingFunction()`
9039b7cd975SBarry Smith @*/
9042fe279fdSBarry Smith PetscErrorCode DMTSSetForcingFunction(DM dm, TSForcingFunction func, void *ctx)
905d71ae5a4SJacob Faibussowitsch {
9069b7cd975SBarry Smith   DMTS tsdm;
9079b7cd975SBarry Smith 
9089b7cd975SBarry Smith   PetscFunctionBegin;
9099b7cd975SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
9109566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm, &tsdm));
9112fe279fdSBarry Smith   if (func) tsdm->ops->forcing = func;
9129b7cd975SBarry Smith   if (ctx) tsdm->forcingctx = ctx;
9133ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9149b7cd975SBarry Smith }
9159b7cd975SBarry Smith 
9169b7cd975SBarry Smith /*@C
917bcf0153eSBarry Smith   DMTSGetForcingFunction - get `TS` forcing function evaluation function
9189b7cd975SBarry Smith 
9199b7cd975SBarry Smith   Not Collective
9209b7cd975SBarry Smith 
9214165533cSJose E. Roman   Input Parameter:
922bcf0153eSBarry Smith . dm - `DM` to be used with `TS`
9239b7cd975SBarry Smith 
9244165533cSJose E. Roman   Output Parameters:
925bcf0153eSBarry Smith + f   - forcing function evaluation function; see `TSForcingFunction` for details
9269b7cd975SBarry Smith - ctx - context for solution evaluation
9279b7cd975SBarry Smith 
9289b7cd975SBarry Smith   Level: advanced
9299b7cd975SBarry Smith 
9309b7cd975SBarry Smith   Note:
931bcf0153eSBarry Smith   `TSSetForcingFunction()` is normally used, but it calls this function internally because the user context is actually
932bcf0153eSBarry Smith   associated with the `DM`.  This makes the interface consistent regardless of whether the user interacts with a `DM` or
933bcf0153eSBarry Smith   not. If `DM` took a more central role at some later date, this could become the primary method of setting the residual.
9349b7cd975SBarry Smith 
935*346ce620SStefano Zampini .seealso: [](ch_ts), `TS`, `DM`, `TSSetForcingFunction()`
9369b7cd975SBarry Smith @*/
937d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSGetForcingFunction(DM dm, TSForcingFunction *f, void **ctx)
938d71ae5a4SJacob Faibussowitsch {
9399b7cd975SBarry Smith   DMTS tsdm;
9409b7cd975SBarry Smith 
9419b7cd975SBarry Smith   PetscFunctionBegin;
9429b7cd975SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
9439566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm, &tsdm));
944f8b49ee9SBarry Smith   if (f) *f = tsdm->ops->forcing;
9459b7cd975SBarry Smith   if (ctx) *ctx = tsdm->forcingctx;
9463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9479b7cd975SBarry Smith }
9489b7cd975SBarry Smith 
94924989b8cSPeter Brune /*@C
950bcf0153eSBarry Smith   DMTSGetRHSFunction - get `TS` explicit residual evaluation function
95124989b8cSPeter Brune 
95224989b8cSPeter Brune   Not Collective
95324989b8cSPeter Brune 
9544165533cSJose E. Roman   Input Parameter:
955bcf0153eSBarry Smith . dm - `DM` to be used with `TS`
95624989b8cSPeter Brune 
9574165533cSJose E. Roman   Output Parameters:
95820f4b53cSBarry Smith + func - residual evaluation function, for calling sequence see `TSSetRHSFunction()`
95924989b8cSPeter Brune - ctx  - context for residual evaluation
96024989b8cSPeter Brune 
96124989b8cSPeter Brune   Level: advanced
96224989b8cSPeter Brune 
96324989b8cSPeter Brune   Note:
964*346ce620SStefano Zampini   `TSGetRHSFunction()` is normally used, but it calls this function internally because the user context is actually
96524989b8cSPeter Brune   associated with the DM.
96624989b8cSPeter Brune 
967*346ce620SStefano Zampini .seealso: [](ch_ts), `DM`, `TS`
96824989b8cSPeter Brune @*/
969d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSGetRHSFunction(DM dm, TSRHSFunction *func, void **ctx)
970d71ae5a4SJacob Faibussowitsch {
971942e3340SBarry Smith   DMTS tsdm;
97224989b8cSPeter Brune 
97324989b8cSPeter Brune   PetscFunctionBegin;
97424989b8cSPeter Brune   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
9759566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm, &tsdm));
976d74926cbSBarry Smith   if (func) *func = tsdm->ops->rhsfunction;
977800f99ffSJeremy L Thompson   if (ctx) {
978800f99ffSJeremy L Thompson     if (tsdm->rhsfunctionctxcontainer) PetscCall(PetscContainerGetPointer(tsdm->rhsfunctionctxcontainer, ctx));
979800f99ffSJeremy L Thompson     else *ctx = NULL;
980800f99ffSJeremy L Thompson   }
9813ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
98224989b8cSPeter Brune }
98324989b8cSPeter Brune 
98424989b8cSPeter Brune /*@C
985bcf0153eSBarry Smith   DMTSSetIJacobian - set `TS` Jacobian evaluation function
98624989b8cSPeter Brune 
98724989b8cSPeter Brune   Not Collective
98824989b8cSPeter Brune 
9894165533cSJose E. Roman   Input Parameters:
990bcf0153eSBarry Smith + dm   - `DM` to be used with `TS`
991a96d6ef6SBarry Smith . func - Jacobian evaluation routine
99224989b8cSPeter Brune - ctx  - context for residual evaluation
99324989b8cSPeter Brune 
99424989b8cSPeter Brune   Level: advanced
99524989b8cSPeter Brune 
99624989b8cSPeter Brune   Note:
997*346ce620SStefano Zampini   `TSSetIJacobian()` is normally used, but it calls this function internally because the user context is actually
998bcf0153eSBarry Smith   associated with the `DM`.  This makes the interface consistent regardless of whether the user interacts with a `DM` or
999bcf0153eSBarry Smith   not. If `DM` took a more central role at some later date, this could become the primary method of setting the Jacobian.
100024989b8cSPeter Brune 
1001*346ce620SStefano Zampini .seealso: [](ch_ts), `TS`, `DM`, `TSIJacobian`, `DMTSGetIJacobian()`
100224989b8cSPeter Brune @*/
1003d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetIJacobian(DM dm, TSIJacobian func, void *ctx)
1004d71ae5a4SJacob Faibussowitsch {
1005800f99ffSJeremy L Thompson   DMTS tsdm;
100624989b8cSPeter Brune 
100724989b8cSPeter Brune   PetscFunctionBegin;
100824989b8cSPeter Brune   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1009800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm, &tsdm));
1010800f99ffSJeremy L Thompson   if (func) tsdm->ops->ijacobian = func;
1011800f99ffSJeremy L Thompson   if (ctx) {
1012800f99ffSJeremy L Thompson     PetscContainer ctxcontainer;
1013800f99ffSJeremy L Thompson     PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)tsdm), &ctxcontainer));
1014800f99ffSJeremy L Thompson     PetscCall(PetscContainerSetPointer(ctxcontainer, ctx));
1015800f99ffSJeremy L Thompson     PetscCall(PetscObjectCompose((PetscObject)tsdm, "ijacobian ctx", (PetscObject)ctxcontainer));
1016800f99ffSJeremy L Thompson     tsdm->ijacobianctxcontainer = ctxcontainer;
1017800f99ffSJeremy L Thompson     PetscCall(PetscContainerDestroy(&ctxcontainer));
1018800f99ffSJeremy L Thompson   }
10193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1020800f99ffSJeremy L Thompson }
1021800f99ffSJeremy L Thompson 
1022800f99ffSJeremy L Thompson /*@C
10235cb80ecdSBarry Smith   DMTSSetIJacobianContextDestroy - set `TS` Jacobian evaluation context destroy function
1024800f99ffSJeremy L Thompson 
1025800f99ffSJeremy L Thompson   Not Collective
1026800f99ffSJeremy L Thompson 
1027800f99ffSJeremy L Thompson   Input Parameters:
10285cb80ecdSBarry Smith + dm - `DM` to be used with `TS`
10295cb80ecdSBarry Smith - f  - Jacobian evaluation context destroy function
1030800f99ffSJeremy L Thompson 
1031800f99ffSJeremy L Thompson   Level: advanced
1032800f99ffSJeremy L Thompson 
1033800f99ffSJeremy L Thompson   Note:
10345cb80ecdSBarry Smith   `TSSetIJacobianContextDestroy()` is normally used, but it calls this function internally because the user context is actually
10355cb80ecdSBarry Smith   associated with the `DM`.  This makes the interface consistent regardless of whether the user interacts with a `DM` or
10365cb80ecdSBarry Smith   not.
1037800f99ffSJeremy L Thompson 
1038b43aa488SJacob Faibussowitsch   Developer Notes:
10395cb80ecdSBarry Smith   If `DM` took a more central role at some later date, this could become the primary method of setting the Jacobian.
10405cb80ecdSBarry Smith 
10411cc06b55SBarry Smith .seealso: [](ch_ts), `TSSetIJacobianContextDestroy()`, `TSSetI2JacobianContextDestroy()`, `DMTSSetIJacobian()`, `TSSetIJacobian()`
1042800f99ffSJeremy L Thompson @*/
1043d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetIJacobianContextDestroy(DM dm, PetscErrorCode (*f)(void *))
1044d71ae5a4SJacob Faibussowitsch {
1045800f99ffSJeremy L Thompson   DMTS tsdm;
1046800f99ffSJeremy L Thompson 
1047800f99ffSJeremy L Thompson   PetscFunctionBegin;
1048800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1049800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm, &tsdm));
1050800f99ffSJeremy L Thompson   if (tsdm->ijacobianctxcontainer) PetscCall(PetscContainerSetUserDestroy(tsdm->ijacobianctxcontainer, f));
10513ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1052800f99ffSJeremy L Thompson }
1053800f99ffSJeremy L Thompson 
1054d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSUnsetIJacobianContext_Internal(DM dm)
1055d71ae5a4SJacob Faibussowitsch {
1056800f99ffSJeremy L Thompson   DMTS tsdm;
1057800f99ffSJeremy L Thompson 
1058800f99ffSJeremy L Thompson   PetscFunctionBegin;
1059800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1060800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm, &tsdm));
1061800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetIJacobianContext_DMTS(tsdm));
10623ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
106324989b8cSPeter Brune }
106424989b8cSPeter Brune 
106524989b8cSPeter Brune /*@C
1066bcf0153eSBarry Smith   DMTSGetIJacobian - get `TS` Jacobian evaluation function
106724989b8cSPeter Brune 
106824989b8cSPeter Brune   Not Collective
106924989b8cSPeter Brune 
10704165533cSJose E. Roman   Input Parameter:
1071bcf0153eSBarry Smith . dm - `DM` to be used with `TS`
107224989b8cSPeter Brune 
10734165533cSJose E. Roman   Output Parameters:
107420f4b53cSBarry Smith + func - Jacobian evaluation function, for calling sequence see `TSSetIJacobian()`
107524989b8cSPeter Brune - ctx  - context for residual evaluation
107624989b8cSPeter Brune 
107724989b8cSPeter Brune   Level: advanced
107824989b8cSPeter Brune 
107924989b8cSPeter Brune   Note:
1080*346ce620SStefano Zampini   `TSGetIJacobian()` is normally used, but it calls this function internally because the user context is actually
1081bcf0153eSBarry Smith   associated with the `DM`.  This makes the interface consistent regardless of whether the user interacts with a `DM` or
1082bcf0153eSBarry Smith   not. If `DM` took a more central role at some later date, this could become the primary method of setting the Jacobian.
108324989b8cSPeter Brune 
1084*346ce620SStefano Zampini .seealso: [](ch_ts), `DM`, `TS`, `DMTSSetIJacobian()`
108524989b8cSPeter Brune @*/
1086d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSGetIJacobian(DM dm, TSIJacobian *func, void **ctx)
1087d71ae5a4SJacob Faibussowitsch {
1088942e3340SBarry Smith   DMTS tsdm;
108924989b8cSPeter Brune 
109024989b8cSPeter Brune   PetscFunctionBegin;
109124989b8cSPeter Brune   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
10929566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm, &tsdm));
1093d74926cbSBarry Smith   if (func) *func = tsdm->ops->ijacobian;
1094800f99ffSJeremy L Thompson   if (ctx) {
1095800f99ffSJeremy L Thompson     if (tsdm->ijacobianctxcontainer) PetscCall(PetscContainerGetPointer(tsdm->ijacobianctxcontainer, ctx));
1096800f99ffSJeremy L Thompson     else *ctx = NULL;
1097800f99ffSJeremy L Thompson   }
10983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
109924989b8cSPeter Brune }
110024989b8cSPeter Brune 
110124989b8cSPeter Brune /*@C
1102bcf0153eSBarry Smith   DMTSSetRHSJacobian - set `TS` Jacobian evaluation function
110324989b8cSPeter Brune 
110424989b8cSPeter Brune   Not Collective
110524989b8cSPeter Brune 
11064165533cSJose E. Roman   Input Parameters:
1107bcf0153eSBarry Smith + dm   - `DM` to be used with `TS`
1108a96d6ef6SBarry Smith . func - Jacobian evaluation routine
110924989b8cSPeter Brune - ctx  - context for residual evaluation
111024989b8cSPeter Brune 
111124989b8cSPeter Brune   Level: advanced
111224989b8cSPeter Brune 
111324989b8cSPeter Brune   Note:
1114*346ce620SStefano Zampini   `TSSetRHSJacobian()` is normally used, but it calls this function internally because the user context is actually
1115bcf0153eSBarry Smith   associated with the `DM`.  This makes the interface consistent regardless of whether the user interacts with a `DM` or
1116bcf0153eSBarry Smith   not.
111724989b8cSPeter Brune 
1118b43aa488SJacob Faibussowitsch   Developer Notes:
1119bcf0153eSBarry Smith   If `DM` took a more central role at some later date, this could become the primary method of setting the Jacobian.
1120bcf0153eSBarry Smith 
1121*346ce620SStefano Zampini .seealso: [](ch_ts), `TSRHSJacobian`, `DMTSGetRHSJacobian()`
112224989b8cSPeter Brune @*/
1123d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetRHSJacobian(DM dm, TSRHSJacobian func, void *ctx)
1124d71ae5a4SJacob Faibussowitsch {
1125942e3340SBarry Smith   DMTS tsdm;
112624989b8cSPeter Brune 
112724989b8cSPeter Brune   PetscFunctionBegin;
112824989b8cSPeter Brune   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
11299566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm, &tsdm));
1130d74926cbSBarry Smith   if (func) tsdm->ops->rhsjacobian = func;
1131800f99ffSJeremy L Thompson   if (ctx) {
1132800f99ffSJeremy L Thompson     PetscContainer ctxcontainer;
1133800f99ffSJeremy L Thompson     PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)tsdm), &ctxcontainer));
1134800f99ffSJeremy L Thompson     PetscCall(PetscContainerSetPointer(ctxcontainer, ctx));
1135800f99ffSJeremy L Thompson     PetscCall(PetscObjectCompose((PetscObject)tsdm, "rhs jacobian ctx", (PetscObject)ctxcontainer));
1136800f99ffSJeremy L Thompson     tsdm->rhsjacobianctxcontainer = ctxcontainer;
1137800f99ffSJeremy L Thompson     PetscCall(PetscContainerDestroy(&ctxcontainer));
1138800f99ffSJeremy L Thompson   }
11393ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1140800f99ffSJeremy L Thompson }
1141800f99ffSJeremy L Thompson 
1142800f99ffSJeremy L Thompson /*@C
11435cb80ecdSBarry Smith   DMTSSetRHSJacobianContextDestroy - set `TS` Jacobian evaluation context destroy function
1144800f99ffSJeremy L Thompson 
1145800f99ffSJeremy L Thompson   Not Collective
1146800f99ffSJeremy L Thompson 
1147800f99ffSJeremy L Thompson   Input Parameters:
11485cb80ecdSBarry Smith + dm - `DM` to be used with `TS`
11495cb80ecdSBarry Smith - f  - Jacobian evaluation context destroy function
11505cb80ecdSBarry Smith 
11515cb80ecdSBarry Smith   Level: advanced
11525cb80ecdSBarry Smith 
11535cb80ecdSBarry Smith   Note:
11545cb80ecdSBarry Smith   The user usually calls `TSSetRHSJacobianContextDestroy()` which calls this routine
1155800f99ffSJeremy L Thompson 
11561cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSetRHSJacobianContextDestroy()`, `DMTSSetRHSJacobian()`, `TSSetRHSJacobian()`
1157800f99ffSJeremy L Thompson @*/
1158d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetRHSJacobianContextDestroy(DM dm, PetscErrorCode (*f)(void *))
1159d71ae5a4SJacob Faibussowitsch {
1160800f99ffSJeremy L Thompson   DMTS tsdm;
1161800f99ffSJeremy L Thompson 
1162800f99ffSJeremy L Thompson   PetscFunctionBegin;
1163800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1164800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm, &tsdm));
1165800f99ffSJeremy L Thompson   if (tsdm->rhsjacobianctxcontainer) PetscCall(PetscContainerSetUserDestroy(tsdm->rhsjacobianctxcontainer, f));
11663ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1167800f99ffSJeremy L Thompson }
1168800f99ffSJeremy L Thompson 
1169d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSUnsetRHSJacobianContext_Internal(DM dm)
1170d71ae5a4SJacob Faibussowitsch {
1171800f99ffSJeremy L Thompson   DMTS tsdm;
1172800f99ffSJeremy L Thompson 
1173800f99ffSJeremy L Thompson   PetscFunctionBegin;
1174800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1175800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm, &tsdm));
1176800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetRHSJacobianContext_DMTS(tsdm));
11773ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
117824989b8cSPeter Brune }
117924989b8cSPeter Brune 
118024989b8cSPeter Brune /*@C
1181bcf0153eSBarry Smith   DMTSGetRHSJacobian - get `TS` Jacobian evaluation function
118224989b8cSPeter Brune 
118324989b8cSPeter Brune   Not Collective
118424989b8cSPeter Brune 
11854165533cSJose E. Roman   Input Parameter:
1186bcf0153eSBarry Smith . dm - `DM` to be used with `TS`
118724989b8cSPeter Brune 
11884165533cSJose E. Roman   Output Parameters:
118920f4b53cSBarry Smith + func - Jacobian evaluation function, for calling sequence see `TSSetRHSJacobian()`
119024989b8cSPeter Brune - ctx  - context for residual evaluation
119124989b8cSPeter Brune 
119224989b8cSPeter Brune   Level: advanced
119324989b8cSPeter Brune 
119424989b8cSPeter Brune   Note:
1195*346ce620SStefano Zampini   `TSGetRHSJacobian()` is normally used, but it calls this function internally because the user context is actually
1196bcf0153eSBarry Smith   associated with the `DM`.  This makes the interface consistent regardless of whether the user interacts with a `DM` or
1197bcf0153eSBarry Smith   not. If `DM` took a more central role at some later date, this could become the primary method of setting the Jacobian.
119824989b8cSPeter Brune 
1199*346ce620SStefano Zampini .seealso: [](ch_ts), `DM`, `TS`, `DMTSSetRHSJacobian()`
120024989b8cSPeter Brune @*/
1201d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSGetRHSJacobian(DM dm, TSRHSJacobian *func, void **ctx)
1202d71ae5a4SJacob Faibussowitsch {
1203942e3340SBarry Smith   DMTS tsdm;
120424989b8cSPeter Brune 
120524989b8cSPeter Brune   PetscFunctionBegin;
120624989b8cSPeter Brune   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
12079566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm, &tsdm));
1208d74926cbSBarry Smith   if (func) *func = tsdm->ops->rhsjacobian;
1209800f99ffSJeremy L Thompson   if (ctx) {
1210800f99ffSJeremy L Thompson     if (tsdm->rhsjacobianctxcontainer) PetscCall(PetscContainerGetPointer(tsdm->rhsjacobianctxcontainer, ctx));
1211800f99ffSJeremy L Thompson     else *ctx = NULL;
1212800f99ffSJeremy L Thompson   }
12133ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
121424989b8cSPeter Brune }
1215ad6bc421SBarry Smith 
1216ad6bc421SBarry Smith /*@C
1217ad6bc421SBarry Smith   DMTSSetIFunctionSerialize - sets functions used to view and load a IFunction context
1218ad6bc421SBarry Smith 
1219ad6bc421SBarry Smith   Not Collective
1220ad6bc421SBarry Smith 
12214165533cSJose E. Roman   Input Parameters:
1222bcf0153eSBarry Smith + dm   - `DM` to be used with `TS`
1223ad6bc421SBarry Smith . view - viewer function
1224ad6bc421SBarry Smith - load - loading function
1225ad6bc421SBarry Smith 
1226ad6bc421SBarry Smith   Level: advanced
1227ad6bc421SBarry Smith 
1228*346ce620SStefano Zampini .seealso: [](ch_ts), `DM`, `TS`
1229ad6bc421SBarry Smith @*/
1230d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetIFunctionSerialize(DM dm, PetscErrorCode (*view)(void *, PetscViewer), PetscErrorCode (*load)(void **, PetscViewer))
1231d71ae5a4SJacob Faibussowitsch {
1232ad6bc421SBarry Smith   DMTS tsdm;
1233ad6bc421SBarry Smith 
1234ad6bc421SBarry Smith   PetscFunctionBegin;
1235ad6bc421SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
12369566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm, &tsdm));
1237ad6bc421SBarry Smith   tsdm->ops->ifunctionview = view;
1238ad6bc421SBarry Smith   tsdm->ops->ifunctionload = load;
12393ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1240ad6bc421SBarry Smith }
1241ad6bc421SBarry Smith 
1242ad6bc421SBarry Smith /*@C
1243ad6bc421SBarry Smith   DMTSSetIJacobianSerialize - sets functions used to view and load a IJacobian context
1244ad6bc421SBarry Smith 
1245ad6bc421SBarry Smith   Not Collective
1246ad6bc421SBarry Smith 
12474165533cSJose E. Roman   Input Parameters:
1248bcf0153eSBarry Smith + dm   - `DM` to be used with `TS`
1249ad6bc421SBarry Smith . view - viewer function
1250ad6bc421SBarry Smith - load - loading function
1251ad6bc421SBarry Smith 
1252ad6bc421SBarry Smith   Level: advanced
1253ad6bc421SBarry Smith 
1254*346ce620SStefano Zampini .seealso: [](ch_ts), `DM`, `TS`
1255ad6bc421SBarry Smith @*/
1256d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetIJacobianSerialize(DM dm, PetscErrorCode (*view)(void *, PetscViewer), PetscErrorCode (*load)(void **, PetscViewer))
1257d71ae5a4SJacob Faibussowitsch {
1258ad6bc421SBarry Smith   DMTS tsdm;
1259ad6bc421SBarry Smith 
1260ad6bc421SBarry Smith   PetscFunctionBegin;
1261ad6bc421SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
12629566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm, &tsdm));
1263ad6bc421SBarry Smith   tsdm->ops->ijacobianview = view;
1264ad6bc421SBarry Smith   tsdm->ops->ijacobianload = load;
12653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1266ad6bc421SBarry Smith }
1267