xref: /petsc/src/ts/utils/dmts.c (revision bcf0153e883cfed9568ef4557dcc209048fb58f7)
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;
9800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
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;
17800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
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;
25800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
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;
33800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
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;
41800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
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;
49800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
50800f99ffSJeremy L Thompson }
51800f99ffSJeremy L Thompson 
52d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMTSDestroy(DMTS *kdm)
53d71ae5a4SJacob Faibussowitsch {
54d74926cbSBarry Smith   PetscFunctionBegin;
55d74926cbSBarry Smith   if (!*kdm) PetscFunctionReturn(0);
56d74926cbSBarry Smith   PetscValidHeaderSpecific((*kdm), DMTS_CLASSID, 1);
579371c9d4SSatish Balay   if (--((PetscObject)(*kdm))->refct > 0) {
589371c9d4SSatish Balay     *kdm = NULL;
599371c9d4SSatish Balay     PetscFunctionReturn(0);
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));
69d74926cbSBarry Smith   PetscFunctionReturn(0);
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   }
932d53ad75SBarry Smith   PetscFunctionReturn(0);
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   }
1572d53ad75SBarry Smith   PetscFunctionReturn(0);
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));
165d74926cbSBarry Smith   PetscFunctionReturn(0);
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));
17524989b8cSPeter Brune   PetscFunctionReturn(0);
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;
18324989b8cSPeter Brune   PetscFunctionReturn(0);
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));
190258e1594SPeter Brune   PetscFunctionReturn(0);
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;
198258e1594SPeter Brune   PetscFunctionReturn(0);
199258e1594SPeter Brune }
200258e1594SPeter Brune 
201d74926cbSBarry Smith /*@C
202*bcf0153eSBarry Smith    DMTSCopy - copies the information in a `DMTS` to another `DMTS`
203d74926cbSBarry Smith 
204d74926cbSBarry Smith    Not Collective
205d74926cbSBarry Smith 
2064165533cSJose E. Roman    Input Parameters:
207*bcf0153eSBarry Smith +  kdm - Original `DMTS`
208*bcf0153eSBarry Smith -  nkdm - `DMTS` to receive the data, should have been created with `DMTSCreate()`
209d74926cbSBarry Smith 
210d74926cbSBarry Smith    Level: developer
211d74926cbSBarry Smith 
212*bcf0153eSBarry Smith .seealso: [](chapter_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);
25324989b8cSPeter Brune   PetscFunctionReturn(0);
25424989b8cSPeter Brune }
25524989b8cSPeter Brune 
25624989b8cSPeter Brune /*@C
257*bcf0153eSBarry Smith    DMGetDMTS - get read-only private `DMTS` context from a `DM`
25824989b8cSPeter Brune 
25924989b8cSPeter Brune    Not Collective
26024989b8cSPeter Brune 
2614165533cSJose E. Roman    Input Parameter:
262*bcf0153eSBarry Smith .  dm - `DM` to be used with `TS`
26324989b8cSPeter Brune 
2644165533cSJose E. Roman    Output Parameter:
265*bcf0153eSBarry Smith .  tsdm - private `DMTS` context
26624989b8cSPeter Brune 
26724989b8cSPeter Brune    Level: developer
26824989b8cSPeter Brune 
26924989b8cSPeter Brune    Notes:
270*bcf0153eSBarry Smith    Use `DMGetDMTSWrite()` if write access is needed. The `DMTSSetXXX()` API should be used wherever possible.
27124989b8cSPeter Brune 
272*bcf0153eSBarry Smith .seealso: [](chapter_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   }
28724989b8cSPeter Brune   PetscFunctionReturn(0);
28824989b8cSPeter Brune }
28924989b8cSPeter Brune 
29024989b8cSPeter Brune /*@C
291*bcf0153eSBarry 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:
296*bcf0153eSBarry Smith .  dm - `DM` to be used with `TS`
29724989b8cSPeter Brune 
2984165533cSJose E. Roman    Output Parameter:
299*bcf0153eSBarry Smith .  tsdm - private `DMTS` context
30024989b8cSPeter Brune 
30124989b8cSPeter Brune    Level: developer
30224989b8cSPeter Brune 
303*bcf0153eSBarry Smith .seealso: [](chapter_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;
32324989b8cSPeter Brune   PetscFunctionReturn(0);
32424989b8cSPeter Brune }
32524989b8cSPeter Brune 
32624989b8cSPeter Brune /*@C
327*bcf0153eSBarry Smith    DMCopyDMTS - copies a `DM` context to a new `DM`
32824989b8cSPeter Brune 
32924989b8cSPeter Brune    Logically Collective
33024989b8cSPeter Brune 
3314165533cSJose E. Roman    Input Parameters:
332*bcf0153eSBarry Smith +  dmsrc - `DM` to obtain context from
333*bcf0153eSBarry 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 
340*bcf0153eSBarry Smith .seealso: [](chapter_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));
35224989b8cSPeter Brune   PetscFunctionReturn(0);
35324989b8cSPeter Brune }
35424989b8cSPeter Brune 
35524989b8cSPeter Brune /*@C
356*bcf0153eSBarry Smith    DMTSSetIFunction - set `TS` implicit function evaluation function
35724989b8cSPeter Brune 
35824989b8cSPeter Brune    Not Collective
35924989b8cSPeter Brune 
3604165533cSJose E. Roman    Input Parameters:
361*bcf0153eSBarry 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 
365a96d6ef6SBarry Smith    Calling sequence of func:
366a96d6ef6SBarry Smith $     PetscErrorCode func(TS ts,PetscReal t,Vec u,Vec u_t,Vec F,ctx);
367a96d6ef6SBarry Smith 
368a96d6ef6SBarry Smith +  t   - time at step/stage being solved
369a96d6ef6SBarry Smith .  u   - state vector
370a96d6ef6SBarry Smith .  u_t - time derivative of state vector
371a96d6ef6SBarry Smith .  F   - function vector
372a96d6ef6SBarry Smith -  ctx - [optional] user-defined context for matrix evaluation routine
373a96d6ef6SBarry Smith 
37424989b8cSPeter Brune    Level: advanced
37524989b8cSPeter Brune 
37624989b8cSPeter Brune    Note:
377*bcf0153eSBarry Smith    `TSSetFunction()` is normally used, but it calls this function internally because the user context is actually
378*bcf0153eSBarry Smith    associated with the `DM`.  This makes the interface consistent regardless of whether the user interacts with a `DM` or
37924989b8cSPeter Brune    not. If DM took a more central role at some later date, this could become the primary method of setting the residual.
38024989b8cSPeter Brune 
381*bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `DM`, `DMTSSetContext()`, `TSSetIFunction()`, `DMTSSetJacobian()`
38224989b8cSPeter Brune @*/
383d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetIFunction(DM dm, TSIFunction func, void *ctx)
384d71ae5a4SJacob Faibussowitsch {
385942e3340SBarry Smith   DMTS tsdm;
38624989b8cSPeter Brune 
38724989b8cSPeter Brune   PetscFunctionBegin;
38824989b8cSPeter Brune   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3899566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm, &tsdm));
390d74926cbSBarry Smith   if (func) tsdm->ops->ifunction = func;
391800f99ffSJeremy L Thompson   if (ctx) {
392800f99ffSJeremy L Thompson     PetscContainer ctxcontainer;
393800f99ffSJeremy L Thompson     PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)tsdm), &ctxcontainer));
394800f99ffSJeremy L Thompson     PetscCall(PetscContainerSetPointer(ctxcontainer, ctx));
395800f99ffSJeremy L Thompson     PetscCall(PetscObjectCompose((PetscObject)tsdm, "ifunction ctx", (PetscObject)ctxcontainer));
396800f99ffSJeremy L Thompson     tsdm->ifunctionctxcontainer = ctxcontainer;
397800f99ffSJeremy L Thompson     PetscCall(PetscContainerDestroy(&ctxcontainer));
398800f99ffSJeremy L Thompson   }
399800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
400800f99ffSJeremy L Thompson }
401800f99ffSJeremy L Thompson 
402800f99ffSJeremy L Thompson /*@C
4035cb80ecdSBarry Smith    DMTSSetIFunctionContextDestroy - set `TS` implicit evaluation context destroy function
404800f99ffSJeremy L Thompson 
405800f99ffSJeremy L Thompson    Not Collective
406800f99ffSJeremy L Thompson 
407800f99ffSJeremy L Thompson    Input Parameters:
4085cb80ecdSBarry Smith +  dm - `DM` to be used with `TS`
4095cb80ecdSBarry Smith -  f - implicit evaluation context destroy function
410800f99ffSJeremy L Thompson 
411800f99ffSJeremy L Thompson    Level: advanced
412800f99ffSJeremy L Thompson 
413*bcf0153eSBarry Smith .seealso: [](chapter_ts), `DM`, `TS`, `DMTSSetIFunction()`, `TSSetIFunction()`
414800f99ffSJeremy L Thompson @*/
415d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetIFunctionContextDestroy(DM dm, PetscErrorCode (*f)(void *))
416d71ae5a4SJacob Faibussowitsch {
417800f99ffSJeremy L Thompson   DMTS tsdm;
418800f99ffSJeremy L Thompson 
419800f99ffSJeremy L Thompson   PetscFunctionBegin;
420800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
421800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm, &tsdm));
422800f99ffSJeremy L Thompson   if (tsdm->ifunctionctxcontainer) PetscCall(PetscContainerSetUserDestroy(tsdm->ifunctionctxcontainer, f));
423800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
424800f99ffSJeremy L Thompson }
425800f99ffSJeremy L Thompson 
426d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSUnsetIFunctionContext_Internal(DM dm)
427d71ae5a4SJacob Faibussowitsch {
428800f99ffSJeremy L Thompson   DMTS tsdm;
429800f99ffSJeremy L Thompson 
430800f99ffSJeremy L Thompson   PetscFunctionBegin;
431800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
432800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm, &tsdm));
433800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetIFunctionContext_DMTS(tsdm));
43424989b8cSPeter Brune   PetscFunctionReturn(0);
43524989b8cSPeter Brune }
43624989b8cSPeter Brune 
43724989b8cSPeter Brune /*@C
438*bcf0153eSBarry Smith    DMTSGetIFunction - get `TS` implicit residual evaluation function
43924989b8cSPeter Brune 
44024989b8cSPeter Brune    Not Collective
44124989b8cSPeter Brune 
4424165533cSJose E. Roman    Input Parameter:
443*bcf0153eSBarry Smith .  dm - `DM` to be used with `TS`
44424989b8cSPeter Brune 
4454165533cSJose E. Roman    Output Parameters:
446*bcf0153eSBarry Smith +  func - function evaluation function, see `TSSetIFunction()` for calling sequence
44724989b8cSPeter Brune -  ctx - context for residual evaluation
44824989b8cSPeter Brune 
44924989b8cSPeter Brune    Level: advanced
45024989b8cSPeter Brune 
45124989b8cSPeter Brune    Note:
452*bcf0153eSBarry Smith    `TSGetFunction()` is normally used, but it calls this function internally because the user context is actually
453*bcf0153eSBarry Smith    associated with the `DM`.
45424989b8cSPeter Brune 
455*bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `DM`, `DMTSSetContext()`, `DMTSSetFunction()`, `TSSetFunction()`
45624989b8cSPeter Brune @*/
457d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSGetIFunction(DM dm, TSIFunction *func, void **ctx)
458d71ae5a4SJacob Faibussowitsch {
459942e3340SBarry Smith   DMTS tsdm;
46024989b8cSPeter Brune 
46124989b8cSPeter Brune   PetscFunctionBegin;
46224989b8cSPeter Brune   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4639566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm, &tsdm));
464d74926cbSBarry Smith   if (func) *func = tsdm->ops->ifunction;
465800f99ffSJeremy L Thompson   if (ctx) {
466800f99ffSJeremy L Thompson     if (tsdm->ifunctionctxcontainer) PetscCall(PetscContainerGetPointer(tsdm->ifunctionctxcontainer, ctx));
467800f99ffSJeremy L Thompson     else *ctx = NULL;
468800f99ffSJeremy L Thompson   }
46924989b8cSPeter Brune   PetscFunctionReturn(0);
47024989b8cSPeter Brune }
47124989b8cSPeter Brune 
472efe9872eSLisandro Dalcin /*@C
473*bcf0153eSBarry Smith    DMTSSetI2Function - set `TS` implicit function evaluation function for 2nd order systems
474efe9872eSLisandro Dalcin 
475efe9872eSLisandro Dalcin    Not Collective
476efe9872eSLisandro Dalcin 
4774165533cSJose E. Roman    Input Parameters:
478*bcf0153eSBarry Smith +  dm - `DM` to be used with `TS`
479a96d6ef6SBarry Smith .  fun - function evaluation routine
480efe9872eSLisandro Dalcin -  ctx - context for residual evaluation
481efe9872eSLisandro Dalcin 
482a96d6ef6SBarry Smith    Calling sequence of fun:
483a96d6ef6SBarry Smith $     PetscErrorCode fun(TS ts,PetscReal t,Vec U,Vec U_t,Vec U_tt,Vec F,ctx);
484a96d6ef6SBarry Smith 
485a96d6ef6SBarry Smith +  t    - time at step/stage being solved
486a96d6ef6SBarry Smith .  U    - state vector
487a96d6ef6SBarry Smith .  U_t  - time derivative of state vector
488a96d6ef6SBarry Smith .  U_tt - second time derivative of state vector
489a96d6ef6SBarry Smith .  F    - function vector
490a96d6ef6SBarry Smith -  ctx  - [optional] user-defined context for matrix evaluation routine (may be NULL)
491a96d6ef6SBarry Smith 
492efe9872eSLisandro Dalcin    Level: advanced
493efe9872eSLisandro Dalcin 
494efe9872eSLisandro Dalcin    Note:
495*bcf0153eSBarry Smith    `TSSetI2Function()` is normally used, but it calls this function internally because the user context is actually
496*bcf0153eSBarry Smith    associated with the `DM`.
497efe9872eSLisandro Dalcin 
498*bcf0153eSBarry Smith .seealso: [](chapter_ts), `DM`, `TS`, `TSSetI2Function()`
499efe9872eSLisandro Dalcin @*/
500d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetI2Function(DM dm, TSI2Function fun, void *ctx)
501d71ae5a4SJacob Faibussowitsch {
502efe9872eSLisandro Dalcin   DMTS tsdm;
503efe9872eSLisandro Dalcin 
504efe9872eSLisandro Dalcin   PetscFunctionBegin;
505efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5069566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm, &tsdm));
507efe9872eSLisandro Dalcin   if (fun) tsdm->ops->i2function = fun;
508800f99ffSJeremy L Thompson   if (ctx) {
509800f99ffSJeremy L Thompson     PetscContainer ctxcontainer;
510800f99ffSJeremy L Thompson     PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)tsdm), &ctxcontainer));
511800f99ffSJeremy L Thompson     PetscCall(PetscContainerSetPointer(ctxcontainer, ctx));
512800f99ffSJeremy L Thompson     PetscCall(PetscObjectCompose((PetscObject)tsdm, "i2function ctx", (PetscObject)ctxcontainer));
513800f99ffSJeremy L Thompson     tsdm->i2functionctxcontainer = ctxcontainer;
514800f99ffSJeremy L Thompson     PetscCall(PetscContainerDestroy(&ctxcontainer));
515800f99ffSJeremy L Thompson   }
516800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
517800f99ffSJeremy L Thompson }
518800f99ffSJeremy L Thompson 
519800f99ffSJeremy L Thompson /*@C
5205cb80ecdSBarry Smith    DMTSSetI2FunctionContextDestroy - set `TS` implicit evaluation for 2nd order systems context destroy
521800f99ffSJeremy L Thompson 
522800f99ffSJeremy L Thompson    Not Collective
523800f99ffSJeremy L Thompson 
524800f99ffSJeremy L Thompson    Input Parameters:
5255cb80ecdSBarry Smith +  dm - `DM` to be used with `TS`
5265cb80ecdSBarry Smith -  f - implicit evaluation context destroy function
527800f99ffSJeremy L Thompson 
528800f99ffSJeremy L Thompson    Level: advanced
529800f99ffSJeremy L Thompson 
530800f99ffSJeremy L Thompson    Note:
5315cb80ecdSBarry Smith    `TSSetI2FunctionContextDestroy()` is normally used, but it calls this function internally because the user context is actually
5325cb80ecdSBarry Smith    associated with the `DM`.
533800f99ffSJeremy L Thompson 
534*bcf0153eSBarry Smith .seealso: [](chapter_ts), `TSSetI2FunctionContextDestroy()`, `DMTSSetI2Function()`, `TSSetI2Function()`
535800f99ffSJeremy L Thompson @*/
536d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetI2FunctionContextDestroy(DM dm, PetscErrorCode (*f)(void *))
537d71ae5a4SJacob Faibussowitsch {
538800f99ffSJeremy L Thompson   DMTS tsdm;
539800f99ffSJeremy L Thompson 
540800f99ffSJeremy L Thompson   PetscFunctionBegin;
541800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
542800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm, &tsdm));
543800f99ffSJeremy L Thompson   if (tsdm->i2functionctxcontainer) PetscCall(PetscContainerSetUserDestroy(tsdm->i2functionctxcontainer, f));
544800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
545800f99ffSJeremy L Thompson }
546800f99ffSJeremy L Thompson 
547d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSUnsetI2FunctionContext_Internal(DM dm)
548d71ae5a4SJacob Faibussowitsch {
549800f99ffSJeremy L Thompson   DMTS tsdm;
550800f99ffSJeremy L Thompson 
551800f99ffSJeremy L Thompson   PetscFunctionBegin;
552800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
553800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm, &tsdm));
554800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetI2FunctionContext_DMTS(tsdm));
555efe9872eSLisandro Dalcin   PetscFunctionReturn(0);
556efe9872eSLisandro Dalcin }
557efe9872eSLisandro Dalcin 
558efe9872eSLisandro Dalcin /*@C
559*bcf0153eSBarry Smith    DMTSGetI2Function - get `TS` implicit residual evaluation function for 2nd order systems
560efe9872eSLisandro Dalcin 
561efe9872eSLisandro Dalcin    Not Collective
562efe9872eSLisandro Dalcin 
5634165533cSJose E. Roman    Input Parameter:
564*bcf0153eSBarry Smith .  dm - `DM` to be used with `TS`
565efe9872eSLisandro Dalcin 
5664165533cSJose E. Roman    Output Parameters:
567*bcf0153eSBarry Smith +  fun - function evaluation function, see `TSSetI2Function()` for calling sequence
568efe9872eSLisandro Dalcin -  ctx - context for residual evaluation
569efe9872eSLisandro Dalcin 
570efe9872eSLisandro Dalcin    Level: advanced
571efe9872eSLisandro Dalcin 
572efe9872eSLisandro Dalcin    Note:
573*bcf0153eSBarry Smith    `TSGetI2Function()` is normally used, but it calls this function internally because the user context is actually
574*bcf0153eSBarry Smith    associated with the `DM`.
575efe9872eSLisandro Dalcin 
576*bcf0153eSBarry Smith .seealso: [](chapter_ts), `DM`, `TS`, `DMTSSetI2Function()`, `TSGetI2Function()`
577efe9872eSLisandro Dalcin @*/
578d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSGetI2Function(DM dm, TSI2Function *fun, void **ctx)
579d71ae5a4SJacob Faibussowitsch {
580efe9872eSLisandro Dalcin   DMTS tsdm;
581efe9872eSLisandro Dalcin 
582efe9872eSLisandro Dalcin   PetscFunctionBegin;
583efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5849566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm, &tsdm));
585efe9872eSLisandro Dalcin   if (fun) *fun = tsdm->ops->i2function;
586800f99ffSJeremy L Thompson   if (ctx) {
587800f99ffSJeremy L Thompson     if (tsdm->i2functionctxcontainer) PetscCall(PetscContainerGetPointer(tsdm->i2functionctxcontainer, ctx));
588800f99ffSJeremy L Thompson     else *ctx = NULL;
589800f99ffSJeremy L Thompson   }
590efe9872eSLisandro Dalcin   PetscFunctionReturn(0);
591efe9872eSLisandro Dalcin }
592efe9872eSLisandro Dalcin 
593efe9872eSLisandro Dalcin /*@C
594*bcf0153eSBarry Smith    DMTSSetI2Jacobian - set `TS` implicit Jacobian evaluation function for 2nd order systems
595efe9872eSLisandro Dalcin 
596efe9872eSLisandro Dalcin    Not Collective
597efe9872eSLisandro Dalcin 
5984165533cSJose E. Roman    Input Parameters:
599*bcf0153eSBarry Smith +  dm - `DM` to be used with `TS`
600a96d6ef6SBarry Smith .  fun - Jacobian evaluation routine
601efe9872eSLisandro Dalcin -  ctx - context for Jacobian evaluation
602efe9872eSLisandro Dalcin 
603a96d6ef6SBarry Smith    Calling sequence of jac:
604a96d6ef6SBarry 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);
605a96d6ef6SBarry Smith 
606a96d6ef6SBarry Smith +  t    - time at step/stage being solved
607a96d6ef6SBarry Smith .  U    - state vector
608a96d6ef6SBarry Smith .  U_t  - time derivative of state vector
609a96d6ef6SBarry Smith .  U_tt - second time derivative of state vector
610a96d6ef6SBarry Smith .  v    - shift for U_t
611a96d6ef6SBarry Smith .  a    - shift for U_tt
612a96d6ef6SBarry 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
613a96d6ef6SBarry Smith .  P    - preconditioning matrix for J, may be same as J
614a96d6ef6SBarry Smith -  ctx  - [optional] user-defined context for matrix evaluation routine
615a96d6ef6SBarry Smith 
616efe9872eSLisandro Dalcin    Level: advanced
617efe9872eSLisandro Dalcin 
618efe9872eSLisandro Dalcin    Note:
619*bcf0153eSBarry Smith    `TSSetI2Jacobian()` is normally used, but it calls this function internally because the user context is actually
620*bcf0153eSBarry Smith    associated with the `DM`.
621efe9872eSLisandro Dalcin 
622*bcf0153eSBarry Smith .seealso: [](chapter_ts), `DM`, `TS`, `TSSetI2Jacobian()`
623efe9872eSLisandro Dalcin @*/
624d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetI2Jacobian(DM dm, TSI2Jacobian jac, void *ctx)
625d71ae5a4SJacob Faibussowitsch {
626efe9872eSLisandro Dalcin   DMTS tsdm;
627efe9872eSLisandro Dalcin 
628efe9872eSLisandro Dalcin   PetscFunctionBegin;
629efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6309566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm, &tsdm));
631efe9872eSLisandro Dalcin   if (jac) tsdm->ops->i2jacobian = jac;
632800f99ffSJeremy L Thompson   if (ctx) {
633800f99ffSJeremy L Thompson     PetscContainer ctxcontainer;
634800f99ffSJeremy L Thompson     PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)tsdm), &ctxcontainer));
635800f99ffSJeremy L Thompson     PetscCall(PetscContainerSetPointer(ctxcontainer, ctx));
636800f99ffSJeremy L Thompson     PetscCall(PetscObjectCompose((PetscObject)tsdm, "i2jacobian ctx", (PetscObject)ctxcontainer));
637800f99ffSJeremy L Thompson     tsdm->i2jacobianctxcontainer = ctxcontainer;
638800f99ffSJeremy L Thompson     PetscCall(PetscContainerDestroy(&ctxcontainer));
639800f99ffSJeremy L Thompson   }
640800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
641800f99ffSJeremy L Thompson }
642800f99ffSJeremy L Thompson 
643800f99ffSJeremy L Thompson /*@C
6445cb80ecdSBarry Smith    DMTSSetI2JacobianContextDestroy - set `TS` implicit Jacobian evaluation for 2nd order systems context destroy function
645800f99ffSJeremy L Thompson 
646800f99ffSJeremy L Thompson    Not Collective
647800f99ffSJeremy L Thompson 
648800f99ffSJeremy L Thompson    Input Parameters:
6495cb80ecdSBarry Smith +  dm - `DM` to be used with `TS`
6505cb80ecdSBarry Smith -  f - implicit Jacobian evaluation context destroy function
651800f99ffSJeremy L Thompson 
65287497f52SBarry Smith    Level: advanced
65387497f52SBarry Smith 
654*bcf0153eSBarry Smith .seealso: [](chapter_ts), `DM`, `TS`, `TSSetI2JacobianContextDestroy()`, `DMTSSetI2Jacobian()`, `TSSetI2Jacobian()`
655800f99ffSJeremy L Thompson @*/
656d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetI2JacobianContextDestroy(DM dm, PetscErrorCode (*f)(void *))
657d71ae5a4SJacob Faibussowitsch {
658800f99ffSJeremy L Thompson   DMTS tsdm;
659800f99ffSJeremy L Thompson 
660800f99ffSJeremy L Thompson   PetscFunctionBegin;
661800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
662800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm, &tsdm));
663800f99ffSJeremy L Thompson   if (tsdm->i2jacobianctxcontainer) PetscCall(PetscContainerSetUserDestroy(tsdm->i2jacobianctxcontainer, f));
664800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
665800f99ffSJeremy L Thompson }
666800f99ffSJeremy L Thompson 
667d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSUnsetI2JacobianContext_Internal(DM dm)
668d71ae5a4SJacob Faibussowitsch {
669800f99ffSJeremy L Thompson   DMTS tsdm;
670800f99ffSJeremy L Thompson 
671800f99ffSJeremy L Thompson   PetscFunctionBegin;
672800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
673800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm, &tsdm));
674800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetI2JacobianContext_DMTS(tsdm));
675efe9872eSLisandro Dalcin   PetscFunctionReturn(0);
676efe9872eSLisandro Dalcin }
677efe9872eSLisandro Dalcin 
678efe9872eSLisandro Dalcin /*@C
679*bcf0153eSBarry Smith    DMTSGetI2Jacobian - get `TS` implicit Jacobian evaluation function for 2nd order systems
680efe9872eSLisandro Dalcin 
681efe9872eSLisandro Dalcin    Not Collective
682efe9872eSLisandro Dalcin 
6834165533cSJose E. Roman    Input Parameter:
684*bcf0153eSBarry Smith .  dm - `DM` to be used with `TS`
685efe9872eSLisandro Dalcin 
6864165533cSJose E. Roman    Output Parameters:
687*bcf0153eSBarry Smith +  jac - Jacobian evaluation function, see `TSSetI2Jacobian()` for calling sequence
688efe9872eSLisandro Dalcin -  ctx - context for Jacobian evaluation
689efe9872eSLisandro Dalcin 
690efe9872eSLisandro Dalcin    Level: advanced
691efe9872eSLisandro Dalcin 
692efe9872eSLisandro Dalcin    Note:
693*bcf0153eSBarry Smith    `TSGetI2Jacobian()` is normally used, but it calls this function internally because the user context is actually
694*bcf0153eSBarry Smith    associated with the `DM`.
695efe9872eSLisandro Dalcin 
696*bcf0153eSBarry Smith .seealso: [](chapter_ts), `DM`, `TS`, `DMTSSetI2Jacobian()`, `TSGetI2Jacobian()`
697efe9872eSLisandro Dalcin @*/
698d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSGetI2Jacobian(DM dm, TSI2Jacobian *jac, void **ctx)
699d71ae5a4SJacob Faibussowitsch {
700efe9872eSLisandro Dalcin   DMTS tsdm;
701efe9872eSLisandro Dalcin 
702efe9872eSLisandro Dalcin   PetscFunctionBegin;
703efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7049566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm, &tsdm));
705efe9872eSLisandro Dalcin   if (jac) *jac = tsdm->ops->i2jacobian;
706800f99ffSJeremy L Thompson   if (ctx) {
707800f99ffSJeremy L Thompson     if (tsdm->i2jacobianctxcontainer) PetscCall(PetscContainerGetPointer(tsdm->i2jacobianctxcontainer, ctx));
708800f99ffSJeremy L Thompson     else *ctx = NULL;
709800f99ffSJeremy L Thompson   }
710efe9872eSLisandro Dalcin   PetscFunctionReturn(0);
711efe9872eSLisandro Dalcin }
71224989b8cSPeter Brune 
71324989b8cSPeter Brune /*@C
714*bcf0153eSBarry Smith    DMTSSetRHSFunction - set `TS` explicit residual evaluation function
71524989b8cSPeter Brune 
71624989b8cSPeter Brune    Not Collective
71724989b8cSPeter Brune 
7184165533cSJose E. Roman    Input Parameters:
719*bcf0153eSBarry Smith +  dm - `DM` to be used with `TS`
720a96d6ef6SBarry Smith .  func - RHS function evaluation routine
72124989b8cSPeter Brune -  ctx - context for residual evaluation
72224989b8cSPeter Brune 
723a96d6ef6SBarry Smith     Calling sequence of func:
724a96d6ef6SBarry Smith $     PetscErrorCode func(TS ts,PetscReal t,Vec u,Vec F,void *ctx);
725a96d6ef6SBarry Smith 
726a96d6ef6SBarry Smith +   ts - timestep context
727a96d6ef6SBarry Smith .   t - current timestep
728a96d6ef6SBarry Smith .   u - input vector
729a96d6ef6SBarry Smith .   F - function vector
730a96d6ef6SBarry Smith -   ctx - [optional] user-defined function context
731a96d6ef6SBarry Smith 
73224989b8cSPeter Brune    Level: advanced
73324989b8cSPeter Brune 
73424989b8cSPeter Brune    Note:
735*bcf0153eSBarry Smith    `TSSetRHSFunction()` is normally used, but it calls this function internally because the user context is actually
736*bcf0153eSBarry Smith    associated with the `DM`.  This makes the interface consistent regardless of whether the user interacts with a `DM` or
737*bcf0153eSBarry Smith    not. If `DM` took a more central role at some later date, this could become the primary method of setting the residual.
73824989b8cSPeter Brune 
739*bcf0153eSBarry Smith .seealso: [](chapter_ts), `DM`, `TS`, `DMTSSetContext()`, `TSSetRHSFunction()`, `DMTSSetJacobian()`
74024989b8cSPeter Brune @*/
741d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetRHSFunction(DM dm, TSRHSFunction func, void *ctx)
742d71ae5a4SJacob Faibussowitsch {
743942e3340SBarry Smith   DMTS tsdm;
74424989b8cSPeter Brune 
74524989b8cSPeter Brune   PetscFunctionBegin;
74624989b8cSPeter Brune   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7479566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm, &tsdm));
748d74926cbSBarry Smith   if (func) tsdm->ops->rhsfunction = func;
749800f99ffSJeremy L Thompson   if (ctx) {
750800f99ffSJeremy L Thompson     PetscContainer ctxcontainer;
751800f99ffSJeremy L Thompson     PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)tsdm), &ctxcontainer));
752800f99ffSJeremy L Thompson     PetscCall(PetscContainerSetPointer(ctxcontainer, ctx));
753800f99ffSJeremy L Thompson     PetscCall(PetscObjectCompose((PetscObject)tsdm, "rhs function ctx", (PetscObject)ctxcontainer));
754800f99ffSJeremy L Thompson     tsdm->rhsfunctionctxcontainer = ctxcontainer;
755800f99ffSJeremy L Thompson     PetscCall(PetscContainerDestroy(&ctxcontainer));
756800f99ffSJeremy L Thompson   }
757800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
758800f99ffSJeremy L Thompson }
759800f99ffSJeremy L Thompson 
760800f99ffSJeremy L Thompson /*@C
7615cb80ecdSBarry Smith    DMTSSetRHSFunctionContextDestroy - set `TS` explicit residual evaluation context destroy function
762800f99ffSJeremy L Thompson 
763800f99ffSJeremy L Thompson    Not Collective
764800f99ffSJeremy L Thompson 
765800f99ffSJeremy L Thompson    Input Parameters:
7665cb80ecdSBarry Smith +  dm - `DM` to be used with `TS`
7675cb80ecdSBarry Smith -  f - explicit evaluation context destroy function
768800f99ffSJeremy L Thompson 
769800f99ffSJeremy L Thompson    Level: advanced
770800f99ffSJeremy L Thompson 
771800f99ffSJeremy L Thompson    Note:
7725cb80ecdSBarry Smith    `TSSetRHSFunctionContextDestroy()` is normally used, but it calls this function internally because the user context is actually
7735cb80ecdSBarry Smith    associated with the `DM`.  This makes the interface consistent regardless of whether the user interacts with a `DM` or
7745cb80ecdSBarry Smith    not.
7755cb80ecdSBarry Smith 
7765cb80ecdSBarry Smith    Developer Note:
7775cb80ecdSBarry Smith    If `DM` took a more central role at some later date, this could become the primary method of setting the residual.
778800f99ffSJeremy L Thompson 
779*bcf0153eSBarry Smith .seealso: [](chapter_ts), `TSSetRHSFunctionContextDestroy()`, `DMTSSetRHSFunction()`, `TSSetRHSFunction()`
780800f99ffSJeremy L Thompson @*/
781d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetRHSFunctionContextDestroy(DM dm, PetscErrorCode (*f)(void *))
782d71ae5a4SJacob Faibussowitsch {
783800f99ffSJeremy L Thompson   DMTS tsdm;
784800f99ffSJeremy L Thompson 
785800f99ffSJeremy L Thompson   PetscFunctionBegin;
786800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
787800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm, &tsdm));
788800f99ffSJeremy L Thompson   if (tsdm->rhsfunctionctxcontainer) PetscCall(PetscContainerSetUserDestroy(tsdm->rhsfunctionctxcontainer, f));
789800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
790800f99ffSJeremy L Thompson }
791800f99ffSJeremy L Thompson 
792d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSUnsetRHSFunctionContext_Internal(DM dm)
793d71ae5a4SJacob Faibussowitsch {
794800f99ffSJeremy L Thompson   DMTS tsdm;
795800f99ffSJeremy L Thompson 
796800f99ffSJeremy L Thompson   PetscFunctionBegin;
797800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
798800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm, &tsdm));
799800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetRHSFunctionContext_DMTS(tsdm));
800800f99ffSJeremy L Thompson   tsdm->rhsfunctionctxcontainer = NULL;
80124989b8cSPeter Brune   PetscFunctionReturn(0);
80224989b8cSPeter Brune }
80324989b8cSPeter Brune 
804ef20d060SBarry Smith /*@C
805e3c11fc1SJed Brown    DMTSSetTransientVariable - sets function to transform from state to transient variables
806e3c11fc1SJed Brown 
807e3c11fc1SJed Brown    Logically Collective
808e3c11fc1SJed Brown 
8094165533cSJose E. Roman    Input Parameters:
810*bcf0153eSBarry Smith +  dm - `DM` to be used with `TS`
811a96d6ef6SBarry Smith .  tvar - a function that transforms to transient variables
812e3c11fc1SJed Brown -  ctx - a context for tvar
813e3c11fc1SJed Brown 
814a96d6ef6SBarry Smith     Calling sequence of tvar:
815a96d6ef6SBarry Smith $     PetscErrorCode tvar(TS ts,Vec p,Vec c,void *ctx);
816a96d6ef6SBarry Smith 
817a96d6ef6SBarry Smith +   ts - timestep context
8186aad120cSJose E. Roman .   p - input vector (primitive form)
819a96d6ef6SBarry Smith .   c - output vector, transient variables (conservative form)
820a96d6ef6SBarry Smith -   ctx - [optional] user-defined function context
821a96d6ef6SBarry Smith 
822e3c11fc1SJed Brown    Level: advanced
823e3c11fc1SJed Brown 
824e3c11fc1SJed Brown    Notes:
825*bcf0153eSBarry Smith    This is typically used to transform from primitive to conservative variables so that a time integrator (e.g., `TSBDF`)
826e3c11fc1SJed Brown    can be conservative.  In this context, primitive variables P are used to model the state (e.g., because they lead to
827e3c11fc1SJed Brown    well-conditioned formulations even in limiting cases such as low-Mach or zero porosity).  The transient variable is
828e3c11fc1SJed Brown    C(P), specified by calling this function.  An IFunction thus receives arguments (P, Cdot) and the IJacobian must be
829e3c11fc1SJed Brown    evaluated via the chain rule, as in
830e3c11fc1SJed Brown 
831e3c11fc1SJed Brown      dF/dP + shift * dF/dCdot dC/dP.
832e3c11fc1SJed Brown 
833*bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSBDF`, `TSSetTransientVariable()`, `DMTSGetTransientVariable()`, `DMTSSetIFunction()`, `DMTSSetIJacobian()`
834e3c11fc1SJed Brown @*/
835d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetTransientVariable(DM dm, TSTransientVariable tvar, void *ctx)
836d71ae5a4SJacob Faibussowitsch {
837e3c11fc1SJed Brown   DMTS dmts;
838e3c11fc1SJed Brown 
839e3c11fc1SJed Brown   PetscFunctionBegin;
840e3c11fc1SJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8419566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm, &dmts));
842e3c11fc1SJed Brown   dmts->ops->transientvar = tvar;
843e3c11fc1SJed Brown   dmts->transientvarctx   = ctx;
844e3c11fc1SJed Brown   PetscFunctionReturn(0);
845e3c11fc1SJed Brown }
846e3c11fc1SJed Brown 
847e3c11fc1SJed Brown /*@C
848*bcf0153eSBarry Smith    DMTSGetTransientVariable - gets function to transform from state to transient variables set with `DMTSSetTransientVariable()`
849e3c11fc1SJed Brown 
850e3c11fc1SJed Brown    Logically Collective
851e3c11fc1SJed Brown 
8524165533cSJose E. Roman    Input Parameter:
853*bcf0153eSBarry Smith .  dm - `DM` to be used with `TS`
854e3c11fc1SJed Brown 
8554165533cSJose E. Roman    Output Parameters:
856a96d6ef6SBarry Smith +  tvar - a function that transforms to transient variables
857e3c11fc1SJed Brown -  ctx - a context for tvar
858e3c11fc1SJed Brown 
859e3c11fc1SJed Brown    Level: advanced
860e3c11fc1SJed Brown 
861*bcf0153eSBarry Smith .seealso: [](chapter_ts), `DM`, `DMTSSetTransientVariable()`, `DMTSGetIFunction()`, `DMTSGetIJacobian()`
862e3c11fc1SJed Brown @*/
863d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSGetTransientVariable(DM dm, TSTransientVariable *tvar, void *ctx)
864d71ae5a4SJacob Faibussowitsch {
865e3c11fc1SJed Brown   DMTS dmts;
866e3c11fc1SJed Brown 
867e3c11fc1SJed Brown   PetscFunctionBegin;
868e3c11fc1SJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8699566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm, &dmts));
870e3c11fc1SJed Brown   if (tvar) *tvar = dmts->ops->transientvar;
871e3c11fc1SJed Brown   if (ctx) *(void **)ctx = dmts->transientvarctx;
872e3c11fc1SJed Brown   PetscFunctionReturn(0);
873e3c11fc1SJed Brown }
874e3c11fc1SJed Brown 
875e3c11fc1SJed Brown /*@C
876*bcf0153eSBarry Smith    DMTSGetSolutionFunction - gets the `TS` solution evaluation function
877ef20d060SBarry Smith 
878ef20d060SBarry Smith    Not Collective
879ef20d060SBarry Smith 
8804165533cSJose E. Roman    Input Parameter:
881*bcf0153eSBarry Smith .  dm - `DM` to be used with `TS`
882ef20d060SBarry Smith 
883ef20d060SBarry Smith    Output Parameters:
884*bcf0153eSBarry Smith +  func - solution function evaluation function, see `TSSetSolution()` for calling sequence
885ef20d060SBarry Smith -  ctx - context for solution evaluation
886ef20d060SBarry Smith 
887ef20d060SBarry Smith    Level: advanced
888ef20d060SBarry Smith 
889*bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `DM`, `DMTSSetContext()`, `TSSetFunction()`, `DMTSSetJacobian()`, `DMTSSetSolutionFunction()`
890ef20d060SBarry Smith @*/
891d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSGetSolutionFunction(DM dm, TSSolutionFunction *func, void **ctx)
892d71ae5a4SJacob Faibussowitsch {
893942e3340SBarry Smith   DMTS tsdm;
894ef20d060SBarry Smith 
895ef20d060SBarry Smith   PetscFunctionBegin;
896ef20d060SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8979566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm, &tsdm));
898d74926cbSBarry Smith   if (func) *func = tsdm->ops->solution;
899ef20d060SBarry Smith   if (ctx) *ctx = tsdm->solutionctx;
900ef20d060SBarry Smith   PetscFunctionReturn(0);
901ef20d060SBarry Smith }
902ef20d060SBarry Smith 
903ef20d060SBarry Smith /*@C
904*bcf0153eSBarry Smith    DMTSSetSolutionFunction - set `TS` solution evaluation function
905ef20d060SBarry Smith 
906ef20d060SBarry Smith    Not Collective
907ef20d060SBarry Smith 
9084165533cSJose E. Roman    Input Parameters:
909*bcf0153eSBarry Smith +  dm - `DM` to be used with `TS`
910a96d6ef6SBarry Smith .  func - solution function evaluation routine
911ef20d060SBarry Smith -  ctx - context for solution evaluation
912ef20d060SBarry Smith 
913a96d6ef6SBarry Smith     Calling sequence of f:
914a96d6ef6SBarry Smith $     PetscErrorCode f(TS ts,PetscReal t,Vec u,void *ctx);
915a96d6ef6SBarry Smith 
916a96d6ef6SBarry Smith +   ts - timestep context
917a96d6ef6SBarry Smith .   t - current timestep
918a96d6ef6SBarry Smith .   u - output vector
919a96d6ef6SBarry Smith -   ctx - [optional] user-defined function context
920a96d6ef6SBarry Smith 
921ef20d060SBarry Smith    Level: advanced
922ef20d060SBarry Smith 
923ef20d060SBarry Smith    Note:
924*bcf0153eSBarry Smith    `TSSetSolutionFunction()` is normally used, but it calls this function internally because the user context is actually
925*bcf0153eSBarry Smith    associated with the `DM`.  This makes the interface consistent regardless of whether the user interacts with a `DM` or
926*bcf0153eSBarry Smith    not. If `DM` took a more central role at some later date, this could become the primary method of setting the residual.
927ef20d060SBarry Smith 
928*bcf0153eSBarry Smith .seealso: [](chapter_ts), `DM`, `TS`, `DMTSSetContext()`, `TSSetFunction()`, `DMTSSetJacobian()`, `DMTSGetSolutionFunction()`
929ef20d060SBarry Smith @*/
930d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetSolutionFunction(DM dm, TSSolutionFunction func, void *ctx)
931d71ae5a4SJacob Faibussowitsch {
932942e3340SBarry Smith   DMTS tsdm;
933ef20d060SBarry Smith 
934ef20d060SBarry Smith   PetscFunctionBegin;
935ef20d060SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
9369566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm, &tsdm));
937d74926cbSBarry Smith   if (func) tsdm->ops->solution = func;
938ef20d060SBarry Smith   if (ctx) tsdm->solutionctx = ctx;
939ef20d060SBarry Smith   PetscFunctionReturn(0);
940ef20d060SBarry Smith }
941ef20d060SBarry Smith 
9429b7cd975SBarry Smith /*@C
943*bcf0153eSBarry Smith    DMTSSetForcingFunction - set `TS` forcing function evaluation function
9449b7cd975SBarry Smith 
9459b7cd975SBarry Smith    Not Collective
9469b7cd975SBarry Smith 
9474165533cSJose E. Roman    Input Parameters:
948*bcf0153eSBarry Smith +  dm - `DM` to be used with `TS`
949a96d6ef6SBarry Smith .  f - forcing function evaluation routine
9509b7cd975SBarry Smith -  ctx - context for solution evaluation
9519b7cd975SBarry Smith 
952a96d6ef6SBarry Smith     Calling sequence of func:
953a96d6ef6SBarry Smith $     PetscErrorCode func (TS ts,PetscReal t,Vec f,void *ctx);
954a96d6ef6SBarry Smith 
955a96d6ef6SBarry Smith +   ts - timestep context
956a96d6ef6SBarry Smith .   t - current timestep
957a96d6ef6SBarry Smith .   f - output vector
958a96d6ef6SBarry Smith -   ctx - [optional] user-defined function context
959a96d6ef6SBarry Smith 
9609b7cd975SBarry Smith    Level: advanced
9619b7cd975SBarry Smith 
9629b7cd975SBarry Smith    Note:
963*bcf0153eSBarry Smith    `TSSetForcingFunction()` is normally used, but it calls this function internally because the user context is actually
964*bcf0153eSBarry Smith    associated with the `DM`.  This makes the interface consistent regardless of whether the user interacts with a `DM` or
965*bcf0153eSBarry Smith    not. If `DM` took a more central role at some later date, this could become the primary method of setting the residual.
9669b7cd975SBarry Smith 
967*bcf0153eSBarry Smith .seealso: [](chapter_ts), `DM`, `TS`, `DMTSSetContext()`, `TSSetFunction()`, `DMTSSetJacobian()`, `TSSetForcingFunction()`, `DMTSGetForcingFunction()`
9689b7cd975SBarry Smith @*/
969d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetForcingFunction(DM dm, TSForcingFunction f, void *ctx)
970d71ae5a4SJacob Faibussowitsch {
9719b7cd975SBarry Smith   DMTS tsdm;
9729b7cd975SBarry Smith 
9739b7cd975SBarry Smith   PetscFunctionBegin;
9749b7cd975SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
9759566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm, &tsdm));
976f8b49ee9SBarry Smith   if (f) tsdm->ops->forcing = f;
9779b7cd975SBarry Smith   if (ctx) tsdm->forcingctx = ctx;
9789b7cd975SBarry Smith   PetscFunctionReturn(0);
9799b7cd975SBarry Smith }
9809b7cd975SBarry Smith 
9819b7cd975SBarry Smith /*@C
982*bcf0153eSBarry Smith    DMTSGetForcingFunction - get `TS` forcing function evaluation function
9839b7cd975SBarry Smith 
9849b7cd975SBarry Smith    Not Collective
9859b7cd975SBarry Smith 
9864165533cSJose E. Roman    Input Parameter:
987*bcf0153eSBarry Smith .   dm - `DM` to be used with `TS`
9889b7cd975SBarry Smith 
9894165533cSJose E. Roman    Output Parameters:
990*bcf0153eSBarry Smith +  f - forcing function evaluation function; see `TSForcingFunction` for details
9919b7cd975SBarry Smith -  ctx - context for solution evaluation
9929b7cd975SBarry Smith 
9939b7cd975SBarry Smith    Level: advanced
9949b7cd975SBarry Smith 
9959b7cd975SBarry Smith    Note:
996*bcf0153eSBarry Smith    `TSSetForcingFunction()` is normally used, but it calls this function internally because the user context is actually
997*bcf0153eSBarry Smith    associated with the `DM`.  This makes the interface consistent regardless of whether the user interacts with a `DM` or
998*bcf0153eSBarry Smith    not. If `DM` took a more central role at some later date, this could become the primary method of setting the residual.
9999b7cd975SBarry Smith 
1000*bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `DM`, `DMTSSetContext()`, `TSSetFunction()`, `DMTSSetJacobian()`, `TSSetForcingFunction()`, `DMTSGetForcingFunction()`
10019b7cd975SBarry Smith @*/
1002d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSGetForcingFunction(DM dm, TSForcingFunction *f, void **ctx)
1003d71ae5a4SJacob Faibussowitsch {
10049b7cd975SBarry Smith   DMTS tsdm;
10059b7cd975SBarry Smith 
10069b7cd975SBarry Smith   PetscFunctionBegin;
10079b7cd975SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
10089566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm, &tsdm));
1009f8b49ee9SBarry Smith   if (f) *f = tsdm->ops->forcing;
10109b7cd975SBarry Smith   if (ctx) *ctx = tsdm->forcingctx;
10119b7cd975SBarry Smith   PetscFunctionReturn(0);
10129b7cd975SBarry Smith }
10139b7cd975SBarry Smith 
101424989b8cSPeter Brune /*@C
1015*bcf0153eSBarry Smith    DMTSGetRHSFunction - get `TS` explicit residual evaluation function
101624989b8cSPeter Brune 
101724989b8cSPeter Brune    Not Collective
101824989b8cSPeter Brune 
10194165533cSJose E. Roman    Input Parameter:
1020*bcf0153eSBarry Smith .  dm - `DM` to be used with `TS`
102124989b8cSPeter Brune 
10224165533cSJose E. Roman    Output Parameters:
1023*bcf0153eSBarry Smith +  func - residual evaluation function, see `TSSetRHSFunction()` for calling sequence
102424989b8cSPeter Brune -  ctx - context for residual evaluation
102524989b8cSPeter Brune 
102624989b8cSPeter Brune    Level: advanced
102724989b8cSPeter Brune 
102824989b8cSPeter Brune    Note:
1029*bcf0153eSBarry Smith    `TSGetFunction()` is normally used, but it calls this function internally because the user context is actually
103024989b8cSPeter Brune    associated with the DM.
103124989b8cSPeter Brune 
1032*bcf0153eSBarry Smith .seealso: [](chapter_ts), `DM`, `TS`, `DMTSSetContext()`, `DMTSSetRHSFunction()`, `TSSetRHSFunction()`
103324989b8cSPeter Brune @*/
1034d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSGetRHSFunction(DM dm, TSRHSFunction *func, void **ctx)
1035d71ae5a4SJacob Faibussowitsch {
1036942e3340SBarry Smith   DMTS tsdm;
103724989b8cSPeter Brune 
103824989b8cSPeter Brune   PetscFunctionBegin;
103924989b8cSPeter Brune   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
10409566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm, &tsdm));
1041d74926cbSBarry Smith   if (func) *func = tsdm->ops->rhsfunction;
1042800f99ffSJeremy L Thompson   if (ctx) {
1043800f99ffSJeremy L Thompson     if (tsdm->rhsfunctionctxcontainer) PetscCall(PetscContainerGetPointer(tsdm->rhsfunctionctxcontainer, ctx));
1044800f99ffSJeremy L Thompson     else *ctx = NULL;
1045800f99ffSJeremy L Thompson   }
104624989b8cSPeter Brune   PetscFunctionReturn(0);
104724989b8cSPeter Brune }
104824989b8cSPeter Brune 
104924989b8cSPeter Brune /*@C
1050*bcf0153eSBarry Smith    DMTSSetIJacobian - set `TS` Jacobian evaluation function
105124989b8cSPeter Brune 
105224989b8cSPeter Brune    Not Collective
105324989b8cSPeter Brune 
10544165533cSJose E. Roman    Input Parameters:
1055*bcf0153eSBarry Smith +  dm - `DM` to be used with `TS`
1056a96d6ef6SBarry Smith .  func - Jacobian evaluation routine
105724989b8cSPeter Brune -  ctx - context for residual evaluation
105824989b8cSPeter Brune 
1059a96d6ef6SBarry Smith    Calling sequence of f:
1060a96d6ef6SBarry Smith $    PetscErrorCode f(TS ts,PetscReal t,Vec U,Vec U_t,PetscReal a,Mat Amat,Mat Pmat,void *ctx);
1061a96d6ef6SBarry Smith 
1062a96d6ef6SBarry Smith +  t    - time at step/stage being solved
1063a96d6ef6SBarry Smith .  U    - state vector
1064a96d6ef6SBarry Smith .  U_t  - time derivative of state vector
1065a96d6ef6SBarry Smith .  a    - shift
1066a96d6ef6SBarry Smith .  Amat - (approximate) Jacobian of F(t,U,W+a*U), equivalent to dF/dU + a*dF/dU_t
1067a96d6ef6SBarry Smith .  Pmat - matrix used for constructing preconditioner, usually the same as Amat
1068a96d6ef6SBarry Smith -  ctx  - [optional] user-defined context for matrix evaluation routine
1069a96d6ef6SBarry Smith 
107024989b8cSPeter Brune    Level: advanced
107124989b8cSPeter Brune 
107224989b8cSPeter Brune    Note:
1073*bcf0153eSBarry Smith    `TSSetJacobian()` is normally used, but it calls this function internally because the user context is actually
1074*bcf0153eSBarry Smith    associated with the `DM`.  This makes the interface consistent regardless of whether the user interacts with a `DM` or
1075*bcf0153eSBarry Smith    not. If `DM` took a more central role at some later date, this could become the primary method of setting the Jacobian.
107624989b8cSPeter Brune 
1077*bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `DM`, `DMTSSetContext()`, `TSSetRHSFunction()`, `DMTSGetJacobian()`, `TSSetIJacobian()`, `TSSetIFunction()`
107824989b8cSPeter Brune @*/
1079d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetIJacobian(DM dm, TSIJacobian func, void *ctx)
1080d71ae5a4SJacob Faibussowitsch {
1081800f99ffSJeremy L Thompson   DMTS tsdm;
108224989b8cSPeter Brune 
108324989b8cSPeter Brune   PetscFunctionBegin;
108424989b8cSPeter Brune   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1085800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm, &tsdm));
1086800f99ffSJeremy L Thompson   if (func) tsdm->ops->ijacobian = func;
1087800f99ffSJeremy L Thompson   if (ctx) {
1088800f99ffSJeremy L Thompson     PetscContainer ctxcontainer;
1089800f99ffSJeremy L Thompson     PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)tsdm), &ctxcontainer));
1090800f99ffSJeremy L Thompson     PetscCall(PetscContainerSetPointer(ctxcontainer, ctx));
1091800f99ffSJeremy L Thompson     PetscCall(PetscObjectCompose((PetscObject)tsdm, "ijacobian ctx", (PetscObject)ctxcontainer));
1092800f99ffSJeremy L Thompson     tsdm->ijacobianctxcontainer = ctxcontainer;
1093800f99ffSJeremy L Thompson     PetscCall(PetscContainerDestroy(&ctxcontainer));
1094800f99ffSJeremy L Thompson   }
1095800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
1096800f99ffSJeremy L Thompson }
1097800f99ffSJeremy L Thompson 
1098800f99ffSJeremy L Thompson /*@C
10995cb80ecdSBarry Smith    DMTSSetIJacobianContextDestroy - set `TS` Jacobian evaluation context destroy function
1100800f99ffSJeremy L Thompson 
1101800f99ffSJeremy L Thompson    Not Collective
1102800f99ffSJeremy L Thompson 
1103800f99ffSJeremy L Thompson    Input Parameters:
11045cb80ecdSBarry Smith +  dm - `DM` to be used with `TS`
11055cb80ecdSBarry Smith -  f - Jacobian evaluation context destroy function
1106800f99ffSJeremy L Thompson 
1107800f99ffSJeremy L Thompson    Level: advanced
1108800f99ffSJeremy L Thompson 
1109800f99ffSJeremy L Thompson    Note:
11105cb80ecdSBarry Smith    `TSSetIJacobianContextDestroy()` is normally used, but it calls this function internally because the user context is actually
11115cb80ecdSBarry Smith    associated with the `DM`.  This makes the interface consistent regardless of whether the user interacts with a `DM` or
11125cb80ecdSBarry Smith    not.
1113800f99ffSJeremy L Thompson 
11145cb80ecdSBarry Smith    Developer Note:
11155cb80ecdSBarry Smith    If `DM` took a more central role at some later date, this could become the primary method of setting the Jacobian.
11165cb80ecdSBarry Smith 
1117*bcf0153eSBarry Smith .seealso: [](chapter_ts), `TSSetIJacobianContextDestroy()`, `TSSetI2JacobianContextDestroy()`, `DMTSSetIJacobian()`, `TSSetIJacobian()`
1118800f99ffSJeremy L Thompson @*/
1119d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetIJacobianContextDestroy(DM dm, PetscErrorCode (*f)(void *))
1120d71ae5a4SJacob Faibussowitsch {
1121800f99ffSJeremy L Thompson   DMTS tsdm;
1122800f99ffSJeremy L Thompson 
1123800f99ffSJeremy L Thompson   PetscFunctionBegin;
1124800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1125800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm, &tsdm));
1126800f99ffSJeremy L Thompson   if (tsdm->ijacobianctxcontainer) PetscCall(PetscContainerSetUserDestroy(tsdm->ijacobianctxcontainer, f));
1127800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
1128800f99ffSJeremy L Thompson }
1129800f99ffSJeremy L Thompson 
1130d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSUnsetIJacobianContext_Internal(DM dm)
1131d71ae5a4SJacob Faibussowitsch {
1132800f99ffSJeremy L Thompson   DMTS tsdm;
1133800f99ffSJeremy L Thompson 
1134800f99ffSJeremy L Thompson   PetscFunctionBegin;
1135800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1136800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm, &tsdm));
1137800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetIJacobianContext_DMTS(tsdm));
113824989b8cSPeter Brune   PetscFunctionReturn(0);
113924989b8cSPeter Brune }
114024989b8cSPeter Brune 
114124989b8cSPeter Brune /*@C
1142*bcf0153eSBarry Smith    DMTSGetIJacobian - get `TS` Jacobian evaluation function
114324989b8cSPeter Brune 
114424989b8cSPeter Brune    Not Collective
114524989b8cSPeter Brune 
11464165533cSJose E. Roman    Input Parameter:
1147*bcf0153eSBarry Smith .  dm - `DM` to be used with `TS`
114824989b8cSPeter Brune 
11494165533cSJose E. Roman    Output Parameters:
1150*bcf0153eSBarry Smith +  func - Jacobian evaluation function, see `TSSetIJacobian()` for calling sequence
115124989b8cSPeter Brune -  ctx - context for residual evaluation
115224989b8cSPeter Brune 
115324989b8cSPeter Brune    Level: advanced
115424989b8cSPeter Brune 
115524989b8cSPeter Brune    Note:
1156*bcf0153eSBarry Smith    `TSGetJacobian()` is normally used, but it calls this function internally because the user context is actually
1157*bcf0153eSBarry Smith    associated with the `DM`.  This makes the interface consistent regardless of whether the user interacts with a `DM` or
1158*bcf0153eSBarry Smith    not. If `DM` took a more central role at some later date, this could become the primary method of setting the Jacobian.
115924989b8cSPeter Brune 
1160*bcf0153eSBarry Smith .seealso: [](chapter_ts), `DM`, `TS`, `DMTSSetContext()`, `TSSetFunction()`, `DMTSSetJacobian()`
116124989b8cSPeter Brune @*/
1162d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSGetIJacobian(DM dm, TSIJacobian *func, void **ctx)
1163d71ae5a4SJacob Faibussowitsch {
1164942e3340SBarry Smith   DMTS tsdm;
116524989b8cSPeter Brune 
116624989b8cSPeter Brune   PetscFunctionBegin;
116724989b8cSPeter Brune   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
11689566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm, &tsdm));
1169d74926cbSBarry Smith   if (func) *func = tsdm->ops->ijacobian;
1170800f99ffSJeremy L Thompson   if (ctx) {
1171800f99ffSJeremy L Thompson     if (tsdm->ijacobianctxcontainer) PetscCall(PetscContainerGetPointer(tsdm->ijacobianctxcontainer, ctx));
1172800f99ffSJeremy L Thompson     else *ctx = NULL;
1173800f99ffSJeremy L Thompson   }
117424989b8cSPeter Brune   PetscFunctionReturn(0);
117524989b8cSPeter Brune }
117624989b8cSPeter Brune 
117724989b8cSPeter Brune /*@C
1178*bcf0153eSBarry Smith    DMTSSetRHSJacobian - set `TS` Jacobian evaluation function
117924989b8cSPeter Brune 
118024989b8cSPeter Brune    Not Collective
118124989b8cSPeter Brune 
11824165533cSJose E. Roman    Input Parameters:
1183*bcf0153eSBarry Smith +  dm - `DM` to be used with `TS`
1184a96d6ef6SBarry Smith .  func - Jacobian evaluation routine
118524989b8cSPeter Brune -  ctx - context for residual evaluation
118624989b8cSPeter Brune 
1187a96d6ef6SBarry Smith    Calling sequence of func:
1188a96d6ef6SBarry Smith $     PetscErrorCode func(TS ts,PetscReal t,Vec u,Mat A,Mat B,void *ctx);
1189a96d6ef6SBarry Smith 
1190a96d6ef6SBarry Smith +  t - current timestep
1191a96d6ef6SBarry Smith .  u - input vector
1192a96d6ef6SBarry Smith .  Amat - (approximate) Jacobian matrix
1193a96d6ef6SBarry Smith .  Pmat - matrix from which preconditioner is to be constructed (usually the same as Amat)
1194a96d6ef6SBarry Smith -  ctx - [optional] user-defined context for matrix evaluation routine
1195a96d6ef6SBarry Smith 
119624989b8cSPeter Brune    Level: advanced
119724989b8cSPeter Brune 
119824989b8cSPeter Brune    Note:
1199*bcf0153eSBarry Smith    `TSSetJacobian()` is normally used, but it calls this function internally because the user context is actually
1200*bcf0153eSBarry Smith    associated with the `DM`.  This makes the interface consistent regardless of whether the user interacts with a `DM` or
1201*bcf0153eSBarry Smith    not.
120224989b8cSPeter Brune 
1203*bcf0153eSBarry Smith    Developer Note:
1204*bcf0153eSBarry Smith    If `DM` took a more central role at some later date, this could become the primary method of setting the Jacobian.
1205*bcf0153eSBarry Smith 
1206*bcf0153eSBarry Smith .seealso: [](chapter_ts), `DMTSSetContext()`, `TSSetFunction()`, `DMTSGetJacobian()`, `TSSetRHSJacobian()`
120724989b8cSPeter Brune @*/
1208d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetRHSJacobian(DM dm, TSRHSJacobian func, void *ctx)
1209d71ae5a4SJacob Faibussowitsch {
1210942e3340SBarry Smith   DMTS tsdm;
121124989b8cSPeter Brune 
121224989b8cSPeter Brune   PetscFunctionBegin;
121324989b8cSPeter Brune   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
12149566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm, &tsdm));
1215d74926cbSBarry Smith   if (func) tsdm->ops->rhsjacobian = func;
1216800f99ffSJeremy L Thompson   if (ctx) {
1217800f99ffSJeremy L Thompson     PetscContainer ctxcontainer;
1218800f99ffSJeremy L Thompson     PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)tsdm), &ctxcontainer));
1219800f99ffSJeremy L Thompson     PetscCall(PetscContainerSetPointer(ctxcontainer, ctx));
1220800f99ffSJeremy L Thompson     PetscCall(PetscObjectCompose((PetscObject)tsdm, "rhs jacobian ctx", (PetscObject)ctxcontainer));
1221800f99ffSJeremy L Thompson     tsdm->rhsjacobianctxcontainer = ctxcontainer;
1222800f99ffSJeremy L Thompson     PetscCall(PetscContainerDestroy(&ctxcontainer));
1223800f99ffSJeremy L Thompson   }
1224800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
1225800f99ffSJeremy L Thompson }
1226800f99ffSJeremy L Thompson 
1227800f99ffSJeremy L Thompson /*@C
12285cb80ecdSBarry Smith    DMTSSetRHSJacobianContextDestroy - set `TS` Jacobian evaluation context destroy function
1229800f99ffSJeremy L Thompson 
1230800f99ffSJeremy L Thompson    Not Collective
1231800f99ffSJeremy L Thompson 
1232800f99ffSJeremy L Thompson    Input Parameters:
12335cb80ecdSBarry Smith +  dm - `DM` to be used with `TS`
12345cb80ecdSBarry Smith -  f - Jacobian evaluation context destroy function
12355cb80ecdSBarry Smith 
12365cb80ecdSBarry Smith    Level: advanced
12375cb80ecdSBarry Smith 
12385cb80ecdSBarry Smith    Note:
12395cb80ecdSBarry Smith    The user usually calls `TSSetRHSJacobianContextDestroy()` which calls this routine
1240800f99ffSJeremy L Thompson 
1241*bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetRHSJacobianContextDestroy()`, `DMTSSetRHSJacobian()`, `TSSetRHSJacobian()`
1242800f99ffSJeremy L Thompson @*/
1243d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetRHSJacobianContextDestroy(DM dm, PetscErrorCode (*f)(void *))
1244d71ae5a4SJacob Faibussowitsch {
1245800f99ffSJeremy L Thompson   DMTS tsdm;
1246800f99ffSJeremy L Thompson 
1247800f99ffSJeremy L Thompson   PetscFunctionBegin;
1248800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1249800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm, &tsdm));
1250800f99ffSJeremy L Thompson   if (tsdm->rhsjacobianctxcontainer) PetscCall(PetscContainerSetUserDestroy(tsdm->rhsjacobianctxcontainer, f));
1251800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
1252800f99ffSJeremy L Thompson }
1253800f99ffSJeremy L Thompson 
1254d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSUnsetRHSJacobianContext_Internal(DM dm)
1255d71ae5a4SJacob Faibussowitsch {
1256800f99ffSJeremy L Thompson   DMTS tsdm;
1257800f99ffSJeremy L Thompson 
1258800f99ffSJeremy L Thompson   PetscFunctionBegin;
1259800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1260800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm, &tsdm));
1261800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetRHSJacobianContext_DMTS(tsdm));
126224989b8cSPeter Brune   PetscFunctionReturn(0);
126324989b8cSPeter Brune }
126424989b8cSPeter Brune 
126524989b8cSPeter Brune /*@C
1266*bcf0153eSBarry Smith    DMTSGetRHSJacobian - get `TS` Jacobian evaluation function
126724989b8cSPeter Brune 
126824989b8cSPeter Brune    Not Collective
126924989b8cSPeter Brune 
12704165533cSJose E. Roman    Input Parameter:
1271*bcf0153eSBarry Smith .  dm - `DM` to be used with `TS`
127224989b8cSPeter Brune 
12734165533cSJose E. Roman    Output Parameters:
1274*bcf0153eSBarry Smith +  func - Jacobian evaluation function, see `TSSetRHSJacobian()` for calling sequence
127524989b8cSPeter Brune -  ctx - context for residual evaluation
127624989b8cSPeter Brune 
127724989b8cSPeter Brune    Level: advanced
127824989b8cSPeter Brune 
127924989b8cSPeter Brune    Note:
1280*bcf0153eSBarry Smith    `TSGetJacobian()` is normally used, but it calls this function internally because the user context is actually
1281*bcf0153eSBarry Smith    associated with the `DM`.  This makes the interface consistent regardless of whether the user interacts with a `DM` or
1282*bcf0153eSBarry Smith    not. If `DM` took a more central role at some later date, this could become the primary method of setting the Jacobian.
128324989b8cSPeter Brune 
1284*bcf0153eSBarry Smith .seealso: [](chapter_ts), `DM`, `TS`, `DMTSSetContext()`, `TSSetRHSFunction()`, `DMTSSetRHSJacobian()`, `TSSetRHSJacobian()`
128524989b8cSPeter Brune @*/
1286d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSGetRHSJacobian(DM dm, TSRHSJacobian *func, void **ctx)
1287d71ae5a4SJacob Faibussowitsch {
1288942e3340SBarry Smith   DMTS tsdm;
128924989b8cSPeter Brune 
129024989b8cSPeter Brune   PetscFunctionBegin;
129124989b8cSPeter Brune   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
12929566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm, &tsdm));
1293d74926cbSBarry Smith   if (func) *func = tsdm->ops->rhsjacobian;
1294800f99ffSJeremy L Thompson   if (ctx) {
1295800f99ffSJeremy L Thompson     if (tsdm->rhsjacobianctxcontainer) PetscCall(PetscContainerGetPointer(tsdm->rhsjacobianctxcontainer, ctx));
1296800f99ffSJeremy L Thompson     else *ctx = NULL;
1297800f99ffSJeremy L Thompson   }
129824989b8cSPeter Brune   PetscFunctionReturn(0);
129924989b8cSPeter Brune }
1300ad6bc421SBarry Smith 
1301ad6bc421SBarry Smith /*@C
1302ad6bc421SBarry Smith    DMTSSetIFunctionSerialize - sets functions used to view and load a IFunction context
1303ad6bc421SBarry Smith 
1304ad6bc421SBarry Smith    Not Collective
1305ad6bc421SBarry Smith 
13064165533cSJose E. Roman    Input Parameters:
1307*bcf0153eSBarry Smith +  dm - `DM` to be used with `TS`
1308ad6bc421SBarry Smith .  view - viewer function
1309ad6bc421SBarry Smith -  load - loading function
1310ad6bc421SBarry Smith 
1311ad6bc421SBarry Smith    Level: advanced
1312ad6bc421SBarry Smith 
1313*bcf0153eSBarry Smith .seealso: [](chapter_ts), `DM`, `TS`, `DMTSSetContext()`, `TSSetFunction()`, `DMTSSetJacobian()`
1314ad6bc421SBarry Smith @*/
1315d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetIFunctionSerialize(DM dm, PetscErrorCode (*view)(void *, PetscViewer), PetscErrorCode (*load)(void **, PetscViewer))
1316d71ae5a4SJacob Faibussowitsch {
1317ad6bc421SBarry Smith   DMTS tsdm;
1318ad6bc421SBarry Smith 
1319ad6bc421SBarry Smith   PetscFunctionBegin;
1320ad6bc421SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
13219566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm, &tsdm));
1322ad6bc421SBarry Smith   tsdm->ops->ifunctionview = view;
1323ad6bc421SBarry Smith   tsdm->ops->ifunctionload = load;
1324ad6bc421SBarry Smith   PetscFunctionReturn(0);
1325ad6bc421SBarry Smith }
1326ad6bc421SBarry Smith 
1327ad6bc421SBarry Smith /*@C
1328ad6bc421SBarry Smith    DMTSSetIJacobianSerialize - sets functions used to view and load a IJacobian context
1329ad6bc421SBarry Smith 
1330ad6bc421SBarry Smith    Not Collective
1331ad6bc421SBarry Smith 
13324165533cSJose E. Roman    Input Parameters:
1333*bcf0153eSBarry Smith +  dm - `DM` to be used with `TS`
1334ad6bc421SBarry Smith .  view - viewer function
1335ad6bc421SBarry Smith -  load - loading function
1336ad6bc421SBarry Smith 
1337ad6bc421SBarry Smith    Level: advanced
1338ad6bc421SBarry Smith 
1339*bcf0153eSBarry Smith .seealso: [](chapter_ts), `DM`, `TS`, `DMTSSetContext()`, `TSSetFunction()`, `DMTSSetJacobian()`
1340ad6bc421SBarry Smith @*/
1341d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetIJacobianSerialize(DM dm, PetscErrorCode (*view)(void *, PetscViewer), PetscErrorCode (*load)(void **, PetscViewer))
1342d71ae5a4SJacob Faibussowitsch {
1343ad6bc421SBarry Smith   DMTS tsdm;
1344ad6bc421SBarry Smith 
1345ad6bc421SBarry Smith   PetscFunctionBegin;
1346ad6bc421SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
13479566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm, &tsdm));
1348ad6bc421SBarry Smith   tsdm->ops->ijacobianview = view;
1349ad6bc421SBarry Smith   tsdm->ops->ijacobianload = load;
1350ad6bc421SBarry Smith   PetscFunctionReturn(0);
1351ad6bc421SBarry Smith }
1352