xref: /petsc/src/ts/utils/dmts.c (revision 5cb80ecd61fc93edbe681011dc160a66bbda2b5d)
1af0996ceSBarry Smith #include <petsc/private/tsimpl.h>     /*I "petscts.h" I*/
2af0996ceSBarry Smith #include <petsc/private/dmimpl.h>
324989b8cSPeter Brune 
4800f99ffSJeremy L Thompson static PetscErrorCode DMTSUnsetRHSFunctionContext_DMTS(DMTS tsdm)
5800f99ffSJeremy L Thompson {
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 
12800f99ffSJeremy L Thompson static PetscErrorCode DMTSUnsetRHSJacobianContext_DMTS(DMTS tsdm)
13800f99ffSJeremy L Thompson {
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 
20800f99ffSJeremy L Thompson static PetscErrorCode DMTSUnsetIFunctionContext_DMTS(DMTS tsdm)
21800f99ffSJeremy L Thompson {
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 
28800f99ffSJeremy L Thompson static PetscErrorCode DMTSUnsetIJacobianContext_DMTS(DMTS tsdm)
29800f99ffSJeremy L Thompson {
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 
36800f99ffSJeremy L Thompson static PetscErrorCode DMTSUnsetI2FunctionContext_DMTS(DMTS tsdm)
37800f99ffSJeremy L Thompson {
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 
44800f99ffSJeremy L Thompson static PetscErrorCode DMTSUnsetI2JacobianContext_DMTS(DMTS tsdm)
45800f99ffSJeremy L Thompson {
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 
52d74926cbSBarry Smith static PetscErrorCode DMTSDestroy(DMTS *kdm)
53d74926cbSBarry Smith {
54d74926cbSBarry Smith   PetscFunctionBegin;
55d74926cbSBarry Smith   if (!*kdm) PetscFunctionReturn(0);
56d74926cbSBarry Smith   PetscValidHeaderSpecific((*kdm),DMTS_CLASSID,1);
57c793f718SLisandro Dalcin   if (--((PetscObject)(*kdm))->refct > 0) {*kdm = NULL; PetscFunctionReturn(0);}
58800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetRHSFunctionContext_DMTS(*kdm));
59800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetRHSJacobianContext_DMTS(*kdm));
60800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetIFunctionContext_DMTS(*kdm));
61800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetIJacobianContext_DMTS(*kdm));
62800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetI2FunctionContext_DMTS(*kdm));
63800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetI2JacobianContext_DMTS(*kdm));
649566063dSJacob Faibussowitsch   if ((*kdm)->ops->destroy) PetscCall(((*kdm)->ops->destroy)(*kdm));
659566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(kdm));
66d74926cbSBarry Smith   PetscFunctionReturn(0);
67d74926cbSBarry Smith }
68d74926cbSBarry Smith 
692d53ad75SBarry Smith PetscErrorCode DMTSLoad(DMTS kdm,PetscViewer viewer)
702d53ad75SBarry Smith {
712d53ad75SBarry Smith   PetscFunctionBegin;
729566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer,&kdm->ops->ifunction,1,NULL,PETSC_FUNCTION));
739566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer,&kdm->ops->ifunctionview,1,NULL,PETSC_FUNCTION));
749566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer,&kdm->ops->ifunctionload,1,NULL,PETSC_FUNCTION));
75ad6bc421SBarry Smith   if (kdm->ops->ifunctionload) {
76800f99ffSJeremy L Thompson     void *ctx;
77800f99ffSJeremy L Thompson 
78800f99ffSJeremy L Thompson     PetscCall(PetscContainerGetPointer(kdm->ifunctionctxcontainer,&ctx));
79800f99ffSJeremy L Thompson     PetscCall((*kdm->ops->ifunctionload)(&ctx,viewer));
80ad6bc421SBarry Smith   }
819566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer,&kdm->ops->ijacobian,1,NULL,PETSC_FUNCTION));
829566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer,&kdm->ops->ijacobianview,1,NULL,PETSC_FUNCTION));
839566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer,&kdm->ops->ijacobianload,1,NULL,PETSC_FUNCTION));
84ad6bc421SBarry Smith   if (kdm->ops->ijacobianload) {
85800f99ffSJeremy L Thompson     void *ctx;
86800f99ffSJeremy L Thompson 
87800f99ffSJeremy L Thompson     PetscCall(PetscContainerGetPointer(kdm->ijacobianctxcontainer,&ctx));
88800f99ffSJeremy L Thompson     PetscCall((*kdm->ops->ijacobianload)(&ctx,viewer));
89ad6bc421SBarry Smith   }
902d53ad75SBarry Smith   PetscFunctionReturn(0);
912d53ad75SBarry Smith }
922d53ad75SBarry Smith 
932d53ad75SBarry Smith PetscErrorCode DMTSView(DMTS kdm,PetscViewer viewer)
942d53ad75SBarry Smith {
952d53ad75SBarry Smith   PetscBool      isascii,isbinary;
962d53ad75SBarry Smith 
972d53ad75SBarry Smith   PetscFunctionBegin;
989566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii));
999566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary));
1002d53ad75SBarry Smith   if (isascii) {
101c7a10e08SBarry Smith #if defined(PETSC_SERIALIZE_FUNCTIONS)
1022d53ad75SBarry Smith     const char *fname;
1032d53ad75SBarry Smith 
1049566063dSJacob Faibussowitsch     PetscCall(PetscFPTFind(kdm->ops->ifunction,&fname));
1052d53ad75SBarry Smith     if (fname) {
1069566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"  IFunction used by TS: %s\n",fname));
1072d53ad75SBarry Smith     }
1089566063dSJacob Faibussowitsch     PetscCall(PetscFPTFind(kdm->ops->ijacobian,&fname));
1092d53ad75SBarry Smith     if (fname) {
1109566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"  IJacobian function used by TS: %s\n",fname));
1112d53ad75SBarry Smith     }
112c7a10e08SBarry Smith #endif
1132d53ad75SBarry Smith   } else if (isbinary) {
1143964eb88SJed Brown     struct {
1153964eb88SJed Brown       TSIFunction ifunction;
1169200755eSBarry Smith     } funcstruct;
1179200755eSBarry Smith     struct {
1183964eb88SJed Brown       PetscErrorCode (*ifunctionview)(void*,PetscViewer);
1199200755eSBarry Smith     } funcviewstruct;
1209200755eSBarry Smith     struct {
1213964eb88SJed Brown       PetscErrorCode (*ifunctionload)(void**,PetscViewer);
1229200755eSBarry Smith     } funcloadstruct;
1233964eb88SJed Brown     struct {
1243964eb88SJed Brown       TSIJacobian ijacobian;
1259200755eSBarry Smith     } jacstruct;
1269200755eSBarry Smith     struct {
1273964eb88SJed Brown       PetscErrorCode (*ijacobianview)(void*,PetscViewer);
1289200755eSBarry Smith     } jacviewstruct;
1299200755eSBarry Smith     struct {
1303964eb88SJed Brown       PetscErrorCode (*ijacobianload)(void**,PetscViewer);
1319200755eSBarry Smith     } jacloadstruct;
1323964eb88SJed Brown 
1339200755eSBarry Smith     funcstruct.ifunction         = kdm->ops->ifunction;
1349200755eSBarry Smith     funcviewstruct.ifunctionview = kdm->ops->ifunctionview;
1359200755eSBarry Smith     funcloadstruct.ifunctionload = kdm->ops->ifunctionload;
1369566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWrite(viewer,&funcstruct,1,PETSC_FUNCTION));
1379566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWrite(viewer,&funcviewstruct,1,PETSC_FUNCTION));
1389566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWrite(viewer,&funcloadstruct,1,PETSC_FUNCTION));
139800f99ffSJeremy L Thompson     if (kdm->ops->ifunctionview) {
140800f99ffSJeremy L Thompson       void *ctx;
141800f99ffSJeremy L Thompson 
142800f99ffSJeremy L Thompson       PetscCall(PetscContainerGetPointer(kdm->ifunctionctxcontainer,&ctx));
143800f99ffSJeremy L Thompson       PetscCall((*kdm->ops->ifunctionview)(ctx,viewer));
144800f99ffSJeremy L Thompson     }
1459200755eSBarry Smith     jacstruct.ijacobian = kdm->ops->ijacobian;
1469200755eSBarry Smith     jacviewstruct.ijacobianview = kdm->ops->ijacobianview;
1479200755eSBarry Smith     jacloadstruct.ijacobianload = kdm->ops->ijacobianload;
1489566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWrite(viewer,&jacstruct,1,PETSC_FUNCTION));
1499566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWrite(viewer,&jacviewstruct,1,PETSC_FUNCTION));
1509566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWrite(viewer,&jacloadstruct,1,PETSC_FUNCTION));
151800f99ffSJeremy L Thompson     if (kdm->ops->ijacobianview) {
152800f99ffSJeremy L Thompson       void *ctx;
153800f99ffSJeremy L Thompson 
154800f99ffSJeremy L Thompson       PetscCall(PetscContainerGetPointer(kdm->ijacobianctxcontainer,&ctx));
155800f99ffSJeremy L Thompson       PetscCall((*kdm->ops->ijacobianview)(ctx,viewer));
156800f99ffSJeremy L Thompson     }
1572d53ad75SBarry Smith   }
1582d53ad75SBarry Smith   PetscFunctionReturn(0);
1592d53ad75SBarry Smith }
1602d53ad75SBarry Smith 
161d74926cbSBarry Smith static PetscErrorCode DMTSCreate(MPI_Comm comm,DMTS *kdm)
162d74926cbSBarry Smith {
163d74926cbSBarry Smith   PetscFunctionBegin;
1649566063dSJacob Faibussowitsch   PetscCall(TSInitializePackage());
1659566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(*kdm, DMTS_CLASSID, "DMTS", "DMTS", "DMTS", comm, DMTSDestroy, DMTSView));
166d74926cbSBarry Smith   PetscFunctionReturn(0);
167d74926cbSBarry Smith }
16824989b8cSPeter Brune 
1692a34c10cSBarry Smith /* Attaches the DMTS to the coarse level.
17024989b8cSPeter Brune  * Under what conditions should we copy versus duplicate?
17124989b8cSPeter Brune  */
172942e3340SBarry Smith static PetscErrorCode DMCoarsenHook_DMTS(DM dm,DM dmc,void *ctx)
17324989b8cSPeter Brune {
17424989b8cSPeter Brune   PetscFunctionBegin;
1759566063dSJacob Faibussowitsch   PetscCall(DMCopyDMTS(dm,dmc));
17624989b8cSPeter Brune   PetscFunctionReturn(0);
17724989b8cSPeter Brune }
17824989b8cSPeter Brune 
17924989b8cSPeter Brune /* This could restrict auxiliary information to the coarse level.
18024989b8cSPeter Brune  */
181942e3340SBarry Smith static PetscErrorCode DMRestrictHook_DMTS(DM dm,Mat Restrict,Vec rscale,Mat Inject,DM dmc,void *ctx)
18224989b8cSPeter Brune {
18324989b8cSPeter Brune   PetscFunctionBegin;
18424989b8cSPeter Brune   PetscFunctionReturn(0);
18524989b8cSPeter Brune }
18624989b8cSPeter Brune 
187258e1594SPeter Brune static PetscErrorCode DMSubDomainHook_DMTS(DM dm,DM subdm,void *ctx)
188258e1594SPeter Brune {
189258e1594SPeter Brune   PetscFunctionBegin;
1909566063dSJacob Faibussowitsch   PetscCall(DMCopyDMTS(dm,subdm));
191258e1594SPeter Brune   PetscFunctionReturn(0);
192258e1594SPeter Brune }
193258e1594SPeter Brune 
194258e1594SPeter Brune /* This could restrict auxiliary information to the coarse level.
195258e1594SPeter Brune  */
196258e1594SPeter Brune static PetscErrorCode DMSubDomainRestrictHook_DMTS(DM dm,VecScatter gscat,VecScatter lscat,DM subdm,void *ctx)
197258e1594SPeter Brune {
198258e1594SPeter Brune   PetscFunctionBegin;
199258e1594SPeter Brune   PetscFunctionReturn(0);
200258e1594SPeter Brune }
201258e1594SPeter Brune 
202d74926cbSBarry Smith /*@C
203d74926cbSBarry Smith    DMTSCopy - copies the information in a DMTS to another DMTS
204d74926cbSBarry Smith 
205d74926cbSBarry Smith    Not Collective
206d74926cbSBarry Smith 
2074165533cSJose E. Roman    Input Parameters:
208d74926cbSBarry Smith +  kdm - Original DMTS
209d74926cbSBarry Smith -  nkdm - DMTS to receive the data, should have been created with DMTSCreate()
210d74926cbSBarry Smith 
211d74926cbSBarry Smith    Level: developer
212d74926cbSBarry Smith 
213db781477SPatrick Sanan .seealso: `DMTSCreate()`, `DMTSDestroy()`
214d74926cbSBarry Smith @*/
215d74926cbSBarry Smith PetscErrorCode DMTSCopy(DMTS kdm,DMTS nkdm)
21624989b8cSPeter Brune {
21724989b8cSPeter Brune   PetscFunctionBegin;
218d74926cbSBarry Smith   PetscValidHeaderSpecific(kdm,DMTS_CLASSID,1);
219d74926cbSBarry Smith   PetscValidHeaderSpecific(nkdm,DMTS_CLASSID,2);
220d74926cbSBarry Smith   nkdm->ops->rhsfunction        = kdm->ops->rhsfunction;
221d74926cbSBarry Smith   nkdm->ops->rhsjacobian        = kdm->ops->rhsjacobian;
222d74926cbSBarry Smith   nkdm->ops->ifunction          = kdm->ops->ifunction;
223d74926cbSBarry Smith   nkdm->ops->ijacobian          = kdm->ops->ijacobian;
224efe9872eSLisandro Dalcin   nkdm->ops->i2function         = kdm->ops->i2function;
225efe9872eSLisandro Dalcin   nkdm->ops->i2jacobian         = kdm->ops->i2jacobian;
226d74926cbSBarry Smith   nkdm->ops->solution           = kdm->ops->solution;
227d74926cbSBarry Smith   nkdm->ops->destroy            = kdm->ops->destroy;
228d74926cbSBarry Smith   nkdm->ops->duplicate          = kdm->ops->duplicate;
229d74926cbSBarry Smith 
230d74926cbSBarry Smith   nkdm->solutionctx             = kdm->solutionctx;
231800f99ffSJeremy L Thompson   nkdm->rhsfunctionctxcontainer = kdm->rhsfunctionctxcontainer;
232800f99ffSJeremy L Thompson   nkdm->rhsjacobianctxcontainer = kdm->rhsjacobianctxcontainer;
233800f99ffSJeremy L Thompson   nkdm->ifunctionctxcontainer   = kdm->ifunctionctxcontainer;
234800f99ffSJeremy L Thompson   nkdm->ijacobianctxcontainer   = kdm->ijacobianctxcontainer;
235800f99ffSJeremy L Thompson   nkdm->i2functionctxcontainer  = kdm->i2functionctxcontainer;
236800f99ffSJeremy L Thompson   nkdm->i2jacobianctxcontainer  = kdm->i2jacobianctxcontainer;
237800f99ffSJeremy L Thompson   if (nkdm->rhsfunctionctxcontainer) PetscCall(PetscObjectCompose((PetscObject)nkdm,"rhs function ctx",(PetscObject)nkdm->rhsfunctionctxcontainer));
238800f99ffSJeremy L Thompson   if (nkdm->rhsjacobianctxcontainer) PetscCall(PetscObjectCompose((PetscObject)nkdm,"rhs jacobian ctx",(PetscObject)nkdm->rhsjacobianctxcontainer));
239800f99ffSJeremy L Thompson   if (nkdm->ifunctionctxcontainer) PetscCall(PetscObjectCompose((PetscObject)nkdm,"ifunction ctx",(PetscObject)nkdm->ifunctionctxcontainer));
240800f99ffSJeremy L Thompson   if (nkdm->ijacobianctxcontainer) PetscCall(PetscObjectCompose((PetscObject)nkdm,"ijacobian ctx",(PetscObject)nkdm->ijacobianctxcontainer));
241800f99ffSJeremy L Thompson   if (nkdm->i2functionctxcontainer) PetscCall(PetscObjectCompose((PetscObject)nkdm,"i2function ctx",(PetscObject)nkdm->i2functionctxcontainer));
242800f99ffSJeremy L Thompson   if (nkdm->i2jacobianctxcontainer) PetscCall(PetscObjectCompose((PetscObject)nkdm,"i2jacobian ctx",(PetscObject)nkdm->i2jacobianctxcontainer));
243d74926cbSBarry Smith 
244d74926cbSBarry Smith   nkdm->data = kdm->data;
245d74926cbSBarry Smith 
246d74926cbSBarry Smith   /*
247d74926cbSBarry Smith   nkdm->fortran_func_pointers[0] = kdm->fortran_func_pointers[0];
248d74926cbSBarry Smith   nkdm->fortran_func_pointers[1] = kdm->fortran_func_pointers[1];
249d74926cbSBarry Smith   nkdm->fortran_func_pointers[2] = kdm->fortran_func_pointers[2];
250d74926cbSBarry Smith   */
251d74926cbSBarry Smith 
252d74926cbSBarry Smith   /* implementation specific copy hooks */
2539566063dSJacob Faibussowitsch   if (kdm->ops->duplicate) PetscCall((*kdm->ops->duplicate)(kdm,nkdm));
25424989b8cSPeter Brune   PetscFunctionReturn(0);
25524989b8cSPeter Brune }
25624989b8cSPeter Brune 
25724989b8cSPeter Brune /*@C
258942e3340SBarry Smith    DMGetDMTS - get read-only private DMTS context from a DM
25924989b8cSPeter Brune 
26024989b8cSPeter Brune    Not Collective
26124989b8cSPeter Brune 
2624165533cSJose E. Roman    Input Parameter:
26324989b8cSPeter Brune .  dm - DM to be used with TS
26424989b8cSPeter Brune 
2654165533cSJose E. Roman    Output Parameter:
266942e3340SBarry Smith .  tsdm - private DMTS context
26724989b8cSPeter Brune 
26824989b8cSPeter Brune    Level: developer
26924989b8cSPeter Brune 
27024989b8cSPeter Brune    Notes:
271942e3340SBarry Smith    Use DMGetDMTSWrite() if write access is needed. The DMTSSetXXX API should be used wherever possible.
27224989b8cSPeter Brune 
273db781477SPatrick Sanan .seealso: `DMGetDMTSWrite()`
27424989b8cSPeter Brune @*/
275942e3340SBarry Smith PetscErrorCode DMGetDMTS(DM dm,DMTS *tsdm)
27624989b8cSPeter Brune {
27724989b8cSPeter Brune   PetscFunctionBegin;
27824989b8cSPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
2792a34c10cSBarry Smith   *tsdm = (DMTS) dm->dmts;
280d74926cbSBarry Smith   if (!*tsdm) {
2819566063dSJacob Faibussowitsch     PetscCall(PetscInfo(dm,"Creating new DMTS\n"));
2829566063dSJacob Faibussowitsch     PetscCall(DMTSCreate(PetscObjectComm((PetscObject)dm),tsdm));
2832a34c10cSBarry Smith     dm->dmts = (PetscObject) *tsdm;
2845c87d4f4SJunchao Zhang     (*tsdm)->originaldm = dm;
2859566063dSJacob Faibussowitsch     PetscCall(DMCoarsenHookAdd(dm,DMCoarsenHook_DMTS,DMRestrictHook_DMTS,NULL));
2869566063dSJacob Faibussowitsch     PetscCall(DMSubDomainHookAdd(dm,DMSubDomainHook_DMTS,DMSubDomainRestrictHook_DMTS,NULL));
28724989b8cSPeter Brune   }
28824989b8cSPeter Brune   PetscFunctionReturn(0);
28924989b8cSPeter Brune }
29024989b8cSPeter Brune 
29124989b8cSPeter Brune /*@C
292942e3340SBarry Smith    DMGetDMTSWrite - get write access to private DMTS context from a DM
29324989b8cSPeter Brune 
29424989b8cSPeter Brune    Not Collective
29524989b8cSPeter Brune 
2964165533cSJose E. Roman    Input Parameter:
29724989b8cSPeter Brune .  dm - DM to be used with TS
29824989b8cSPeter Brune 
2994165533cSJose E. Roman    Output Parameter:
300942e3340SBarry Smith .  tsdm - private DMTS context
30124989b8cSPeter Brune 
30224989b8cSPeter Brune    Level: developer
30324989b8cSPeter Brune 
304db781477SPatrick Sanan .seealso: `DMGetDMTS()`
30524989b8cSPeter Brune @*/
306942e3340SBarry Smith PetscErrorCode DMGetDMTSWrite(DM dm,DMTS *tsdm)
30724989b8cSPeter Brune {
308942e3340SBarry Smith   DMTS           sdm;
30924989b8cSPeter Brune 
31024989b8cSPeter Brune   PetscFunctionBegin;
31124989b8cSPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3129566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm,&sdm));
3133c633725SBarry Smith   PetscCheck(sdm->originaldm,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"DMTS has a NULL originaldm");
31424989b8cSPeter Brune   if (sdm->originaldm != dm) {  /* Copy on write */
3152a34c10cSBarry Smith     DMTS oldsdm = sdm;
3169566063dSJacob Faibussowitsch     PetscCall(PetscInfo(dm,"Copying DMTS due to write\n"));
3179566063dSJacob Faibussowitsch     PetscCall(DMTSCreate(PetscObjectComm((PetscObject)dm),&sdm));
3189566063dSJacob Faibussowitsch     PetscCall(DMTSCopy(oldsdm,sdm));
3199566063dSJacob Faibussowitsch     PetscCall(DMTSDestroy((DMTS*)&dm->dmts));
3202a34c10cSBarry Smith     dm->dmts = (PetscObject) sdm;
3215c87d4f4SJunchao Zhang     sdm->originaldm = dm;
32224989b8cSPeter Brune   }
32324989b8cSPeter Brune   *tsdm = sdm;
32424989b8cSPeter Brune   PetscFunctionReturn(0);
32524989b8cSPeter Brune }
32624989b8cSPeter Brune 
32724989b8cSPeter Brune /*@C
328942e3340SBarry Smith    DMCopyDMTS - copies a DM context to a new DM
32924989b8cSPeter Brune 
33024989b8cSPeter Brune    Logically Collective
33124989b8cSPeter Brune 
3324165533cSJose E. Roman    Input Parameters:
33324989b8cSPeter Brune +  dmsrc - DM to obtain context from
33424989b8cSPeter Brune -  dmdest - DM to add context to
33524989b8cSPeter Brune 
33624989b8cSPeter Brune    Level: developer
33724989b8cSPeter Brune 
33824989b8cSPeter Brune    Note:
33924989b8cSPeter Brune    The context is copied by reference. This function does not ensure that a context exists.
34024989b8cSPeter Brune 
341db781477SPatrick Sanan .seealso: `DMGetDMTS()`, `TSSetDM()`
34224989b8cSPeter Brune @*/
343942e3340SBarry Smith PetscErrorCode DMCopyDMTS(DM dmsrc,DM dmdest)
34424989b8cSPeter Brune {
34524989b8cSPeter Brune   PetscFunctionBegin;
34624989b8cSPeter Brune   PetscValidHeaderSpecific(dmsrc,DM_CLASSID,1);
34724989b8cSPeter Brune   PetscValidHeaderSpecific(dmdest,DM_CLASSID,2);
3489566063dSJacob Faibussowitsch   PetscCall(DMTSDestroy((DMTS*)&dmdest->dmts));
3492a34c10cSBarry Smith   dmdest->dmts = dmsrc->dmts;
3509566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference(dmdest->dmts));
3519566063dSJacob Faibussowitsch   PetscCall(DMCoarsenHookAdd(dmdest,DMCoarsenHook_DMTS,DMRestrictHook_DMTS,NULL));
3529566063dSJacob Faibussowitsch   PetscCall(DMSubDomainHookAdd(dmdest,DMSubDomainHook_DMTS,DMSubDomainRestrictHook_DMTS,NULL));
35324989b8cSPeter Brune   PetscFunctionReturn(0);
35424989b8cSPeter Brune }
35524989b8cSPeter Brune 
35624989b8cSPeter Brune /*@C
35724989b8cSPeter Brune    DMTSSetIFunction - set TS implicit function evaluation function
35824989b8cSPeter Brune 
35924989b8cSPeter Brune    Not Collective
36024989b8cSPeter Brune 
3614165533cSJose E. Roman    Input Parameters:
36224989b8cSPeter Brune +  dm - DM to be used with TS
363a96d6ef6SBarry Smith .  func - function evaluating f(t,u,u_t)
36424989b8cSPeter Brune -  ctx - context for residual evaluation
36524989b8cSPeter Brune 
366a96d6ef6SBarry Smith    Calling sequence of func:
367a96d6ef6SBarry Smith $     PetscErrorCode func(TS ts,PetscReal t,Vec u,Vec u_t,Vec F,ctx);
368a96d6ef6SBarry Smith 
369a96d6ef6SBarry Smith +  t   - time at step/stage being solved
370a96d6ef6SBarry Smith .  u   - state vector
371a96d6ef6SBarry Smith .  u_t - time derivative of state vector
372a96d6ef6SBarry Smith .  F   - function vector
373a96d6ef6SBarry Smith -  ctx - [optional] user-defined context for matrix evaluation routine
374a96d6ef6SBarry Smith 
37524989b8cSPeter Brune    Level: advanced
37624989b8cSPeter Brune 
37724989b8cSPeter Brune    Note:
37824989b8cSPeter Brune    TSSetFunction() is normally used, but it calls this function internally because the user context is actually
37924989b8cSPeter Brune    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
38024989b8cSPeter Brune    not. If DM took a more central role at some later date, this could become the primary method of setting the residual.
38124989b8cSPeter Brune 
382db781477SPatrick Sanan .seealso: `DMTSSetContext()`, `TSSetIFunction()`, `DMTSSetJacobian()`
38324989b8cSPeter Brune @*/
38424989b8cSPeter Brune PetscErrorCode DMTSSetIFunction(DM dm,TSIFunction func,void *ctx)
38524989b8cSPeter Brune {
386942e3340SBarry Smith   DMTS           tsdm;
38724989b8cSPeter Brune 
38824989b8cSPeter Brune   PetscFunctionBegin;
38924989b8cSPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
3909566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm,&tsdm));
391d74926cbSBarry Smith   if (func) tsdm->ops->ifunction = func;
392800f99ffSJeremy L Thompson   if (ctx) {
393800f99ffSJeremy L Thompson     PetscContainer ctxcontainer;
394800f99ffSJeremy L Thompson     PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)tsdm),&ctxcontainer));
395800f99ffSJeremy L Thompson     PetscCall(PetscContainerSetPointer(ctxcontainer,ctx));
396800f99ffSJeremy L Thompson     PetscCall(PetscObjectCompose((PetscObject)tsdm,"ifunction ctx",(PetscObject)ctxcontainer));
397800f99ffSJeremy L Thompson     tsdm->ifunctionctxcontainer = ctxcontainer;
398800f99ffSJeremy L Thompson     PetscCall(PetscContainerDestroy(&ctxcontainer));
399800f99ffSJeremy L Thompson   }
400800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
401800f99ffSJeremy L Thompson }
402800f99ffSJeremy L Thompson 
403800f99ffSJeremy L Thompson /*@C
404*5cb80ecdSBarry Smith    DMTSSetIFunctionContextDestroy - set `TS` implicit evaluation context destroy function
405800f99ffSJeremy L Thompson 
406800f99ffSJeremy L Thompson    Not Collective
407800f99ffSJeremy L Thompson 
408800f99ffSJeremy L Thompson    Input Parameters:
409*5cb80ecdSBarry Smith +  dm - `DM` to be used with `TS`
410*5cb80ecdSBarry Smith -  f - implicit evaluation context destroy function
411800f99ffSJeremy L Thompson 
412800f99ffSJeremy L Thompson    Level: advanced
413800f99ffSJeremy L Thompson 
414800f99ffSJeremy L Thompson    Note:
415*5cb80ecdSBarry Smith    `TSSetFunctionContextDestroy()` is normally used, but it calls this function internally because the user context is actually
416*5cb80ecdSBarry Smith    associated with the `DM`.  This makes the interface consistent regardless of whether the user interacts with a `DM` or
417*5cb80ecdSBarry Smith    not.
418*5cb80ecdSBarry Smith 
419*5cb80ecdSBarry Smith    Developer Note:
420*5cb80ecdSBarry Smith    If `DM` took a more central role at some later date, this could become the primary method of setting the residual.
421800f99ffSJeremy L Thompson 
422800f99ffSJeremy L Thompson .seealso: `TSSetFunctionContextDestroy()`, `DMTSSetIFunction()`, `TSSetIFunction()`
423800f99ffSJeremy L Thompson @*/
424800f99ffSJeremy L Thompson PetscErrorCode DMTSSetIFunctionContextDestroy(DM dm,PetscErrorCode (*f)(void*))
425800f99ffSJeremy L Thompson {
426800f99ffSJeremy L Thompson   DMTS           tsdm;
427800f99ffSJeremy L Thompson 
428800f99ffSJeremy L Thompson   PetscFunctionBegin;
429800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
430800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm,&tsdm));
431800f99ffSJeremy L Thompson   if (tsdm->ifunctionctxcontainer)PetscCall(PetscContainerSetUserDestroy(tsdm->ifunctionctxcontainer,f));
432800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
433800f99ffSJeremy L Thompson }
434800f99ffSJeremy L Thompson 
435800f99ffSJeremy L Thompson PetscErrorCode DMTSUnsetIFunctionContext_Internal(DM dm)
436800f99ffSJeremy L Thompson {
437800f99ffSJeremy L Thompson   DMTS           tsdm;
438800f99ffSJeremy L Thompson 
439800f99ffSJeremy L Thompson   PetscFunctionBegin;
440800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
441800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm,&tsdm));
442800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetIFunctionContext_DMTS(tsdm));
44324989b8cSPeter Brune   PetscFunctionReturn(0);
44424989b8cSPeter Brune }
44524989b8cSPeter Brune 
44624989b8cSPeter Brune /*@C
44724989b8cSPeter Brune    DMTSGetIFunction - get TS implicit residual evaluation function
44824989b8cSPeter Brune 
44924989b8cSPeter Brune    Not Collective
45024989b8cSPeter Brune 
4514165533cSJose E. Roman    Input Parameter:
45224989b8cSPeter Brune .  dm - DM to be used with TS
45324989b8cSPeter Brune 
4544165533cSJose E. Roman    Output Parameters:
45524989b8cSPeter Brune +  func - function evaluation function, see TSSetIFunction() for calling sequence
45624989b8cSPeter Brune -  ctx - context for residual evaluation
45724989b8cSPeter Brune 
45824989b8cSPeter Brune    Level: advanced
45924989b8cSPeter Brune 
46024989b8cSPeter Brune    Note:
46124989b8cSPeter Brune    TSGetFunction() is normally used, but it calls this function internally because the user context is actually
46224989b8cSPeter Brune    associated with the DM.
46324989b8cSPeter Brune 
464db781477SPatrick Sanan .seealso: `DMTSSetContext()`, `DMTSSetFunction()`, `TSSetFunction()`
46524989b8cSPeter Brune @*/
46624989b8cSPeter Brune PetscErrorCode DMTSGetIFunction(DM dm,TSIFunction *func,void **ctx)
46724989b8cSPeter Brune {
468942e3340SBarry Smith   DMTS           tsdm;
46924989b8cSPeter Brune 
47024989b8cSPeter Brune   PetscFunctionBegin;
47124989b8cSPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
4729566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm,&tsdm));
473d74926cbSBarry Smith   if (func) *func = tsdm->ops->ifunction;
474800f99ffSJeremy L Thompson   if (ctx) {
475800f99ffSJeremy L Thompson     if (tsdm->ifunctionctxcontainer) PetscCall(PetscContainerGetPointer(tsdm->ifunctionctxcontainer,ctx));
476800f99ffSJeremy L Thompson     else *ctx = NULL;
477800f99ffSJeremy L Thompson   }
47824989b8cSPeter Brune   PetscFunctionReturn(0);
47924989b8cSPeter Brune }
48024989b8cSPeter Brune 
481efe9872eSLisandro Dalcin /*@C
482efe9872eSLisandro Dalcin    DMTSSetI2Function - set TS implicit function evaluation function for 2nd order systems
483efe9872eSLisandro Dalcin 
484efe9872eSLisandro Dalcin    Not Collective
485efe9872eSLisandro Dalcin 
4864165533cSJose E. Roman    Input Parameters:
487efe9872eSLisandro Dalcin +  dm - DM to be used with TS
488a96d6ef6SBarry Smith .  fun - function evaluation routine
489efe9872eSLisandro Dalcin -  ctx - context for residual evaluation
490efe9872eSLisandro Dalcin 
491a96d6ef6SBarry Smith    Calling sequence of fun:
492a96d6ef6SBarry Smith $     PetscErrorCode fun(TS ts,PetscReal t,Vec U,Vec U_t,Vec U_tt,Vec F,ctx);
493a96d6ef6SBarry Smith 
494a96d6ef6SBarry Smith +  t    - time at step/stage being solved
495a96d6ef6SBarry Smith .  U    - state vector
496a96d6ef6SBarry Smith .  U_t  - time derivative of state vector
497a96d6ef6SBarry Smith .  U_tt - second time derivative of state vector
498a96d6ef6SBarry Smith .  F    - function vector
499a96d6ef6SBarry Smith -  ctx  - [optional] user-defined context for matrix evaluation routine (may be NULL)
500a96d6ef6SBarry Smith 
501efe9872eSLisandro Dalcin    Level: advanced
502efe9872eSLisandro Dalcin 
503efe9872eSLisandro Dalcin    Note:
504efe9872eSLisandro Dalcin    TSSetI2Function() is normally used, but it calls this function internally because the user context is actually
505efe9872eSLisandro Dalcin    associated with the DM.
506efe9872eSLisandro Dalcin 
507db781477SPatrick Sanan .seealso: `TSSetI2Function()`
508efe9872eSLisandro Dalcin @*/
509efe9872eSLisandro Dalcin PetscErrorCode DMTSSetI2Function(DM dm,TSI2Function fun,void *ctx)
510efe9872eSLisandro Dalcin {
511efe9872eSLisandro Dalcin   DMTS           tsdm;
512efe9872eSLisandro Dalcin 
513efe9872eSLisandro Dalcin   PetscFunctionBegin;
514efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5159566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm,&tsdm));
516efe9872eSLisandro Dalcin   if (fun) tsdm->ops->i2function = fun;
517800f99ffSJeremy L Thompson   if (ctx) {
518800f99ffSJeremy L Thompson     PetscContainer ctxcontainer;
519800f99ffSJeremy L Thompson     PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)tsdm),&ctxcontainer));
520800f99ffSJeremy L Thompson     PetscCall(PetscContainerSetPointer(ctxcontainer,ctx));
521800f99ffSJeremy L Thompson     PetscCall(PetscObjectCompose((PetscObject)tsdm,"i2function ctx",(PetscObject)ctxcontainer));
522800f99ffSJeremy L Thompson     tsdm->i2functionctxcontainer = ctxcontainer;
523800f99ffSJeremy L Thompson     PetscCall(PetscContainerDestroy(&ctxcontainer));
524800f99ffSJeremy L Thompson   }
525800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
526800f99ffSJeremy L Thompson }
527800f99ffSJeremy L Thompson 
528800f99ffSJeremy L Thompson /*@C
529*5cb80ecdSBarry Smith    DMTSSetI2FunctionContextDestroy - set `TS` implicit evaluation for 2nd order systems context destroy
530800f99ffSJeremy L Thompson 
531800f99ffSJeremy L Thompson    Not Collective
532800f99ffSJeremy L Thompson 
533800f99ffSJeremy L Thompson    Input Parameters:
534*5cb80ecdSBarry Smith +  dm - `DM` to be used with `TS`
535*5cb80ecdSBarry Smith -  f - implicit evaluation context destroy function
536800f99ffSJeremy L Thompson 
537800f99ffSJeremy L Thompson    Level: advanced
538800f99ffSJeremy L Thompson 
539800f99ffSJeremy L Thompson    Note:
540*5cb80ecdSBarry Smith    `TSSetI2FunctionContextDestroy()` is normally used, but it calls this function internally because the user context is actually
541*5cb80ecdSBarry Smith    associated with the `DM`.
542800f99ffSJeremy L Thompson 
543800f99ffSJeremy L Thompson .seealso: `TSSetI2FunctionContextDestroy()`, `DMTSSetI2Function()`, `TSSetI2Function()`
544800f99ffSJeremy L Thompson @*/
545800f99ffSJeremy L Thompson PetscErrorCode DMTSSetI2FunctionContextDestroy(DM dm,PetscErrorCode (*f)(void*))
546800f99ffSJeremy L Thompson {
547800f99ffSJeremy L Thompson   DMTS           tsdm;
548800f99ffSJeremy L Thompson 
549800f99ffSJeremy L Thompson   PetscFunctionBegin;
550800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
551800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm,&tsdm));
552800f99ffSJeremy L Thompson   if (tsdm->i2functionctxcontainer) PetscCall(PetscContainerSetUserDestroy(tsdm->i2functionctxcontainer,f));
553800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
554800f99ffSJeremy L Thompson }
555800f99ffSJeremy L Thompson 
556800f99ffSJeremy L Thompson PetscErrorCode DMTSUnsetI2FunctionContext_Internal(DM dm)
557800f99ffSJeremy L Thompson {
558800f99ffSJeremy L Thompson   DMTS           tsdm;
559800f99ffSJeremy L Thompson 
560800f99ffSJeremy L Thompson   PetscFunctionBegin;
561800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
562800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm,&tsdm));
563800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetI2FunctionContext_DMTS(tsdm));
564efe9872eSLisandro Dalcin   PetscFunctionReturn(0);
565efe9872eSLisandro Dalcin }
566efe9872eSLisandro Dalcin 
567efe9872eSLisandro Dalcin /*@C
568efe9872eSLisandro Dalcin    DMTSGetI2Function - get TS implicit residual evaluation function for 2nd order systems
569efe9872eSLisandro Dalcin 
570efe9872eSLisandro Dalcin    Not Collective
571efe9872eSLisandro Dalcin 
5724165533cSJose E. Roman    Input Parameter:
573efe9872eSLisandro Dalcin .  dm - DM to be used with TS
574efe9872eSLisandro Dalcin 
5754165533cSJose E. Roman    Output Parameters:
576efe9872eSLisandro Dalcin +  fun - function evaluation function, see TSSetI2Function() for calling sequence
577efe9872eSLisandro Dalcin -  ctx - context for residual evaluation
578efe9872eSLisandro Dalcin 
579efe9872eSLisandro Dalcin    Level: advanced
580efe9872eSLisandro Dalcin 
581efe9872eSLisandro Dalcin    Note:
582efe9872eSLisandro Dalcin    TSGetI2Function() is normally used, but it calls this function internally because the user context is actually
583efe9872eSLisandro Dalcin    associated with the DM.
584efe9872eSLisandro Dalcin 
585c2e3fba1SPatrick Sanan .seealso: `DMTSSetI2Function()`, `TSGetI2Function()`
586efe9872eSLisandro Dalcin @*/
587efe9872eSLisandro Dalcin PetscErrorCode DMTSGetI2Function(DM dm,TSI2Function *fun,void **ctx)
588efe9872eSLisandro Dalcin {
589efe9872eSLisandro Dalcin   DMTS           tsdm;
590efe9872eSLisandro Dalcin 
591efe9872eSLisandro Dalcin   PetscFunctionBegin;
592efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
5939566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm,&tsdm));
594efe9872eSLisandro Dalcin   if (fun) *fun = tsdm->ops->i2function;
595800f99ffSJeremy L Thompson   if (ctx) {
596800f99ffSJeremy L Thompson     if (tsdm->i2functionctxcontainer) PetscCall(PetscContainerGetPointer(tsdm->i2functionctxcontainer,ctx));
597800f99ffSJeremy L Thompson     else *ctx = NULL;
598800f99ffSJeremy L Thompson   }
599efe9872eSLisandro Dalcin   PetscFunctionReturn(0);
600efe9872eSLisandro Dalcin }
601efe9872eSLisandro Dalcin 
602efe9872eSLisandro Dalcin /*@C
603efe9872eSLisandro Dalcin    DMTSSetI2Jacobian - set TS implicit Jacobian evaluation function for 2nd order systems
604efe9872eSLisandro Dalcin 
605efe9872eSLisandro Dalcin    Not Collective
606efe9872eSLisandro Dalcin 
6074165533cSJose E. Roman    Input Parameters:
608efe9872eSLisandro Dalcin +  dm - DM to be used with TS
609a96d6ef6SBarry Smith .  fun - Jacobian evaluation routine
610efe9872eSLisandro Dalcin -  ctx - context for Jacobian evaluation
611efe9872eSLisandro Dalcin 
612a96d6ef6SBarry Smith    Calling sequence of jac:
613a96d6ef6SBarry 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);
614a96d6ef6SBarry Smith 
615a96d6ef6SBarry Smith +  t    - time at step/stage being solved
616a96d6ef6SBarry Smith .  U    - state vector
617a96d6ef6SBarry Smith .  U_t  - time derivative of state vector
618a96d6ef6SBarry Smith .  U_tt - second time derivative of state vector
619a96d6ef6SBarry Smith .  v    - shift for U_t
620a96d6ef6SBarry Smith .  a    - shift for U_tt
621a96d6ef6SBarry 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
622a96d6ef6SBarry Smith .  P    - preconditioning matrix for J, may be same as J
623a96d6ef6SBarry Smith -  ctx  - [optional] user-defined context for matrix evaluation routine
624a96d6ef6SBarry Smith 
625efe9872eSLisandro Dalcin    Level: advanced
626efe9872eSLisandro Dalcin 
627efe9872eSLisandro Dalcin    Note:
628efe9872eSLisandro Dalcin    TSSetI2Jacobian() is normally used, but it calls this function internally because the user context is actually
629efe9872eSLisandro Dalcin    associated with the DM.
630efe9872eSLisandro Dalcin 
631db781477SPatrick Sanan .seealso: `TSSetI2Jacobian()`
632efe9872eSLisandro Dalcin @*/
633efe9872eSLisandro Dalcin PetscErrorCode DMTSSetI2Jacobian(DM dm,TSI2Jacobian jac,void *ctx)
634efe9872eSLisandro Dalcin {
635efe9872eSLisandro Dalcin   DMTS           tsdm;
636efe9872eSLisandro Dalcin 
637efe9872eSLisandro Dalcin   PetscFunctionBegin;
638efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
6399566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm,&tsdm));
640efe9872eSLisandro Dalcin   if (jac) tsdm->ops->i2jacobian = jac;
641800f99ffSJeremy L Thompson   if (ctx) {
642800f99ffSJeremy L Thompson     PetscContainer ctxcontainer;
643800f99ffSJeremy L Thompson     PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)tsdm),&ctxcontainer));
644800f99ffSJeremy L Thompson     PetscCall(PetscContainerSetPointer(ctxcontainer,ctx));
645800f99ffSJeremy L Thompson     PetscCall(PetscObjectCompose((PetscObject)tsdm,"i2jacobian ctx",(PetscObject)ctxcontainer));
646800f99ffSJeremy L Thompson     tsdm->i2jacobianctxcontainer = ctxcontainer;
647800f99ffSJeremy L Thompson     PetscCall(PetscContainerDestroy(&ctxcontainer));
648800f99ffSJeremy L Thompson   }
649800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
650800f99ffSJeremy L Thompson }
651800f99ffSJeremy L Thompson 
652800f99ffSJeremy L Thompson /*@C
653*5cb80ecdSBarry Smith    DMTSSetI2JacobianContextDestroy - set `TS` implicit Jacobian evaluation for 2nd order systems context destroy function
654800f99ffSJeremy L Thompson 
655800f99ffSJeremy L Thompson    Not Collective
656800f99ffSJeremy L Thompson 
657800f99ffSJeremy L Thompson    Input Parameters:
658*5cb80ecdSBarry Smith +  dm - `DM` to be used with `TS`
659*5cb80ecdSBarry Smith -  f - implicit Jacobian evaluation context destroy function
660800f99ffSJeremy L Thompson 
661800f99ffSJeremy L Thompson .seealso: `TSSetI2JacobianContextDestroy()`, `DMTSSetI2Jacobian()`, `TSSetI2Jacobian()`
662800f99ffSJeremy L Thompson @*/
663800f99ffSJeremy L Thompson PetscErrorCode DMTSSetI2JacobianContextDestroy(DM dm,PetscErrorCode (*f)(void*))
664800f99ffSJeremy L Thompson {
665800f99ffSJeremy L Thompson   DMTS           tsdm;
666800f99ffSJeremy L Thompson 
667800f99ffSJeremy L Thompson   PetscFunctionBegin;
668800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
669800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm,&tsdm));
670800f99ffSJeremy L Thompson   if (tsdm->i2jacobianctxcontainer) PetscCall(PetscContainerSetUserDestroy(tsdm->i2jacobianctxcontainer,f));
671800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
672800f99ffSJeremy L Thompson }
673800f99ffSJeremy L Thompson 
674800f99ffSJeremy L Thompson PetscErrorCode DMTSUnsetI2JacobianContext_Internal(DM dm)
675800f99ffSJeremy L Thompson {
676800f99ffSJeremy L Thompson   DMTS           tsdm;
677800f99ffSJeremy L Thompson 
678800f99ffSJeremy L Thompson   PetscFunctionBegin;
679800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
680800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm,&tsdm));
681800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetI2JacobianContext_DMTS(tsdm));
682efe9872eSLisandro Dalcin   PetscFunctionReturn(0);
683efe9872eSLisandro Dalcin }
684efe9872eSLisandro Dalcin 
685efe9872eSLisandro Dalcin /*@C
686efe9872eSLisandro Dalcin    DMTSGetI2Jacobian - get TS implicit Jacobian evaluation function for 2nd order systems
687efe9872eSLisandro Dalcin 
688efe9872eSLisandro Dalcin    Not Collective
689efe9872eSLisandro Dalcin 
6904165533cSJose E. Roman    Input Parameter:
691efe9872eSLisandro Dalcin .  dm - DM to be used with TS
692efe9872eSLisandro Dalcin 
6934165533cSJose E. Roman    Output Parameters:
694efe9872eSLisandro Dalcin +  jac - Jacobian evaluation function, see TSSetI2Jacobian() for calling sequence
695efe9872eSLisandro Dalcin -  ctx - context for Jacobian evaluation
696efe9872eSLisandro Dalcin 
697efe9872eSLisandro Dalcin    Level: advanced
698efe9872eSLisandro Dalcin 
699efe9872eSLisandro Dalcin    Note:
700efe9872eSLisandro Dalcin    TSGetI2Jacobian() is normally used, but it calls this function internally because the user context is actually
701efe9872eSLisandro Dalcin    associated with the DM.
702efe9872eSLisandro Dalcin 
703c2e3fba1SPatrick Sanan .seealso: `DMTSSetI2Jacobian()`, `TSGetI2Jacobian()`
704efe9872eSLisandro Dalcin @*/
705efe9872eSLisandro Dalcin PetscErrorCode DMTSGetI2Jacobian(DM dm,TSI2Jacobian *jac,void **ctx)
706efe9872eSLisandro Dalcin {
707efe9872eSLisandro Dalcin   DMTS           tsdm;
708efe9872eSLisandro Dalcin 
709efe9872eSLisandro Dalcin   PetscFunctionBegin;
710efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
7119566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm,&tsdm));
712efe9872eSLisandro Dalcin   if (jac) *jac = tsdm->ops->i2jacobian;
713800f99ffSJeremy L Thompson   if (ctx) {
714800f99ffSJeremy L Thompson     if (tsdm->i2jacobianctxcontainer) PetscCall(PetscContainerGetPointer(tsdm->i2jacobianctxcontainer,ctx));
715800f99ffSJeremy L Thompson     else *ctx = NULL;
716800f99ffSJeremy L Thompson   }
717efe9872eSLisandro Dalcin   PetscFunctionReturn(0);
718efe9872eSLisandro Dalcin }
71924989b8cSPeter Brune 
72024989b8cSPeter Brune /*@C
72124989b8cSPeter Brune    DMTSSetRHSFunction - set TS explicit residual evaluation function
72224989b8cSPeter Brune 
72324989b8cSPeter Brune    Not Collective
72424989b8cSPeter Brune 
7254165533cSJose E. Roman    Input Parameters:
72624989b8cSPeter Brune +  dm - DM to be used with TS
727a96d6ef6SBarry Smith .  func - RHS function evaluation routine
72824989b8cSPeter Brune -  ctx - context for residual evaluation
72924989b8cSPeter Brune 
730a96d6ef6SBarry Smith     Calling sequence of func:
731a96d6ef6SBarry Smith $     PetscErrorCode func(TS ts,PetscReal t,Vec u,Vec F,void *ctx);
732a96d6ef6SBarry Smith 
733a96d6ef6SBarry Smith +   ts - timestep context
734a96d6ef6SBarry Smith .   t - current timestep
735a96d6ef6SBarry Smith .   u - input vector
736a96d6ef6SBarry Smith .   F - function vector
737a96d6ef6SBarry Smith -   ctx - [optional] user-defined function context
738a96d6ef6SBarry Smith 
73924989b8cSPeter Brune    Level: advanced
74024989b8cSPeter Brune 
74124989b8cSPeter Brune    Note:
742800f99ffSJeremy L Thompson    TSSetRHSFunction() is normally used, but it calls this function internally because the user context is actually
74324989b8cSPeter Brune    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
74424989b8cSPeter Brune    not. If DM took a more central role at some later date, this could become the primary method of setting the residual.
74524989b8cSPeter Brune 
746db781477SPatrick Sanan .seealso: `DMTSSetContext()`, `TSSetRHSFunction()`, `DMTSSetJacobian()`
74724989b8cSPeter Brune @*/
74824989b8cSPeter Brune PetscErrorCode DMTSSetRHSFunction(DM dm,TSRHSFunction func,void *ctx)
74924989b8cSPeter Brune {
750942e3340SBarry Smith   DMTS           tsdm;
75124989b8cSPeter Brune 
75224989b8cSPeter Brune   PetscFunctionBegin;
75324989b8cSPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
7549566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm,&tsdm));
755d74926cbSBarry Smith   if (func) tsdm->ops->rhsfunction = func;
756800f99ffSJeremy L Thompson   if (ctx) {
757800f99ffSJeremy L Thompson     PetscContainer ctxcontainer;
758800f99ffSJeremy L Thompson     PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)tsdm),&ctxcontainer));
759800f99ffSJeremy L Thompson     PetscCall(PetscContainerSetPointer(ctxcontainer,ctx));
760800f99ffSJeremy L Thompson     PetscCall(PetscObjectCompose((PetscObject)tsdm,"rhs function ctx",(PetscObject)ctxcontainer));
761800f99ffSJeremy L Thompson     tsdm->rhsfunctionctxcontainer = ctxcontainer;
762800f99ffSJeremy L Thompson     PetscCall(PetscContainerDestroy(&ctxcontainer));
763800f99ffSJeremy L Thompson   }
764800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
765800f99ffSJeremy L Thompson }
766800f99ffSJeremy L Thompson 
767800f99ffSJeremy L Thompson /*@C
768*5cb80ecdSBarry Smith    DMTSSetRHSFunctionContextDestroy - set `TS` explicit residual evaluation context destroy function
769800f99ffSJeremy L Thompson 
770800f99ffSJeremy L Thompson    Not Collective
771800f99ffSJeremy L Thompson 
772800f99ffSJeremy L Thompson    Input Parameters:
773*5cb80ecdSBarry Smith +  dm - `DM` to be used with `TS`
774*5cb80ecdSBarry Smith -  f - explicit evaluation context destroy function
775800f99ffSJeremy L Thompson 
776800f99ffSJeremy L Thompson    Level: advanced
777800f99ffSJeremy L Thompson 
778800f99ffSJeremy L Thompson    Note:
779*5cb80ecdSBarry Smith    `TSSetRHSFunctionContextDestroy()` is normally used, but it calls this function internally because the user context is actually
780*5cb80ecdSBarry Smith    associated with the `DM`.  This makes the interface consistent regardless of whether the user interacts with a `DM` or
781*5cb80ecdSBarry Smith    not.
782*5cb80ecdSBarry Smith 
783*5cb80ecdSBarry Smith    Developer Note:
784*5cb80ecdSBarry Smith    If `DM` took a more central role at some later date, this could become the primary method of setting the residual.
785800f99ffSJeremy L Thompson 
786800f99ffSJeremy L Thompson .seealso: `TSSetRHSFunctionContextDestroy()`, `DMTSSetRHSFunction()`, `TSSetRHSFunction()`
787800f99ffSJeremy L Thompson @*/
788800f99ffSJeremy L Thompson PetscErrorCode DMTSSetRHSFunctionContextDestroy(DM dm,PetscErrorCode (*f)(void*))
789800f99ffSJeremy L Thompson {
790800f99ffSJeremy L Thompson   DMTS           tsdm;
791800f99ffSJeremy L Thompson 
792800f99ffSJeremy L Thompson   PetscFunctionBegin;
793800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
794800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm,&tsdm));
795800f99ffSJeremy L Thompson   if (tsdm->rhsfunctionctxcontainer) PetscCall(PetscContainerSetUserDestroy(tsdm->rhsfunctionctxcontainer,f));
796800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
797800f99ffSJeremy L Thompson }
798800f99ffSJeremy L Thompson 
799800f99ffSJeremy L Thompson PetscErrorCode DMTSUnsetRHSFunctionContext_Internal(DM dm)
800800f99ffSJeremy L Thompson {
801800f99ffSJeremy L Thompson   DMTS           tsdm;
802800f99ffSJeremy L Thompson 
803800f99ffSJeremy L Thompson   PetscFunctionBegin;
804800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
805800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm,&tsdm));
806800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetRHSFunctionContext_DMTS(tsdm));
807800f99ffSJeremy L Thompson   tsdm->rhsfunctionctxcontainer = NULL;
80824989b8cSPeter Brune   PetscFunctionReturn(0);
80924989b8cSPeter Brune }
81024989b8cSPeter Brune 
811ef20d060SBarry Smith /*@C
812e3c11fc1SJed Brown    DMTSSetTransientVariable - sets function to transform from state to transient variables
813e3c11fc1SJed Brown 
814e3c11fc1SJed Brown    Logically Collective
815e3c11fc1SJed Brown 
8164165533cSJose E. Roman    Input Parameters:
817e3c11fc1SJed Brown +  dm - DM to be used with TS
818a96d6ef6SBarry Smith .  tvar - a function that transforms to transient variables
819e3c11fc1SJed Brown -  ctx - a context for tvar
820e3c11fc1SJed Brown 
821a96d6ef6SBarry Smith     Calling sequence of tvar:
822a96d6ef6SBarry Smith $     PetscErrorCode tvar(TS ts,Vec p,Vec c,void *ctx);
823a96d6ef6SBarry Smith 
824a96d6ef6SBarry Smith +   ts - timestep context
8256aad120cSJose E. Roman .   p - input vector (primitive form)
826a96d6ef6SBarry Smith .   c - output vector, transient variables (conservative form)
827a96d6ef6SBarry Smith -   ctx - [optional] user-defined function context
828a96d6ef6SBarry Smith 
829e3c11fc1SJed Brown    Level: advanced
830e3c11fc1SJed Brown 
831e3c11fc1SJed Brown    Notes:
832e3c11fc1SJed Brown    This is typically used to transform from primitive to conservative variables so that a time integrator (e.g., TSBDF)
833e3c11fc1SJed Brown    can be conservative.  In this context, primitive variables P are used to model the state (e.g., because they lead to
834e3c11fc1SJed Brown    well-conditioned formulations even in limiting cases such as low-Mach or zero porosity).  The transient variable is
835e3c11fc1SJed Brown    C(P), specified by calling this function.  An IFunction thus receives arguments (P, Cdot) and the IJacobian must be
836e3c11fc1SJed Brown    evaluated via the chain rule, as in
837e3c11fc1SJed Brown 
838e3c11fc1SJed Brown      dF/dP + shift * dF/dCdot dC/dP.
839e3c11fc1SJed Brown 
840db781477SPatrick Sanan .seealso: `TSSetTransientVariable()`, `DMTSGetTransientVariable()`, `DMTSSetIFunction()`, `DMTSSetIJacobian()`
841e3c11fc1SJed Brown @*/
842e3c11fc1SJed Brown PetscErrorCode DMTSSetTransientVariable(DM dm,TSTransientVariable tvar,void *ctx)
843e3c11fc1SJed Brown {
844e3c11fc1SJed Brown   DMTS           dmts;
845e3c11fc1SJed Brown 
846e3c11fc1SJed Brown   PetscFunctionBegin;
847e3c11fc1SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
8489566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm,&dmts));
849e3c11fc1SJed Brown   dmts->ops->transientvar = tvar;
850e3c11fc1SJed Brown   dmts->transientvarctx = ctx;
851e3c11fc1SJed Brown   PetscFunctionReturn(0);
852e3c11fc1SJed Brown }
853e3c11fc1SJed Brown 
854e3c11fc1SJed Brown /*@C
855e3c11fc1SJed Brown    DMTSGetTransientVariable - gets function to transform from state to transient variables
856e3c11fc1SJed Brown 
857e3c11fc1SJed Brown    Logically Collective
858e3c11fc1SJed Brown 
8594165533cSJose E. Roman    Input Parameter:
860e3c11fc1SJed Brown .  dm - DM to be used with TS
861e3c11fc1SJed Brown 
8624165533cSJose E. Roman    Output Parameters:
863a96d6ef6SBarry Smith +  tvar - a function that transforms to transient variables
864e3c11fc1SJed Brown -  ctx - a context for tvar
865e3c11fc1SJed Brown 
866e3c11fc1SJed Brown    Level: advanced
867e3c11fc1SJed Brown 
868db781477SPatrick Sanan .seealso: `DMTSSetTransientVariable()`, `DMTSGetIFunction()`, `DMTSGetIJacobian()`
869e3c11fc1SJed Brown @*/
870e3c11fc1SJed Brown PetscErrorCode DMTSGetTransientVariable(DM dm,TSTransientVariable *tvar,void *ctx)
871e3c11fc1SJed Brown {
872e3c11fc1SJed Brown   DMTS           dmts;
873e3c11fc1SJed Brown 
874e3c11fc1SJed Brown   PetscFunctionBegin;
875e3c11fc1SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
8769566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm,&dmts));
877e3c11fc1SJed Brown   if (tvar) *tvar = dmts->ops->transientvar;
878e3c11fc1SJed Brown   if (ctx)  *(void**)ctx = dmts->transientvarctx;
879e3c11fc1SJed Brown   PetscFunctionReturn(0);
880e3c11fc1SJed Brown }
881e3c11fc1SJed Brown 
882e3c11fc1SJed Brown /*@C
883ef20d060SBarry Smith    DMTSGetSolutionFunction - gets the TS solution evaluation function
884ef20d060SBarry Smith 
885ef20d060SBarry Smith    Not Collective
886ef20d060SBarry Smith 
8874165533cSJose E. Roman    Input Parameter:
888ef20d060SBarry Smith .  dm - DM to be used with TS
889ef20d060SBarry Smith 
890ef20d060SBarry Smith    Output Parameters:
891ef20d060SBarry Smith +  func - solution function evaluation function, see TSSetSolution() for calling sequence
892ef20d060SBarry Smith -  ctx - context for solution evaluation
893ef20d060SBarry Smith 
894ef20d060SBarry Smith    Level: advanced
895ef20d060SBarry Smith 
896db781477SPatrick Sanan .seealso: `DMTSSetContext()`, `TSSetFunction()`, `DMTSSetJacobian()`, `DMTSSetSolutionFunction()`
897ef20d060SBarry Smith @*/
898ef20d060SBarry Smith PetscErrorCode DMTSGetSolutionFunction(DM dm,TSSolutionFunction *func,void **ctx)
899ef20d060SBarry Smith {
900942e3340SBarry Smith   DMTS           tsdm;
901ef20d060SBarry Smith 
902ef20d060SBarry Smith   PetscFunctionBegin;
903ef20d060SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
9049566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm,&tsdm));
905d74926cbSBarry Smith   if (func) *func = tsdm->ops->solution;
906ef20d060SBarry Smith   if (ctx)  *ctx  = tsdm->solutionctx;
907ef20d060SBarry Smith   PetscFunctionReturn(0);
908ef20d060SBarry Smith }
909ef20d060SBarry Smith 
910ef20d060SBarry Smith /*@C
911ef20d060SBarry Smith    DMTSSetSolutionFunction - set TS solution evaluation function
912ef20d060SBarry Smith 
913ef20d060SBarry Smith    Not Collective
914ef20d060SBarry Smith 
9154165533cSJose E. Roman    Input Parameters:
916ef20d060SBarry Smith +  dm - DM to be used with TS
917a96d6ef6SBarry Smith .  func - solution function evaluation routine
918ef20d060SBarry Smith -  ctx - context for solution evaluation
919ef20d060SBarry Smith 
920a96d6ef6SBarry Smith     Calling sequence of f:
921a96d6ef6SBarry Smith $     PetscErrorCode f(TS ts,PetscReal t,Vec u,void *ctx);
922a96d6ef6SBarry Smith 
923a96d6ef6SBarry Smith +   ts - timestep context
924a96d6ef6SBarry Smith .   t - current timestep
925a96d6ef6SBarry Smith .   u - output vector
926a96d6ef6SBarry Smith -   ctx - [optional] user-defined function context
927a96d6ef6SBarry Smith 
928ef20d060SBarry Smith    Level: advanced
929ef20d060SBarry Smith 
930ef20d060SBarry Smith    Note:
931ef20d060SBarry Smith    TSSetSolutionFunction() is normally used, but it calls this function internally because the user context is actually
932ef20d060SBarry Smith    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
933ef20d060SBarry Smith    not. If DM took a more central role at some later date, this could become the primary method of setting the residual.
934ef20d060SBarry Smith 
935db781477SPatrick Sanan .seealso: `DMTSSetContext()`, `TSSetFunction()`, `DMTSSetJacobian()`, `DMTSGetSolutionFunction()`
936ef20d060SBarry Smith @*/
937ef20d060SBarry Smith PetscErrorCode DMTSSetSolutionFunction(DM dm,TSSolutionFunction func,void *ctx)
938ef20d060SBarry Smith {
939942e3340SBarry Smith   DMTS           tsdm;
940ef20d060SBarry Smith 
941ef20d060SBarry Smith   PetscFunctionBegin;
942ef20d060SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
9439566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm,&tsdm));
944d74926cbSBarry Smith   if (func) tsdm->ops->solution = func;
945ef20d060SBarry Smith   if (ctx)  tsdm->solutionctx   = ctx;
946ef20d060SBarry Smith   PetscFunctionReturn(0);
947ef20d060SBarry Smith }
948ef20d060SBarry Smith 
9499b7cd975SBarry Smith /*@C
9509b7cd975SBarry Smith    DMTSSetForcingFunction - set TS forcing function evaluation function
9519b7cd975SBarry Smith 
9529b7cd975SBarry Smith    Not Collective
9539b7cd975SBarry Smith 
9544165533cSJose E. Roman    Input Parameters:
9559b7cd975SBarry Smith +  dm - DM to be used with TS
956a96d6ef6SBarry Smith .  f - forcing function evaluation routine
9579b7cd975SBarry Smith -  ctx - context for solution evaluation
9589b7cd975SBarry Smith 
959a96d6ef6SBarry Smith     Calling sequence of func:
960a96d6ef6SBarry Smith $     PetscErrorCode func (TS ts,PetscReal t,Vec f,void *ctx);
961a96d6ef6SBarry Smith 
962a96d6ef6SBarry Smith +   ts - timestep context
963a96d6ef6SBarry Smith .   t - current timestep
964a96d6ef6SBarry Smith .   f - output vector
965a96d6ef6SBarry Smith -   ctx - [optional] user-defined function context
966a96d6ef6SBarry Smith 
9679b7cd975SBarry Smith    Level: advanced
9689b7cd975SBarry Smith 
9699b7cd975SBarry Smith    Note:
9709b7cd975SBarry Smith    TSSetForcingFunction() is normally used, but it calls this function internally because the user context is actually
9719b7cd975SBarry Smith    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
9729b7cd975SBarry Smith    not. If DM took a more central role at some later date, this could become the primary method of setting the residual.
9739b7cd975SBarry Smith 
974db781477SPatrick Sanan .seealso: `DMTSSetContext()`, `TSSetFunction()`, `DMTSSetJacobian()`, `TSSetForcingFunction()`, `DMTSGetForcingFunction()`
9759b7cd975SBarry Smith @*/
976d56366bfSLisandro Dalcin PetscErrorCode DMTSSetForcingFunction(DM dm,TSForcingFunction f,void *ctx)
9779b7cd975SBarry Smith {
9789b7cd975SBarry Smith   DMTS           tsdm;
9799b7cd975SBarry Smith 
9809b7cd975SBarry Smith   PetscFunctionBegin;
9819b7cd975SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
9829566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm,&tsdm));
983f8b49ee9SBarry Smith   if (f)    tsdm->ops->forcing = f;
9849b7cd975SBarry Smith   if (ctx)  tsdm->forcingctx   = ctx;
9859b7cd975SBarry Smith   PetscFunctionReturn(0);
9869b7cd975SBarry Smith }
9879b7cd975SBarry Smith 
9889b7cd975SBarry Smith /*@C
9899b7cd975SBarry Smith    DMTSGetForcingFunction - get TS forcing function evaluation function
9909b7cd975SBarry Smith 
9919b7cd975SBarry Smith    Not Collective
9929b7cd975SBarry Smith 
9934165533cSJose E. Roman    Input Parameter:
9949b7cd975SBarry Smith .   dm - DM to be used with TS
9959b7cd975SBarry Smith 
9964165533cSJose E. Roman    Output Parameters:
997f8b49ee9SBarry Smith +  f - forcing function evaluation function; see TSForcingFunction for details
9989b7cd975SBarry Smith -  ctx - context for solution evaluation
9999b7cd975SBarry Smith 
10009b7cd975SBarry Smith    Level: advanced
10019b7cd975SBarry Smith 
10029b7cd975SBarry Smith    Note:
10039b7cd975SBarry Smith    TSSetForcingFunction() is normally used, but it calls this function internally because the user context is actually
10049b7cd975SBarry Smith    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
10059b7cd975SBarry Smith    not. If DM took a more central role at some later date, this could become the primary method of setting the residual.
10069b7cd975SBarry Smith 
1007db781477SPatrick Sanan .seealso: `DMTSSetContext()`, `TSSetFunction()`, `DMTSSetJacobian()`, `TSSetForcingFunction()`, `DMTSGetForcingFunction()`
10089b7cd975SBarry Smith @*/
1009d56366bfSLisandro Dalcin PetscErrorCode DMTSGetForcingFunction(DM dm,TSForcingFunction *f,void **ctx)
10109b7cd975SBarry Smith {
10119b7cd975SBarry Smith   DMTS           tsdm;
10129b7cd975SBarry Smith 
10139b7cd975SBarry Smith   PetscFunctionBegin;
10149b7cd975SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
10159566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm,&tsdm));
1016f8b49ee9SBarry Smith   if (f)   *f   = tsdm->ops->forcing;
10179b7cd975SBarry Smith   if (ctx) *ctx = tsdm->forcingctx;
10189b7cd975SBarry Smith   PetscFunctionReturn(0);
10199b7cd975SBarry Smith }
10209b7cd975SBarry Smith 
102124989b8cSPeter Brune /*@C
102224989b8cSPeter Brune    DMTSGetRHSFunction - get TS explicit residual evaluation function
102324989b8cSPeter Brune 
102424989b8cSPeter Brune    Not Collective
102524989b8cSPeter Brune 
10264165533cSJose E. Roman    Input Parameter:
102724989b8cSPeter Brune .  dm - DM to be used with TS
102824989b8cSPeter Brune 
10294165533cSJose E. Roman    Output Parameters:
103024989b8cSPeter Brune +  func - residual evaluation function, see TSSetRHSFunction() for calling sequence
103124989b8cSPeter Brune -  ctx - context for residual evaluation
103224989b8cSPeter Brune 
103324989b8cSPeter Brune    Level: advanced
103424989b8cSPeter Brune 
103524989b8cSPeter Brune    Note:
103624989b8cSPeter Brune    TSGetFunction() is normally used, but it calls this function internally because the user context is actually
103724989b8cSPeter Brune    associated with the DM.
103824989b8cSPeter Brune 
1039db781477SPatrick Sanan .seealso: `DMTSSetContext()`, `DMTSSetRHSFunction()`, `TSSetRHSFunction()`
104024989b8cSPeter Brune @*/
104124989b8cSPeter Brune PetscErrorCode DMTSGetRHSFunction(DM dm,TSRHSFunction *func,void **ctx)
104224989b8cSPeter Brune {
1043942e3340SBarry Smith   DMTS           tsdm;
104424989b8cSPeter Brune 
104524989b8cSPeter Brune   PetscFunctionBegin;
104624989b8cSPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
10479566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm,&tsdm));
1048d74926cbSBarry Smith   if (func) *func = tsdm->ops->rhsfunction;
1049800f99ffSJeremy L Thompson   if (ctx) {
1050800f99ffSJeremy L Thompson     if (tsdm->rhsfunctionctxcontainer) PetscCall(PetscContainerGetPointer(tsdm->rhsfunctionctxcontainer,ctx));
1051800f99ffSJeremy L Thompson     else *ctx = NULL;
1052800f99ffSJeremy L Thompson   }
105324989b8cSPeter Brune   PetscFunctionReturn(0);
105424989b8cSPeter Brune }
105524989b8cSPeter Brune 
105624989b8cSPeter Brune /*@C
105724989b8cSPeter Brune    DMTSSetIJacobian - set TS Jacobian evaluation function
105824989b8cSPeter Brune 
105924989b8cSPeter Brune    Not Collective
106024989b8cSPeter Brune 
10614165533cSJose E. Roman    Input Parameters:
106224989b8cSPeter Brune +  dm - DM to be used with TS
1063a96d6ef6SBarry Smith .  func - Jacobian evaluation routine
106424989b8cSPeter Brune -  ctx - context for residual evaluation
106524989b8cSPeter Brune 
1066a96d6ef6SBarry Smith    Calling sequence of f:
1067a96d6ef6SBarry Smith $    PetscErrorCode f(TS ts,PetscReal t,Vec U,Vec U_t,PetscReal a,Mat Amat,Mat Pmat,void *ctx);
1068a96d6ef6SBarry Smith 
1069a96d6ef6SBarry Smith +  t    - time at step/stage being solved
1070a96d6ef6SBarry Smith .  U    - state vector
1071a96d6ef6SBarry Smith .  U_t  - time derivative of state vector
1072a96d6ef6SBarry Smith .  a    - shift
1073a96d6ef6SBarry Smith .  Amat - (approximate) Jacobian of F(t,U,W+a*U), equivalent to dF/dU + a*dF/dU_t
1074a96d6ef6SBarry Smith .  Pmat - matrix used for constructing preconditioner, usually the same as Amat
1075a96d6ef6SBarry Smith -  ctx  - [optional] user-defined context for matrix evaluation routine
1076a96d6ef6SBarry Smith 
107724989b8cSPeter Brune    Level: advanced
107824989b8cSPeter Brune 
107924989b8cSPeter Brune    Note:
108024989b8cSPeter Brune    TSSetJacobian() is normally used, but it calls this function internally because the user context is actually
108124989b8cSPeter Brune    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
108224989b8cSPeter Brune    not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian.
108324989b8cSPeter Brune 
1084db781477SPatrick Sanan .seealso: `DMTSSetContext()`, `TSSetRHSFunction()`, `DMTSGetJacobian()`, `TSSetIJacobian()`, `TSSetIFunction()`
108524989b8cSPeter Brune @*/
108624989b8cSPeter Brune PetscErrorCode DMTSSetIJacobian(DM dm,TSIJacobian func,void *ctx)
108724989b8cSPeter Brune {
1088800f99ffSJeremy L Thompson   DMTS           tsdm;
108924989b8cSPeter Brune 
109024989b8cSPeter Brune   PetscFunctionBegin;
109124989b8cSPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1092800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm,&tsdm));
1093800f99ffSJeremy L Thompson   if (func) tsdm->ops->ijacobian = func;
1094800f99ffSJeremy L Thompson   if (ctx) {
1095800f99ffSJeremy L Thompson     PetscContainer ctxcontainer;
1096800f99ffSJeremy L Thompson     PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)tsdm),&ctxcontainer));
1097800f99ffSJeremy L Thompson     PetscCall(PetscContainerSetPointer(ctxcontainer,ctx));
1098800f99ffSJeremy L Thompson     PetscCall(PetscObjectCompose((PetscObject)tsdm,"ijacobian ctx",(PetscObject)ctxcontainer));
1099800f99ffSJeremy L Thompson     tsdm->ijacobianctxcontainer = ctxcontainer;
1100800f99ffSJeremy L Thompson     PetscCall(PetscContainerDestroy(&ctxcontainer));
1101800f99ffSJeremy L Thompson   }
1102800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
1103800f99ffSJeremy L Thompson }
1104800f99ffSJeremy L Thompson 
1105800f99ffSJeremy L Thompson /*@C
1106*5cb80ecdSBarry Smith    DMTSSetIJacobianContextDestroy - set `TS` Jacobian evaluation context destroy function
1107800f99ffSJeremy L Thompson 
1108800f99ffSJeremy L Thompson    Not Collective
1109800f99ffSJeremy L Thompson 
1110800f99ffSJeremy L Thompson    Input Parameters:
1111*5cb80ecdSBarry Smith +  dm - `DM` to be used with `TS`
1112*5cb80ecdSBarry Smith -  f - Jacobian evaluation context destroy function
1113800f99ffSJeremy L Thompson 
1114800f99ffSJeremy L Thompson    Level: advanced
1115800f99ffSJeremy L Thompson 
1116800f99ffSJeremy L Thompson    Note:
1117*5cb80ecdSBarry Smith    `TSSetIJacobianContextDestroy()` is normally used, but it calls this function internally because the user context is actually
1118*5cb80ecdSBarry Smith    associated with the `DM`.  This makes the interface consistent regardless of whether the user interacts with a `DM` or
1119*5cb80ecdSBarry Smith    not.
1120800f99ffSJeremy L Thompson 
1121*5cb80ecdSBarry Smith    Developer Note:
1122*5cb80ecdSBarry Smith    If `DM` took a more central role at some later date, this could become the primary method of setting the Jacobian.
1123*5cb80ecdSBarry Smith 
1124*5cb80ecdSBarry Smith .seealso: `TSSetIJacobianContextDestroy()`, `TSSetI2JacobianContextDestroy()`, `DMTSSetIJacobian()`, `TSSetIJacobian()`
1125800f99ffSJeremy L Thompson @*/
1126800f99ffSJeremy L Thompson PetscErrorCode DMTSSetIJacobianContextDestroy(DM dm,PetscErrorCode (*f)(void*))
1127800f99ffSJeremy L Thompson {
1128800f99ffSJeremy L Thompson   DMTS           tsdm;
1129800f99ffSJeremy L Thompson 
1130800f99ffSJeremy L Thompson   PetscFunctionBegin;
1131800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1132800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm,&tsdm));
1133800f99ffSJeremy L Thompson   if (tsdm->ijacobianctxcontainer) PetscCall(PetscContainerSetUserDestroy(tsdm->ijacobianctxcontainer,f));
1134800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
1135800f99ffSJeremy L Thompson }
1136800f99ffSJeremy L Thompson 
1137800f99ffSJeremy L Thompson PetscErrorCode DMTSUnsetIJacobianContext_Internal(DM dm)
1138800f99ffSJeremy L Thompson {
1139800f99ffSJeremy L Thompson   DMTS           tsdm;
1140800f99ffSJeremy L Thompson 
1141800f99ffSJeremy L Thompson   PetscFunctionBegin;
1142800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1143800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm,&tsdm));
1144800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetIJacobianContext_DMTS(tsdm));
114524989b8cSPeter Brune   PetscFunctionReturn(0);
114624989b8cSPeter Brune }
114724989b8cSPeter Brune 
114824989b8cSPeter Brune /*@C
114924989b8cSPeter Brune    DMTSGetIJacobian - get TS Jacobian evaluation function
115024989b8cSPeter Brune 
115124989b8cSPeter Brune    Not Collective
115224989b8cSPeter Brune 
11534165533cSJose E. Roman    Input Parameter:
115424989b8cSPeter Brune .  dm - DM to be used with TS
115524989b8cSPeter Brune 
11564165533cSJose E. Roman    Output Parameters:
115724989b8cSPeter Brune +  func - Jacobian evaluation function, see TSSetIJacobian() for calling sequence
115824989b8cSPeter Brune -  ctx - context for residual evaluation
115924989b8cSPeter Brune 
116024989b8cSPeter Brune    Level: advanced
116124989b8cSPeter Brune 
116224989b8cSPeter Brune    Note:
116324989b8cSPeter Brune    TSGetJacobian() is normally used, but it calls this function internally because the user context is actually
116424989b8cSPeter Brune    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
116524989b8cSPeter Brune    not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian.
116624989b8cSPeter Brune 
1167db781477SPatrick Sanan .seealso: `DMTSSetContext()`, `TSSetFunction()`, `DMTSSetJacobian()`
116824989b8cSPeter Brune @*/
116924989b8cSPeter Brune PetscErrorCode DMTSGetIJacobian(DM dm,TSIJacobian *func,void **ctx)
117024989b8cSPeter Brune {
1171942e3340SBarry Smith   DMTS           tsdm;
117224989b8cSPeter Brune 
117324989b8cSPeter Brune   PetscFunctionBegin;
117424989b8cSPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
11759566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm,&tsdm));
1176d74926cbSBarry Smith   if (func) *func = tsdm->ops->ijacobian;
1177800f99ffSJeremy L Thompson   if (ctx) {
1178800f99ffSJeremy L Thompson     if (tsdm->ijacobianctxcontainer) PetscCall(PetscContainerGetPointer(tsdm->ijacobianctxcontainer,ctx));
1179800f99ffSJeremy L Thompson     else *ctx = NULL;
1180800f99ffSJeremy L Thompson   }
118124989b8cSPeter Brune   PetscFunctionReturn(0);
118224989b8cSPeter Brune }
118324989b8cSPeter Brune 
118424989b8cSPeter Brune /*@C
118524989b8cSPeter Brune    DMTSSetRHSJacobian - set TS Jacobian evaluation function
118624989b8cSPeter Brune 
118724989b8cSPeter Brune    Not Collective
118824989b8cSPeter Brune 
11894165533cSJose E. Roman    Input Parameters:
119024989b8cSPeter Brune +  dm - DM to be used with TS
1191a96d6ef6SBarry Smith .  func - Jacobian evaluation routine
119224989b8cSPeter Brune -  ctx - context for residual evaluation
119324989b8cSPeter Brune 
1194a96d6ef6SBarry Smith    Calling sequence of func:
1195a96d6ef6SBarry Smith $     PetscErrorCode func(TS ts,PetscReal t,Vec u,Mat A,Mat B,void *ctx);
1196a96d6ef6SBarry Smith 
1197a96d6ef6SBarry Smith +  t - current timestep
1198a96d6ef6SBarry Smith .  u - input vector
1199a96d6ef6SBarry Smith .  Amat - (approximate) Jacobian matrix
1200a96d6ef6SBarry Smith .  Pmat - matrix from which preconditioner is to be constructed (usually the same as Amat)
1201a96d6ef6SBarry Smith -  ctx - [optional] user-defined context for matrix evaluation routine
1202a96d6ef6SBarry Smith 
120324989b8cSPeter Brune    Level: advanced
120424989b8cSPeter Brune 
120524989b8cSPeter Brune    Note:
120624989b8cSPeter Brune    TSSetJacobian() is normally used, but it calls this function internally because the user context is actually
120724989b8cSPeter Brune    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
120824989b8cSPeter Brune    not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian.
120924989b8cSPeter Brune 
1210db781477SPatrick Sanan .seealso: `DMTSSetContext()`, `TSSetFunction()`, `DMTSGetJacobian()`, `TSSetRHSJacobian()`
121124989b8cSPeter Brune @*/
121224989b8cSPeter Brune PetscErrorCode DMTSSetRHSJacobian(DM dm,TSRHSJacobian func,void *ctx)
121324989b8cSPeter Brune {
1214942e3340SBarry Smith   DMTS           tsdm;
121524989b8cSPeter Brune 
121624989b8cSPeter Brune   PetscFunctionBegin;
121724989b8cSPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
12189566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm,&tsdm));
1219d74926cbSBarry Smith   if (func) tsdm->ops->rhsjacobian = func;
1220800f99ffSJeremy L Thompson   if (ctx) {
1221800f99ffSJeremy L Thompson     PetscContainer ctxcontainer;
1222800f99ffSJeremy L Thompson     PetscCall(PetscContainerCreate(PetscObjectComm((PetscObject)tsdm),&ctxcontainer));
1223800f99ffSJeremy L Thompson     PetscCall(PetscContainerSetPointer(ctxcontainer,ctx));
1224800f99ffSJeremy L Thompson     PetscCall(PetscObjectCompose((PetscObject)tsdm,"rhs jacobian ctx",(PetscObject)ctxcontainer));
1225800f99ffSJeremy L Thompson     tsdm->rhsjacobianctxcontainer = ctxcontainer;
1226800f99ffSJeremy L Thompson     PetscCall(PetscContainerDestroy(&ctxcontainer));
1227800f99ffSJeremy L Thompson   }
1228800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
1229800f99ffSJeremy L Thompson }
1230800f99ffSJeremy L Thompson 
1231800f99ffSJeremy L Thompson /*@C
1232*5cb80ecdSBarry Smith    DMTSSetRHSJacobianContextDestroy - set `TS` Jacobian evaluation context destroy function
1233800f99ffSJeremy L Thompson 
1234800f99ffSJeremy L Thompson    Not Collective
1235800f99ffSJeremy L Thompson 
1236800f99ffSJeremy L Thompson    Input Parameters:
1237*5cb80ecdSBarry Smith +  dm - `DM` to be used with `TS`
1238*5cb80ecdSBarry Smith -  f - Jacobian evaluation context destroy function
1239*5cb80ecdSBarry Smith 
1240*5cb80ecdSBarry Smith    Level: advanced
1241*5cb80ecdSBarry Smith 
1242*5cb80ecdSBarry Smith    Note:
1243*5cb80ecdSBarry Smith    The user usually calls `TSSetRHSJacobianContextDestroy()` which calls this routine
1244800f99ffSJeremy L Thompson 
1245800f99ffSJeremy L Thompson .seealso: `TSSetRHSJacobianContextDestroy()`, `DMTSSetRHSJacobian()`, `TSSetRHSJacobian()`
1246800f99ffSJeremy L Thompson @*/
1247800f99ffSJeremy L Thompson PetscErrorCode DMTSSetRHSJacobianContextDestroy(DM dm,PetscErrorCode (*f)(void*))
1248800f99ffSJeremy L Thompson {
1249800f99ffSJeremy L Thompson   DMTS           tsdm;
1250800f99ffSJeremy L Thompson 
1251800f99ffSJeremy L Thompson   PetscFunctionBegin;
1252800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1253800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm,&tsdm));
1254800f99ffSJeremy L Thompson   if (tsdm->rhsjacobianctxcontainer) PetscCall(PetscContainerSetUserDestroy(tsdm->rhsjacobianctxcontainer,f));
1255800f99ffSJeremy L Thompson   PetscFunctionReturn(0);
1256800f99ffSJeremy L Thompson }
1257800f99ffSJeremy L Thompson 
1258800f99ffSJeremy L Thompson PetscErrorCode DMTSUnsetRHSJacobianContext_Internal(DM dm)
1259800f99ffSJeremy L Thompson {
1260800f99ffSJeremy L Thompson   DMTS           tsdm;
1261800f99ffSJeremy L Thompson 
1262800f99ffSJeremy L Thompson   PetscFunctionBegin;
1263800f99ffSJeremy L Thompson   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1264800f99ffSJeremy L Thompson   PetscCall(DMGetDMTSWrite(dm,&tsdm));
1265800f99ffSJeremy L Thompson   PetscCall(DMTSUnsetRHSJacobianContext_DMTS(tsdm));
126624989b8cSPeter Brune   PetscFunctionReturn(0);
126724989b8cSPeter Brune }
126824989b8cSPeter Brune 
126924989b8cSPeter Brune /*@C
127024989b8cSPeter Brune    DMTSGetRHSJacobian - get TS Jacobian evaluation function
127124989b8cSPeter Brune 
127224989b8cSPeter Brune    Not Collective
127324989b8cSPeter Brune 
12744165533cSJose E. Roman    Input Parameter:
127524989b8cSPeter Brune .  dm - DM to be used with TS
127624989b8cSPeter Brune 
12774165533cSJose E. Roman    Output Parameters:
127824989b8cSPeter Brune +  func - Jacobian evaluation function, see TSSetRHSJacobian() for calling sequence
127924989b8cSPeter Brune -  ctx - context for residual evaluation
128024989b8cSPeter Brune 
128124989b8cSPeter Brune    Level: advanced
128224989b8cSPeter Brune 
128324989b8cSPeter Brune    Note:
128424989b8cSPeter Brune    TSGetJacobian() is normally used, but it calls this function internally because the user context is actually
128524989b8cSPeter Brune    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
128624989b8cSPeter Brune    not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian.
128724989b8cSPeter Brune 
1288db781477SPatrick Sanan .seealso: `DMTSSetContext()`, `TSSetRHSFunction()`, `DMTSSetRHSJacobian()`, `TSSetRHSJacobian()`
128924989b8cSPeter Brune @*/
129024989b8cSPeter Brune PetscErrorCode DMTSGetRHSJacobian(DM dm,TSRHSJacobian *func,void **ctx)
129124989b8cSPeter Brune {
1292942e3340SBarry Smith   DMTS           tsdm;
129324989b8cSPeter Brune 
129424989b8cSPeter Brune   PetscFunctionBegin;
129524989b8cSPeter Brune   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
12969566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm,&tsdm));
1297d74926cbSBarry Smith   if (func) *func = tsdm->ops->rhsjacobian;
1298800f99ffSJeremy L Thompson   if (ctx) {
1299800f99ffSJeremy L Thompson     if (tsdm->rhsjacobianctxcontainer) PetscCall(PetscContainerGetPointer(tsdm->rhsjacobianctxcontainer,ctx));
1300800f99ffSJeremy L Thompson     else *ctx = NULL;
1301800f99ffSJeremy L Thompson   }
130224989b8cSPeter Brune   PetscFunctionReturn(0);
130324989b8cSPeter Brune }
1304ad6bc421SBarry Smith 
1305ad6bc421SBarry Smith /*@C
1306ad6bc421SBarry Smith    DMTSSetIFunctionSerialize - sets functions used to view and load a IFunction context
1307ad6bc421SBarry Smith 
1308ad6bc421SBarry Smith    Not Collective
1309ad6bc421SBarry Smith 
13104165533cSJose E. Roman    Input Parameters:
1311ad6bc421SBarry Smith +  dm - DM to be used with TS
1312ad6bc421SBarry Smith .  view - viewer function
1313ad6bc421SBarry Smith -  load - loading function
1314ad6bc421SBarry Smith 
1315ad6bc421SBarry Smith    Level: advanced
1316ad6bc421SBarry Smith 
1317db781477SPatrick Sanan .seealso: `DMTSSetContext()`, `TSSetFunction()`, `DMTSSetJacobian()`
1318ad6bc421SBarry Smith @*/
1319ad6bc421SBarry Smith PetscErrorCode DMTSSetIFunctionSerialize(DM dm,PetscErrorCode (*view)(void*,PetscViewer),PetscErrorCode (*load)(void**,PetscViewer))
1320ad6bc421SBarry Smith {
1321ad6bc421SBarry Smith   DMTS           tsdm;
1322ad6bc421SBarry Smith 
1323ad6bc421SBarry Smith   PetscFunctionBegin;
1324ad6bc421SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
13259566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm,&tsdm));
1326ad6bc421SBarry Smith   tsdm->ops->ifunctionview = view;
1327ad6bc421SBarry Smith   tsdm->ops->ifunctionload = load;
1328ad6bc421SBarry Smith   PetscFunctionReturn(0);
1329ad6bc421SBarry Smith }
1330ad6bc421SBarry Smith 
1331ad6bc421SBarry Smith /*@C
1332ad6bc421SBarry Smith    DMTSSetIJacobianSerialize - sets functions used to view and load a IJacobian context
1333ad6bc421SBarry Smith 
1334ad6bc421SBarry Smith    Not Collective
1335ad6bc421SBarry Smith 
13364165533cSJose E. Roman    Input Parameters:
1337ad6bc421SBarry Smith +  dm - DM to be used with TS
1338ad6bc421SBarry Smith .  view - viewer function
1339ad6bc421SBarry Smith -  load - loading function
1340ad6bc421SBarry Smith 
1341ad6bc421SBarry Smith    Level: advanced
1342ad6bc421SBarry Smith 
1343db781477SPatrick Sanan .seealso: `DMTSSetContext()`, `TSSetFunction()`, `DMTSSetJacobian()`
1344ad6bc421SBarry Smith @*/
1345ad6bc421SBarry Smith PetscErrorCode DMTSSetIJacobianSerialize(DM dm,PetscErrorCode (*view)(void*,PetscViewer),PetscErrorCode (*load)(void**,PetscViewer))
1346ad6bc421SBarry Smith {
1347ad6bc421SBarry Smith   DMTS           tsdm;
1348ad6bc421SBarry Smith 
1349ad6bc421SBarry Smith   PetscFunctionBegin;
1350ad6bc421SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
13519566063dSJacob Faibussowitsch   PetscCall(DMGetDMTSWrite(dm,&tsdm));
1352ad6bc421SBarry Smith   tsdm->ops->ijacobianview = view;
1353ad6bc421SBarry Smith   tsdm->ops->ijacobianload = load;
1354ad6bc421SBarry Smith   PetscFunctionReturn(0);
1355ad6bc421SBarry Smith }
1356