xref: /petsc/src/ts/utils/dmts.c (revision d71ae5a4db6382e7f06317b8d368875286fe9008)
1af0996ceSBarry Smith #include <petsc/private/tsimpl.h> /*I "petscts.h" I*/
2af0996ceSBarry Smith #include <petsc/private/dmimpl.h>
324989b8cSPeter Brune 
4*d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMTSUnsetRHSFunctionContext_DMTS(DMTS tsdm)
5*d71ae5a4SJacob 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 
12*d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMTSUnsetRHSJacobianContext_DMTS(DMTS tsdm)
13*d71ae5a4SJacob 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 
20*d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMTSUnsetIFunctionContext_DMTS(DMTS tsdm)
21*d71ae5a4SJacob 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 
28*d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMTSUnsetIJacobianContext_DMTS(DMTS tsdm)
29*d71ae5a4SJacob 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 
36*d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMTSUnsetI2FunctionContext_DMTS(DMTS tsdm)
37*d71ae5a4SJacob 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 
44*d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMTSUnsetI2JacobianContext_DMTS(DMTS tsdm)
45*d71ae5a4SJacob 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 
52*d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMTSDestroy(DMTS *kdm)
53*d71ae5a4SJacob 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 
72*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSLoad(DMTS kdm, PetscViewer viewer)
73*d71ae5a4SJacob 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 
96*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSView(DMTS kdm, PetscViewer viewer)
97*d71ae5a4SJacob 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 
160*d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMTSCreate(MPI_Comm comm, DMTS *kdm)
161*d71ae5a4SJacob 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  */
171*d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMCoarsenHook_DMTS(DM dm, DM dmc, void *ctx)
172*d71ae5a4SJacob 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  */
180*d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMRestrictHook_DMTS(DM dm, Mat Restrict, Vec rscale, Mat Inject, DM dmc, void *ctx)
181*d71ae5a4SJacob Faibussowitsch {
18224989b8cSPeter Brune   PetscFunctionBegin;
18324989b8cSPeter Brune   PetscFunctionReturn(0);
18424989b8cSPeter Brune }
18524989b8cSPeter Brune 
186*d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMSubDomainHook_DMTS(DM dm, DM subdm, void *ctx)
187*d71ae5a4SJacob 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  */
195*d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMSubDomainRestrictHook_DMTS(DM dm, VecScatter gscat, VecScatter lscat, DM subdm, void *ctx)
196*d71ae5a4SJacob Faibussowitsch {
197258e1594SPeter Brune   PetscFunctionBegin;
198258e1594SPeter Brune   PetscFunctionReturn(0);
199258e1594SPeter Brune }
200258e1594SPeter Brune 
201d74926cbSBarry Smith /*@C
202d74926cbSBarry Smith    DMTSCopy - copies the information in a DMTS to another DMTS
203d74926cbSBarry Smith 
204d74926cbSBarry Smith    Not Collective
205d74926cbSBarry Smith 
2064165533cSJose E. Roman    Input Parameters:
207d74926cbSBarry Smith +  kdm - Original DMTS
208d74926cbSBarry Smith -  nkdm - DMTS to receive the data, should have been created with DMTSCreate()
209d74926cbSBarry Smith 
210d74926cbSBarry Smith    Level: developer
211d74926cbSBarry Smith 
212db781477SPatrick Sanan .seealso: `DMTSCreate()`, `DMTSDestroy()`
213d74926cbSBarry Smith @*/
214*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSCopy(DMTS kdm, DMTS nkdm)
215*d71ae5a4SJacob 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
257942e3340SBarry Smith    DMGetDMTS - get read-only private DMTS context from a DM
25824989b8cSPeter Brune 
25924989b8cSPeter Brune    Not Collective
26024989b8cSPeter Brune 
2614165533cSJose E. Roman    Input Parameter:
26224989b8cSPeter Brune .  dm - DM to be used with TS
26324989b8cSPeter Brune 
2644165533cSJose E. Roman    Output Parameter:
265942e3340SBarry Smith .  tsdm - private DMTS context
26624989b8cSPeter Brune 
26724989b8cSPeter Brune    Level: developer
26824989b8cSPeter Brune 
26924989b8cSPeter Brune    Notes:
270942e3340SBarry Smith    Use DMGetDMTSWrite() if write access is needed. The DMTSSetXXX API should be used wherever possible.
27124989b8cSPeter Brune 
272db781477SPatrick Sanan .seealso: `DMGetDMTSWrite()`
27324989b8cSPeter Brune @*/
274*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetDMTS(DM dm, DMTS *tsdm)
275*d71ae5a4SJacob 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
291942e3340SBarry 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:
29624989b8cSPeter Brune .  dm - DM to be used with TS
29724989b8cSPeter Brune 
2984165533cSJose E. Roman    Output Parameter:
299942e3340SBarry Smith .  tsdm - private DMTS context
30024989b8cSPeter Brune 
30124989b8cSPeter Brune    Level: developer
30224989b8cSPeter Brune 
303db781477SPatrick Sanan .seealso: `DMGetDMTS()`
30424989b8cSPeter Brune @*/
305*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetDMTSWrite(DM dm, DMTS *tsdm)
306*d71ae5a4SJacob 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
327942e3340SBarry Smith    DMCopyDMTS - copies a DM context to a new DM
32824989b8cSPeter Brune 
32924989b8cSPeter Brune    Logically Collective
33024989b8cSPeter Brune 
3314165533cSJose E. Roman    Input Parameters:
33224989b8cSPeter Brune +  dmsrc - DM to obtain context from
33324989b8cSPeter Brune -  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 
340db781477SPatrick Sanan .seealso: `DMGetDMTS()`, `TSSetDM()`
34124989b8cSPeter Brune @*/
342*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCopyDMTS(DM dmsrc, DM dmdest)
343*d71ae5a4SJacob 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
35624989b8cSPeter Brune    DMTSSetIFunction - set TS implicit function evaluation function
35724989b8cSPeter Brune 
35824989b8cSPeter Brune    Not Collective
35924989b8cSPeter Brune 
3604165533cSJose E. Roman    Input Parameters:
36124989b8cSPeter Brune +  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:
37724989b8cSPeter Brune    TSSetFunction() is normally used, but it calls this function internally because the user context is actually
37824989b8cSPeter Brune    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 
381db781477SPatrick Sanan .seealso: `DMTSSetContext()`, `TSSetIFunction()`, `DMTSSetJacobian()`
38224989b8cSPeter Brune @*/
383*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetIFunction(DM dm, TSIFunction func, void *ctx)
384*d71ae5a4SJacob 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 
41390f54644SBarry Smith .seealso: `DMTSSetIFunction()`, `TSSetIFunction()`
414800f99ffSJeremy L Thompson @*/
415*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetIFunctionContextDestroy(DM dm, PetscErrorCode (*f)(void *))
416*d71ae5a4SJacob 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 
426*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSUnsetIFunctionContext_Internal(DM dm)
427*d71ae5a4SJacob 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
43824989b8cSPeter Brune    DMTSGetIFunction - get TS implicit residual evaluation function
43924989b8cSPeter Brune 
44024989b8cSPeter Brune    Not Collective
44124989b8cSPeter Brune 
4424165533cSJose E. Roman    Input Parameter:
44324989b8cSPeter Brune .  dm - DM to be used with TS
44424989b8cSPeter Brune 
4454165533cSJose E. Roman    Output Parameters:
44624989b8cSPeter Brune +  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:
45224989b8cSPeter Brune    TSGetFunction() is normally used, but it calls this function internally because the user context is actually
45324989b8cSPeter Brune    associated with the DM.
45424989b8cSPeter Brune 
455db781477SPatrick Sanan .seealso: `DMTSSetContext()`, `DMTSSetFunction()`, `TSSetFunction()`
45624989b8cSPeter Brune @*/
457*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSGetIFunction(DM dm, TSIFunction *func, void **ctx)
458*d71ae5a4SJacob 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
473efe9872eSLisandro Dalcin    DMTSSetI2Function - set TS implicit function evaluation function for 2nd order systems
474efe9872eSLisandro Dalcin 
475efe9872eSLisandro Dalcin    Not Collective
476efe9872eSLisandro Dalcin 
4774165533cSJose E. Roman    Input Parameters:
478efe9872eSLisandro Dalcin +  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:
495efe9872eSLisandro Dalcin    TSSetI2Function() is normally used, but it calls this function internally because the user context is actually
496efe9872eSLisandro Dalcin    associated with the DM.
497efe9872eSLisandro Dalcin 
498db781477SPatrick Sanan .seealso: `TSSetI2Function()`
499efe9872eSLisandro Dalcin @*/
500*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetI2Function(DM dm, TSI2Function fun, void *ctx)
501*d71ae5a4SJacob 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 
534800f99ffSJeremy L Thompson .seealso: `TSSetI2FunctionContextDestroy()`, `DMTSSetI2Function()`, `TSSetI2Function()`
535800f99ffSJeremy L Thompson @*/
536*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetI2FunctionContextDestroy(DM dm, PetscErrorCode (*f)(void *))
537*d71ae5a4SJacob 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 
547*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSUnsetI2FunctionContext_Internal(DM dm)
548*d71ae5a4SJacob 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
559efe9872eSLisandro Dalcin    DMTSGetI2Function - get TS implicit residual evaluation function for 2nd order systems
560efe9872eSLisandro Dalcin 
561efe9872eSLisandro Dalcin    Not Collective
562efe9872eSLisandro Dalcin 
5634165533cSJose E. Roman    Input Parameter:
564efe9872eSLisandro Dalcin .  dm - DM to be used with TS
565efe9872eSLisandro Dalcin 
5664165533cSJose E. Roman    Output Parameters:
567efe9872eSLisandro Dalcin +  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:
573efe9872eSLisandro Dalcin    TSGetI2Function() is normally used, but it calls this function internally because the user context is actually
574efe9872eSLisandro Dalcin    associated with the DM.
575efe9872eSLisandro Dalcin 
576c2e3fba1SPatrick Sanan .seealso: `DMTSSetI2Function()`, `TSGetI2Function()`
577efe9872eSLisandro Dalcin @*/
578*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSGetI2Function(DM dm, TSI2Function *fun, void **ctx)
579*d71ae5a4SJacob 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
594efe9872eSLisandro Dalcin    DMTSSetI2Jacobian - set TS implicit Jacobian evaluation function for 2nd order systems
595efe9872eSLisandro Dalcin 
596efe9872eSLisandro Dalcin    Not Collective
597efe9872eSLisandro Dalcin 
5984165533cSJose E. Roman    Input Parameters:
599efe9872eSLisandro Dalcin +  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:
619efe9872eSLisandro Dalcin    TSSetI2Jacobian() is normally used, but it calls this function internally because the user context is actually
620efe9872eSLisandro Dalcin    associated with the DM.
621efe9872eSLisandro Dalcin 
622db781477SPatrick Sanan .seealso: `TSSetI2Jacobian()`
623efe9872eSLisandro Dalcin @*/
624*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetI2Jacobian(DM dm, TSI2Jacobian jac, void *ctx)
625*d71ae5a4SJacob 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 
654800f99ffSJeremy L Thompson .seealso: `TSSetI2JacobianContextDestroy()`, `DMTSSetI2Jacobian()`, `TSSetI2Jacobian()`
655800f99ffSJeremy L Thompson @*/
656*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetI2JacobianContextDestroy(DM dm, PetscErrorCode (*f)(void *))
657*d71ae5a4SJacob 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 
667*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSUnsetI2JacobianContext_Internal(DM dm)
668*d71ae5a4SJacob 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
679efe9872eSLisandro Dalcin    DMTSGetI2Jacobian - get TS implicit Jacobian evaluation function for 2nd order systems
680efe9872eSLisandro Dalcin 
681efe9872eSLisandro Dalcin    Not Collective
682efe9872eSLisandro Dalcin 
6834165533cSJose E. Roman    Input Parameter:
684efe9872eSLisandro Dalcin .  dm - DM to be used with TS
685efe9872eSLisandro Dalcin 
6864165533cSJose E. Roman    Output Parameters:
687efe9872eSLisandro Dalcin +  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:
693efe9872eSLisandro Dalcin    TSGetI2Jacobian() is normally used, but it calls this function internally because the user context is actually
694efe9872eSLisandro Dalcin    associated with the DM.
695efe9872eSLisandro Dalcin 
696c2e3fba1SPatrick Sanan .seealso: `DMTSSetI2Jacobian()`, `TSGetI2Jacobian()`
697efe9872eSLisandro Dalcin @*/
698*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSGetI2Jacobian(DM dm, TSI2Jacobian *jac, void **ctx)
699*d71ae5a4SJacob 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
71424989b8cSPeter Brune    DMTSSetRHSFunction - set TS explicit residual evaluation function
71524989b8cSPeter Brune 
71624989b8cSPeter Brune    Not Collective
71724989b8cSPeter Brune 
7184165533cSJose E. Roman    Input Parameters:
71924989b8cSPeter Brune +  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:
735800f99ffSJeremy L Thompson    TSSetRHSFunction() is normally used, but it calls this function internally because the user context is actually
73624989b8cSPeter Brune    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
73724989b8cSPeter Brune    not. If DM took a more central role at some later date, this could become the primary method of setting the residual.
73824989b8cSPeter Brune 
739db781477SPatrick Sanan .seealso: `DMTSSetContext()`, `TSSetRHSFunction()`, `DMTSSetJacobian()`
74024989b8cSPeter Brune @*/
741*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetRHSFunction(DM dm, TSRHSFunction func, void *ctx)
742*d71ae5a4SJacob 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 
779800f99ffSJeremy L Thompson .seealso: `TSSetRHSFunctionContextDestroy()`, `DMTSSetRHSFunction()`, `TSSetRHSFunction()`
780800f99ffSJeremy L Thompson @*/
781*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetRHSFunctionContextDestroy(DM dm, PetscErrorCode (*f)(void *))
782*d71ae5a4SJacob 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 
792*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSUnsetRHSFunctionContext_Internal(DM dm)
793*d71ae5a4SJacob 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:
810e3c11fc1SJed Brown +  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:
825e3c11fc1SJed Brown    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 
833db781477SPatrick Sanan .seealso: `TSSetTransientVariable()`, `DMTSGetTransientVariable()`, `DMTSSetIFunction()`, `DMTSSetIJacobian()`
834e3c11fc1SJed Brown @*/
835*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetTransientVariable(DM dm, TSTransientVariable tvar, void *ctx)
836*d71ae5a4SJacob 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
848e3c11fc1SJed Brown    DMTSGetTransientVariable - gets function to transform from state to transient variables
849e3c11fc1SJed Brown 
850e3c11fc1SJed Brown    Logically Collective
851e3c11fc1SJed Brown 
8524165533cSJose E. Roman    Input Parameter:
853e3c11fc1SJed Brown .  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 
861db781477SPatrick Sanan .seealso: `DMTSSetTransientVariable()`, `DMTSGetIFunction()`, `DMTSGetIJacobian()`
862e3c11fc1SJed Brown @*/
863*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSGetTransientVariable(DM dm, TSTransientVariable *tvar, void *ctx)
864*d71ae5a4SJacob 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
876ef20d060SBarry Smith    DMTSGetSolutionFunction - gets the TS solution evaluation function
877ef20d060SBarry Smith 
878ef20d060SBarry Smith    Not Collective
879ef20d060SBarry Smith 
8804165533cSJose E. Roman    Input Parameter:
881ef20d060SBarry Smith .  dm - DM to be used with TS
882ef20d060SBarry Smith 
883ef20d060SBarry Smith    Output Parameters:
884ef20d060SBarry 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 
889db781477SPatrick Sanan .seealso: `DMTSSetContext()`, `TSSetFunction()`, `DMTSSetJacobian()`, `DMTSSetSolutionFunction()`
890ef20d060SBarry Smith @*/
891*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSGetSolutionFunction(DM dm, TSSolutionFunction *func, void **ctx)
892*d71ae5a4SJacob 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
904ef20d060SBarry Smith    DMTSSetSolutionFunction - set TS solution evaluation function
905ef20d060SBarry Smith 
906ef20d060SBarry Smith    Not Collective
907ef20d060SBarry Smith 
9084165533cSJose E. Roman    Input Parameters:
909ef20d060SBarry 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:
924ef20d060SBarry Smith    TSSetSolutionFunction() is normally used, but it calls this function internally because the user context is actually
925ef20d060SBarry Smith    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
926ef20d060SBarry 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 
928db781477SPatrick Sanan .seealso: `DMTSSetContext()`, `TSSetFunction()`, `DMTSSetJacobian()`, `DMTSGetSolutionFunction()`
929ef20d060SBarry Smith @*/
930*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetSolutionFunction(DM dm, TSSolutionFunction func, void *ctx)
931*d71ae5a4SJacob 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
9439b7cd975SBarry Smith    DMTSSetForcingFunction - set TS forcing function evaluation function
9449b7cd975SBarry Smith 
9459b7cd975SBarry Smith    Not Collective
9469b7cd975SBarry Smith 
9474165533cSJose E. Roman    Input Parameters:
9489b7cd975SBarry 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:
9639b7cd975SBarry Smith    TSSetForcingFunction() is normally used, but it calls this function internally because the user context is actually
9649b7cd975SBarry Smith    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
9659b7cd975SBarry 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 
967db781477SPatrick Sanan .seealso: `DMTSSetContext()`, `TSSetFunction()`, `DMTSSetJacobian()`, `TSSetForcingFunction()`, `DMTSGetForcingFunction()`
9689b7cd975SBarry Smith @*/
969*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetForcingFunction(DM dm, TSForcingFunction f, void *ctx)
970*d71ae5a4SJacob 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
9829b7cd975SBarry Smith    DMTSGetForcingFunction - get TS forcing function evaluation function
9839b7cd975SBarry Smith 
9849b7cd975SBarry Smith    Not Collective
9859b7cd975SBarry Smith 
9864165533cSJose E. Roman    Input Parameter:
9879b7cd975SBarry Smith .   dm - DM to be used with TS
9889b7cd975SBarry Smith 
9894165533cSJose E. Roman    Output Parameters:
990f8b49ee9SBarry 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:
9969b7cd975SBarry Smith    TSSetForcingFunction() is normally used, but it calls this function internally because the user context is actually
9979b7cd975SBarry Smith    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
9989b7cd975SBarry 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 
1000db781477SPatrick Sanan .seealso: `DMTSSetContext()`, `TSSetFunction()`, `DMTSSetJacobian()`, `TSSetForcingFunction()`, `DMTSGetForcingFunction()`
10019b7cd975SBarry Smith @*/
1002*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSGetForcingFunction(DM dm, TSForcingFunction *f, void **ctx)
1003*d71ae5a4SJacob 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
101524989b8cSPeter Brune    DMTSGetRHSFunction - get TS explicit residual evaluation function
101624989b8cSPeter Brune 
101724989b8cSPeter Brune    Not Collective
101824989b8cSPeter Brune 
10194165533cSJose E. Roman    Input Parameter:
102024989b8cSPeter Brune .  dm - DM to be used with TS
102124989b8cSPeter Brune 
10224165533cSJose E. Roman    Output Parameters:
102324989b8cSPeter Brune +  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:
102924989b8cSPeter Brune    TSGetFunction() is normally used, but it calls this function internally because the user context is actually
103024989b8cSPeter Brune    associated with the DM.
103124989b8cSPeter Brune 
1032db781477SPatrick Sanan .seealso: `DMTSSetContext()`, `DMTSSetRHSFunction()`, `TSSetRHSFunction()`
103324989b8cSPeter Brune @*/
1034*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSGetRHSFunction(DM dm, TSRHSFunction *func, void **ctx)
1035*d71ae5a4SJacob 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
105024989b8cSPeter Brune    DMTSSetIJacobian - set TS Jacobian evaluation function
105124989b8cSPeter Brune 
105224989b8cSPeter Brune    Not Collective
105324989b8cSPeter Brune 
10544165533cSJose E. Roman    Input Parameters:
105524989b8cSPeter Brune +  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:
107324989b8cSPeter Brune    TSSetJacobian() is normally used, but it calls this function internally because the user context is actually
107424989b8cSPeter Brune    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
107524989b8cSPeter Brune    not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian.
107624989b8cSPeter Brune 
1077db781477SPatrick Sanan .seealso: `DMTSSetContext()`, `TSSetRHSFunction()`, `DMTSGetJacobian()`, `TSSetIJacobian()`, `TSSetIFunction()`
107824989b8cSPeter Brune @*/
1079*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetIJacobian(DM dm, TSIJacobian func, void *ctx)
1080*d71ae5a4SJacob 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 
11175cb80ecdSBarry Smith .seealso: `TSSetIJacobianContextDestroy()`, `TSSetI2JacobianContextDestroy()`, `DMTSSetIJacobian()`, `TSSetIJacobian()`
1118800f99ffSJeremy L Thompson @*/
1119*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetIJacobianContextDestroy(DM dm, PetscErrorCode (*f)(void *))
1120*d71ae5a4SJacob 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 
1130*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSUnsetIJacobianContext_Internal(DM dm)
1131*d71ae5a4SJacob 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
114224989b8cSPeter Brune    DMTSGetIJacobian - get TS Jacobian evaluation function
114324989b8cSPeter Brune 
114424989b8cSPeter Brune    Not Collective
114524989b8cSPeter Brune 
11464165533cSJose E. Roman    Input Parameter:
114724989b8cSPeter Brune .  dm - DM to be used with TS
114824989b8cSPeter Brune 
11494165533cSJose E. Roman    Output Parameters:
115024989b8cSPeter Brune +  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:
115624989b8cSPeter Brune    TSGetJacobian() is normally used, but it calls this function internally because the user context is actually
115724989b8cSPeter Brune    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
115824989b8cSPeter Brune    not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian.
115924989b8cSPeter Brune 
1160db781477SPatrick Sanan .seealso: `DMTSSetContext()`, `TSSetFunction()`, `DMTSSetJacobian()`
116124989b8cSPeter Brune @*/
1162*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSGetIJacobian(DM dm, TSIJacobian *func, void **ctx)
1163*d71ae5a4SJacob 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
117824989b8cSPeter Brune    DMTSSetRHSJacobian - set TS Jacobian evaluation function
117924989b8cSPeter Brune 
118024989b8cSPeter Brune    Not Collective
118124989b8cSPeter Brune 
11824165533cSJose E. Roman    Input Parameters:
118324989b8cSPeter Brune +  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:
119924989b8cSPeter Brune    TSSetJacobian() is normally used, but it calls this function internally because the user context is actually
120024989b8cSPeter Brune    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
120124989b8cSPeter Brune    not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian.
120224989b8cSPeter Brune 
1203db781477SPatrick Sanan .seealso: `DMTSSetContext()`, `TSSetFunction()`, `DMTSGetJacobian()`, `TSSetRHSJacobian()`
120424989b8cSPeter Brune @*/
1205*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetRHSJacobian(DM dm, TSRHSJacobian func, void *ctx)
1206*d71ae5a4SJacob Faibussowitsch {
1207942e3340SBarry Smith   DMTS tsdm;
120824989b8cSPeter Brune 
120924989b8cSPeter Brune   PetscFunctionBegin;
121024989b8cSPeter Brune   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
12119566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm, &tsdm));
1212d74926cbSBarry Smith   if (func) tsdm->ops->rhsjacobian = func;
1213800f99ffSJeremy L Thompson   if (ctx) {
1214800f99ffSJeremy L Thompson     PetscContainer ctxcontainer;
1215800f99ffSJeremy L Thompson     PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)tsdm), &ctxcontainer));
1216800f99ffSJeremy L Thompson     PetscCall(PetscContainerSetPointer(ctxcontainer, ctx));
1217800f99ffSJeremy L Thompson     PetscCall(PetscObjectCompose((PetscObject)tsdm, "rhs jacobian ctx", (PetscObject)ctxcontainer));
1218800f99ffSJeremy L Thompson     tsdm->rhsjacobianctxcontainer = ctxcontainer;
1219800f99ffSJeremy L Thompson     PetscCall(PetscContainerDestroy(&ctxcontainer));
1220800f99ffSJeremy L Thompson   }
1221800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
1222800f99ffSJeremy L Thompson }
1223800f99ffSJeremy L Thompson 
1224800f99ffSJeremy L Thompson /*@C
12255cb80ecdSBarry Smith    DMTSSetRHSJacobianContextDestroy - set `TS` Jacobian evaluation context destroy function
1226800f99ffSJeremy L Thompson 
1227800f99ffSJeremy L Thompson    Not Collective
1228800f99ffSJeremy L Thompson 
1229800f99ffSJeremy L Thompson    Input Parameters:
12305cb80ecdSBarry Smith +  dm - `DM` to be used with `TS`
12315cb80ecdSBarry Smith -  f - Jacobian evaluation context destroy function
12325cb80ecdSBarry Smith 
12335cb80ecdSBarry Smith    Level: advanced
12345cb80ecdSBarry Smith 
12355cb80ecdSBarry Smith    Note:
12365cb80ecdSBarry Smith    The user usually calls `TSSetRHSJacobianContextDestroy()` which calls this routine
1237800f99ffSJeremy L Thompson 
123887497f52SBarry Smith    Level: advanced
123987497f52SBarry Smith 
1240800f99ffSJeremy L Thompson .seealso: `TSSetRHSJacobianContextDestroy()`, `DMTSSetRHSJacobian()`, `TSSetRHSJacobian()`
1241800f99ffSJeremy L Thompson @*/
1242*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetRHSJacobianContextDestroy(DM dm, PetscErrorCode (*f)(void *))
1243*d71ae5a4SJacob Faibussowitsch {
1244800f99ffSJeremy L Thompson   DMTS tsdm;
1245800f99ffSJeremy L Thompson 
1246800f99ffSJeremy L Thompson   PetscFunctionBegin;
1247800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1248800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm, &tsdm));
1249800f99ffSJeremy L Thompson   if (tsdm->rhsjacobianctxcontainer) PetscCall(PetscContainerSetUserDestroy(tsdm->rhsjacobianctxcontainer, f));
1250800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
1251800f99ffSJeremy L Thompson }
1252800f99ffSJeremy L Thompson 
1253*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSUnsetRHSJacobianContext_Internal(DM dm)
1254*d71ae5a4SJacob Faibussowitsch {
1255800f99ffSJeremy L Thompson   DMTS tsdm;
1256800f99ffSJeremy L Thompson 
1257800f99ffSJeremy L Thompson   PetscFunctionBegin;
1258800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1259800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm, &tsdm));
1260800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetRHSJacobianContext_DMTS(tsdm));
126124989b8cSPeter Brune   PetscFunctionReturn(0);
126224989b8cSPeter Brune }
126324989b8cSPeter Brune 
126424989b8cSPeter Brune /*@C
126524989b8cSPeter Brune    DMTSGetRHSJacobian - get TS Jacobian evaluation function
126624989b8cSPeter Brune 
126724989b8cSPeter Brune    Not Collective
126824989b8cSPeter Brune 
12694165533cSJose E. Roman    Input Parameter:
127024989b8cSPeter Brune .  dm - DM to be used with TS
127124989b8cSPeter Brune 
12724165533cSJose E. Roman    Output Parameters:
127324989b8cSPeter Brune +  func - Jacobian evaluation function, see TSSetRHSJacobian() for calling sequence
127424989b8cSPeter Brune -  ctx - context for residual evaluation
127524989b8cSPeter Brune 
127624989b8cSPeter Brune    Level: advanced
127724989b8cSPeter Brune 
127824989b8cSPeter Brune    Note:
127924989b8cSPeter Brune    TSGetJacobian() is normally used, but it calls this function internally because the user context is actually
128024989b8cSPeter Brune    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
128124989b8cSPeter Brune    not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian.
128224989b8cSPeter Brune 
1283db781477SPatrick Sanan .seealso: `DMTSSetContext()`, `TSSetRHSFunction()`, `DMTSSetRHSJacobian()`, `TSSetRHSJacobian()`
128424989b8cSPeter Brune @*/
1285*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSGetRHSJacobian(DM dm, TSRHSJacobian *func, void **ctx)
1286*d71ae5a4SJacob Faibussowitsch {
1287942e3340SBarry Smith   DMTS tsdm;
128824989b8cSPeter Brune 
128924989b8cSPeter Brune   PetscFunctionBegin;
129024989b8cSPeter Brune   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
12919566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm, &tsdm));
1292d74926cbSBarry Smith   if (func) *func = tsdm->ops->rhsjacobian;
1293800f99ffSJeremy L Thompson   if (ctx) {
1294800f99ffSJeremy L Thompson     if (tsdm->rhsjacobianctxcontainer) PetscCall(PetscContainerGetPointer(tsdm->rhsjacobianctxcontainer, ctx));
1295800f99ffSJeremy L Thompson     else *ctx = NULL;
1296800f99ffSJeremy L Thompson   }
129724989b8cSPeter Brune   PetscFunctionReturn(0);
129824989b8cSPeter Brune }
1299ad6bc421SBarry Smith 
1300ad6bc421SBarry Smith /*@C
1301ad6bc421SBarry Smith    DMTSSetIFunctionSerialize - sets functions used to view and load a IFunction context
1302ad6bc421SBarry Smith 
1303ad6bc421SBarry Smith    Not Collective
1304ad6bc421SBarry Smith 
13054165533cSJose E. Roman    Input Parameters:
1306ad6bc421SBarry Smith +  dm - DM to be used with TS
1307ad6bc421SBarry Smith .  view - viewer function
1308ad6bc421SBarry Smith -  load - loading function
1309ad6bc421SBarry Smith 
1310ad6bc421SBarry Smith    Level: advanced
1311ad6bc421SBarry Smith 
1312db781477SPatrick Sanan .seealso: `DMTSSetContext()`, `TSSetFunction()`, `DMTSSetJacobian()`
1313ad6bc421SBarry Smith @*/
1314*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetIFunctionSerialize(DM dm, PetscErrorCode (*view)(void *, PetscViewer), PetscErrorCode (*load)(void **, PetscViewer))
1315*d71ae5a4SJacob Faibussowitsch {
1316ad6bc421SBarry Smith   DMTS tsdm;
1317ad6bc421SBarry Smith 
1318ad6bc421SBarry Smith   PetscFunctionBegin;
1319ad6bc421SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
13209566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm, &tsdm));
1321ad6bc421SBarry Smith   tsdm->ops->ifunctionview = view;
1322ad6bc421SBarry Smith   tsdm->ops->ifunctionload = load;
1323ad6bc421SBarry Smith   PetscFunctionReturn(0);
1324ad6bc421SBarry Smith }
1325ad6bc421SBarry Smith 
1326ad6bc421SBarry Smith /*@C
1327ad6bc421SBarry Smith    DMTSSetIJacobianSerialize - sets functions used to view and load a IJacobian context
1328ad6bc421SBarry Smith 
1329ad6bc421SBarry Smith    Not Collective
1330ad6bc421SBarry Smith 
13314165533cSJose E. Roman    Input Parameters:
1332ad6bc421SBarry Smith +  dm - DM to be used with TS
1333ad6bc421SBarry Smith .  view - viewer function
1334ad6bc421SBarry Smith -  load - loading function
1335ad6bc421SBarry Smith 
1336ad6bc421SBarry Smith    Level: advanced
1337ad6bc421SBarry Smith 
1338db781477SPatrick Sanan .seealso: `DMTSSetContext()`, `TSSetFunction()`, `DMTSSetJacobian()`
1339ad6bc421SBarry Smith @*/
1340*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetIJacobianSerialize(DM dm, PetscErrorCode (*view)(void *, PetscViewer), PetscErrorCode (*load)(void **, PetscViewer))
1341*d71ae5a4SJacob Faibussowitsch {
1342ad6bc421SBarry Smith   DMTS tsdm;
1343ad6bc421SBarry Smith 
1344ad6bc421SBarry Smith   PetscFunctionBegin;
1345ad6bc421SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
13469566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm, &tsdm));
1347ad6bc421SBarry Smith   tsdm->ops->ijacobianview = view;
1348ad6bc421SBarry Smith   tsdm->ops->ijacobianload = load;
1349ad6bc421SBarry Smith   PetscFunctionReturn(0);
1350ad6bc421SBarry Smith }
1351