Actual source code: dmts.c
1: #include <petsc/private/tsimpl.h>
2: #include <petsc/private/dmimpl.h>
4: static PetscErrorCode DMTSDestroy(DMTS *kdm)
5: {
6: if (!*kdm) return 0;
8: if (--((PetscObject)(*kdm))->refct > 0) {*kdm = NULL; return 0;}
9: if ((*kdm)->ops->destroy) ((*kdm)->ops->destroy)(*kdm);
10: PetscHeaderDestroy(kdm);
11: return 0;
12: }
14: PetscErrorCode DMTSLoad(DMTS kdm,PetscViewer viewer)
15: {
16: PetscViewerBinaryRead(viewer,&kdm->ops->ifunction,1,NULL,PETSC_FUNCTION);
17: PetscViewerBinaryRead(viewer,&kdm->ops->ifunctionview,1,NULL,PETSC_FUNCTION);
18: PetscViewerBinaryRead(viewer,&kdm->ops->ifunctionload,1,NULL,PETSC_FUNCTION);
19: if (kdm->ops->ifunctionload) {
20: (*kdm->ops->ifunctionload)(&kdm->ifunctionctx,viewer);
21: }
22: PetscViewerBinaryRead(viewer,&kdm->ops->ijacobian,1,NULL,PETSC_FUNCTION);
23: PetscViewerBinaryRead(viewer,&kdm->ops->ijacobianview,1,NULL,PETSC_FUNCTION);
24: PetscViewerBinaryRead(viewer,&kdm->ops->ijacobianload,1,NULL,PETSC_FUNCTION);
25: if (kdm->ops->ijacobianload) {
26: (*kdm->ops->ijacobianload)(&kdm->ijacobianctx,viewer);
27: }
28: return 0;
29: }
31: PetscErrorCode DMTSView(DMTS kdm,PetscViewer viewer)
32: {
33: PetscBool isascii,isbinary;
35: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
36: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);
37: if (isascii) {
38: #if defined(PETSC_SERIALIZE_FUNCTIONS)
39: const char *fname;
41: PetscFPTFind(kdm->ops->ifunction,&fname);
42: if (fname) {
43: PetscViewerASCIIPrintf(viewer," IFunction used by TS: %s\n",fname);
44: }
45: PetscFPTFind(kdm->ops->ijacobian,&fname);
46: if (fname) {
47: PetscViewerASCIIPrintf(viewer," IJacobian function used by TS: %s\n",fname);
48: }
49: #endif
50: } else if (isbinary) {
51: struct {
52: TSIFunction ifunction;
53: } funcstruct;
54: struct {
55: PetscErrorCode (*ifunctionview)(void*,PetscViewer);
56: } funcviewstruct;
57: struct {
58: PetscErrorCode (*ifunctionload)(void**,PetscViewer);
59: } funcloadstruct;
60: struct {
61: TSIJacobian ijacobian;
62: } jacstruct;
63: struct {
64: PetscErrorCode (*ijacobianview)(void*,PetscViewer);
65: } jacviewstruct;
66: struct {
67: PetscErrorCode (*ijacobianload)(void**,PetscViewer);
68: } jacloadstruct;
70: funcstruct.ifunction = kdm->ops->ifunction;
71: funcviewstruct.ifunctionview = kdm->ops->ifunctionview;
72: funcloadstruct.ifunctionload = kdm->ops->ifunctionload;
73: PetscViewerBinaryWrite(viewer,&funcstruct,1,PETSC_FUNCTION);
74: PetscViewerBinaryWrite(viewer,&funcviewstruct,1,PETSC_FUNCTION);
75: PetscViewerBinaryWrite(viewer,&funcloadstruct,1,PETSC_FUNCTION);
76: if (kdm->ops->ifunctionview) {
77: (*kdm->ops->ifunctionview)(kdm->ifunctionctx,viewer);
78: }
79: jacstruct.ijacobian = kdm->ops->ijacobian;
80: jacviewstruct.ijacobianview = kdm->ops->ijacobianview;
81: jacloadstruct.ijacobianload = kdm->ops->ijacobianload;
82: PetscViewerBinaryWrite(viewer,&jacstruct,1,PETSC_FUNCTION);
83: PetscViewerBinaryWrite(viewer,&jacviewstruct,1,PETSC_FUNCTION);
84: PetscViewerBinaryWrite(viewer,&jacloadstruct,1,PETSC_FUNCTION);
85: if (kdm->ops->ijacobianview) {
86: (*kdm->ops->ijacobianview)(kdm->ijacobianctx,viewer);
87: }
88: }
89: return 0;
90: }
92: static PetscErrorCode DMTSCreate(MPI_Comm comm,DMTS *kdm)
93: {
94: TSInitializePackage();
95: PetscHeaderCreate(*kdm, DMTS_CLASSID, "DMTS", "DMTS", "DMTS", comm, DMTSDestroy, DMTSView);
96: return 0;
97: }
99: /* Attaches the DMTS to the coarse level.
100: * Under what conditions should we copy versus duplicate?
101: */
102: static PetscErrorCode DMCoarsenHook_DMTS(DM dm,DM dmc,void *ctx)
103: {
104: DMCopyDMTS(dm,dmc);
105: return 0;
106: }
108: /* This could restrict auxiliary information to the coarse level.
109: */
110: static PetscErrorCode DMRestrictHook_DMTS(DM dm,Mat Restrict,Vec rscale,Mat Inject,DM dmc,void *ctx)
111: {
112: return 0;
113: }
115: static PetscErrorCode DMSubDomainHook_DMTS(DM dm,DM subdm,void *ctx)
116: {
117: DMCopyDMTS(dm,subdm);
118: return 0;
119: }
121: /* This could restrict auxiliary information to the coarse level.
122: */
123: static PetscErrorCode DMSubDomainRestrictHook_DMTS(DM dm,VecScatter gscat,VecScatter lscat,DM subdm,void *ctx)
124: {
125: return 0;
126: }
128: /*@C
129: DMTSCopy - copies the information in a DMTS to another DMTS
131: Not Collective
133: Input Parameters:
134: + kdm - Original DMTS
135: - nkdm - DMTS to receive the data, should have been created with DMTSCreate()
137: Level: developer
139: .seealso: DMTSCreate(), DMTSDestroy()
140: @*/
141: PetscErrorCode DMTSCopy(DMTS kdm,DMTS nkdm)
142: {
145: nkdm->ops->rhsfunction = kdm->ops->rhsfunction;
146: nkdm->ops->rhsjacobian = kdm->ops->rhsjacobian;
147: nkdm->ops->ifunction = kdm->ops->ifunction;
148: nkdm->ops->ijacobian = kdm->ops->ijacobian;
149: nkdm->ops->i2function = kdm->ops->i2function;
150: nkdm->ops->i2jacobian = kdm->ops->i2jacobian;
151: nkdm->ops->solution = kdm->ops->solution;
152: nkdm->ops->destroy = kdm->ops->destroy;
153: nkdm->ops->duplicate = kdm->ops->duplicate;
155: nkdm->rhsfunctionctx = kdm->rhsfunctionctx;
156: nkdm->rhsjacobianctx = kdm->rhsjacobianctx;
157: nkdm->ifunctionctx = kdm->ifunctionctx;
158: nkdm->ijacobianctx = kdm->ijacobianctx;
159: nkdm->i2functionctx = kdm->i2functionctx;
160: nkdm->i2jacobianctx = kdm->i2jacobianctx;
161: nkdm->solutionctx = kdm->solutionctx;
163: nkdm->data = kdm->data;
165: /*
166: nkdm->fortran_func_pointers[0] = kdm->fortran_func_pointers[0];
167: nkdm->fortran_func_pointers[1] = kdm->fortran_func_pointers[1];
168: nkdm->fortran_func_pointers[2] = kdm->fortran_func_pointers[2];
169: */
171: /* implementation specific copy hooks */
172: if (kdm->ops->duplicate) (*kdm->ops->duplicate)(kdm,nkdm);
173: return 0;
174: }
176: /*@C
177: DMGetDMTS - get read-only private DMTS context from a DM
179: Not Collective
181: Input Parameter:
182: . dm - DM to be used with TS
184: Output Parameter:
185: . tsdm - private DMTS context
187: Level: developer
189: Notes:
190: Use DMGetDMTSWrite() if write access is needed. The DMTSSetXXX API should be used wherever possible.
192: .seealso: DMGetDMTSWrite()
193: @*/
194: PetscErrorCode DMGetDMTS(DM dm,DMTS *tsdm)
195: {
197: *tsdm = (DMTS) dm->dmts;
198: if (!*tsdm) {
199: PetscInfo(dm,"Creating new DMTS\n");
200: DMTSCreate(PetscObjectComm((PetscObject)dm),tsdm);
201: dm->dmts = (PetscObject) *tsdm;
202: (*tsdm)->originaldm = dm;
203: DMCoarsenHookAdd(dm,DMCoarsenHook_DMTS,DMRestrictHook_DMTS,NULL);
204: DMSubDomainHookAdd(dm,DMSubDomainHook_DMTS,DMSubDomainRestrictHook_DMTS,NULL);
205: }
206: return 0;
207: }
209: /*@C
210: DMGetDMTSWrite - get write access to private DMTS context from a DM
212: Not Collective
214: Input Parameter:
215: . dm - DM to be used with TS
217: Output Parameter:
218: . tsdm - private DMTS context
220: Level: developer
222: .seealso: DMGetDMTS()
223: @*/
224: PetscErrorCode DMGetDMTSWrite(DM dm,DMTS *tsdm)
225: {
226: DMTS sdm;
229: DMGetDMTS(dm,&sdm);
231: if (sdm->originaldm != dm) { /* Copy on write */
232: DMTS oldsdm = sdm;
233: PetscInfo(dm,"Copying DMTS due to write\n");
234: DMTSCreate(PetscObjectComm((PetscObject)dm),&sdm);
235: DMTSCopy(oldsdm,sdm);
236: DMTSDestroy((DMTS*)&dm->dmts);
237: dm->dmts = (PetscObject) sdm;
238: sdm->originaldm = dm;
239: }
240: *tsdm = sdm;
241: return 0;
242: }
244: /*@C
245: DMCopyDMTS - copies a DM context to a new DM
247: Logically Collective
249: Input Parameters:
250: + dmsrc - DM to obtain context from
251: - dmdest - DM to add context to
253: Level: developer
255: Note:
256: The context is copied by reference. This function does not ensure that a context exists.
258: .seealso: DMGetDMTS(), TSSetDM()
259: @*/
260: PetscErrorCode DMCopyDMTS(DM dmsrc,DM dmdest)
261: {
264: DMTSDestroy((DMTS*)&dmdest->dmts);
265: dmdest->dmts = dmsrc->dmts;
266: PetscObjectReference(dmdest->dmts);
267: DMCoarsenHookAdd(dmdest,DMCoarsenHook_DMTS,DMRestrictHook_DMTS,NULL);
268: DMSubDomainHookAdd(dmdest,DMSubDomainHook_DMTS,DMSubDomainRestrictHook_DMTS,NULL);
269: return 0;
270: }
272: /*@C
273: DMTSSetIFunction - set TS implicit function evaluation function
275: Not Collective
277: Input Parameters:
278: + dm - DM to be used with TS
279: . func - function evaluating f(t,u,u_t)
280: - ctx - context for residual evaluation
282: Calling sequence of func:
283: $ PetscErrorCode func(TS ts,PetscReal t,Vec u,Vec u_t,Vec F,ctx);
285: + t - time at step/stage being solved
286: . u - state vector
287: . u_t - time derivative of state vector
288: . F - function vector
289: - ctx - [optional] user-defined context for matrix evaluation routine
291: Level: advanced
293: Note:
294: TSSetFunction() is normally used, but it calls this function internally because the user context is actually
295: associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or
296: not. If DM took a more central role at some later date, this could become the primary method of setting the residual.
298: .seealso: DMTSSetContext(), TSSetIFunction(), DMTSSetJacobian()
299: @*/
300: PetscErrorCode DMTSSetIFunction(DM dm,TSIFunction func,void *ctx)
301: {
302: DMTS tsdm;
305: DMGetDMTSWrite(dm,&tsdm);
306: if (func) tsdm->ops->ifunction = func;
307: if (ctx) tsdm->ifunctionctx = ctx;
308: return 0;
309: }
311: /*@C
312: DMTSGetIFunction - get TS implicit residual evaluation function
314: Not Collective
316: Input Parameter:
317: . dm - DM to be used with TS
319: Output Parameters:
320: + func - function evaluation function, see TSSetIFunction() for calling sequence
321: - ctx - context for residual evaluation
323: Level: advanced
325: Note:
326: TSGetFunction() is normally used, but it calls this function internally because the user context is actually
327: associated with the DM.
329: .seealso: DMTSSetContext(), DMTSSetFunction(), TSSetFunction()
330: @*/
331: PetscErrorCode DMTSGetIFunction(DM dm,TSIFunction *func,void **ctx)
332: {
333: DMTS tsdm;
336: DMGetDMTS(dm,&tsdm);
337: if (func) *func = tsdm->ops->ifunction;
338: if (ctx) *ctx = tsdm->ifunctionctx;
339: return 0;
340: }
342: /*@C
343: DMTSSetI2Function - set TS implicit function evaluation function for 2nd order systems
345: Not Collective
347: Input Parameters:
348: + dm - DM to be used with TS
349: . fun - function evaluation routine
350: - ctx - context for residual evaluation
352: Calling sequence of fun:
353: $ PetscErrorCode fun(TS ts,PetscReal t,Vec U,Vec U_t,Vec U_tt,Vec F,ctx);
355: + t - time at step/stage being solved
356: . U - state vector
357: . U_t - time derivative of state vector
358: . U_tt - second time derivative of state vector
359: . F - function vector
360: - ctx - [optional] user-defined context for matrix evaluation routine (may be NULL)
362: Level: advanced
364: Note:
365: TSSetI2Function() is normally used, but it calls this function internally because the user context is actually
366: associated with the DM.
368: .seealso: TSSetI2Function()
369: @*/
370: PetscErrorCode DMTSSetI2Function(DM dm,TSI2Function fun,void *ctx)
371: {
372: DMTS tsdm;
375: DMGetDMTSWrite(dm,&tsdm);
376: if (fun) tsdm->ops->i2function = fun;
377: if (ctx) tsdm->i2functionctx = ctx;
378: return 0;
379: }
381: /*@C
382: DMTSGetI2Function - get TS implicit residual evaluation function for 2nd order systems
384: Not Collective
386: Input Parameter:
387: . dm - DM to be used with TS
389: Output Parameters:
390: + fun - function evaluation function, see TSSetI2Function() for calling sequence
391: - ctx - context for residual evaluation
393: Level: advanced
395: Note:
396: TSGetI2Function() is normally used, but it calls this function internally because the user context is actually
397: associated with the DM.
399: .seealso: DMTSSetI2Function(),TSGetI2Function()
400: @*/
401: PetscErrorCode DMTSGetI2Function(DM dm,TSI2Function *fun,void **ctx)
402: {
403: DMTS tsdm;
406: DMGetDMTS(dm,&tsdm);
407: if (fun) *fun = tsdm->ops->i2function;
408: if (ctx) *ctx = tsdm->i2functionctx;
409: return 0;
410: }
412: /*@C
413: DMTSSetI2Jacobian - set TS implicit Jacobian evaluation function for 2nd order systems
415: Not Collective
417: Input Parameters:
418: + dm - DM to be used with TS
419: . fun - Jacobian evaluation routine
420: - ctx - context for Jacobian evaluation
422: Calling sequence of jac:
423: $ PetscErrorCode jac(TS ts,PetscReal t,Vec U,Vec U_t,Vec U_tt,PetscReal v,PetscReal a,Mat J,Mat P,void *ctx);
425: + t - time at step/stage being solved
426: . U - state vector
427: . U_t - time derivative of state vector
428: . U_tt - second time derivative of state vector
429: . v - shift for U_t
430: . a - shift for U_tt
431: . 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
432: . P - preconditioning matrix for J, may be same as J
433: - ctx - [optional] user-defined context for matrix evaluation routine
435: Level: advanced
437: Note:
438: TSSetI2Jacobian() is normally used, but it calls this function internally because the user context is actually
439: associated with the DM.
441: .seealso: TSSetI2Jacobian()
442: @*/
443: PetscErrorCode DMTSSetI2Jacobian(DM dm,TSI2Jacobian jac,void *ctx)
444: {
445: DMTS tsdm;
448: DMGetDMTSWrite(dm,&tsdm);
449: if (jac) tsdm->ops->i2jacobian = jac;
450: if (ctx) tsdm->i2jacobianctx = ctx;
451: return 0;
452: }
454: /*@C
455: DMTSGetI2Jacobian - get TS implicit Jacobian evaluation function for 2nd order systems
457: Not Collective
459: Input Parameter:
460: . dm - DM to be used with TS
462: Output Parameters:
463: + jac - Jacobian evaluation function, see TSSetI2Jacobian() for calling sequence
464: - ctx - context for Jacobian evaluation
466: Level: advanced
468: Note:
469: TSGetI2Jacobian() is normally used, but it calls this function internally because the user context is actually
470: associated with the DM.
472: .seealso: DMTSSetI2Jacobian(),TSGetI2Jacobian()
473: @*/
474: PetscErrorCode DMTSGetI2Jacobian(DM dm,TSI2Jacobian *jac,void **ctx)
475: {
476: DMTS tsdm;
479: DMGetDMTS(dm,&tsdm);
480: if (jac) *jac = tsdm->ops->i2jacobian;
481: if (ctx) *ctx = tsdm->i2jacobianctx;
482: return 0;
483: }
485: /*@C
486: DMTSSetRHSFunction - set TS explicit residual evaluation function
488: Not Collective
490: Input Parameters:
491: + dm - DM to be used with TS
492: . func - RHS function evaluation routine
493: - ctx - context for residual evaluation
495: Calling sequence of func:
496: $ PetscErrorCode func(TS ts,PetscReal t,Vec u,Vec F,void *ctx);
498: + ts - timestep context
499: . t - current timestep
500: . u - input vector
501: . F - function vector
502: - ctx - [optional] user-defined function context
504: Level: advanced
506: Note:
507: TSSetRSHFunction() is normally used, but it calls this function internally because the user context is actually
508: associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or
509: not. If DM took a more central role at some later date, this could become the primary method of setting the residual.
511: .seealso: DMTSSetContext(), TSSetRHSFunction(), DMTSSetJacobian()
512: @*/
513: PetscErrorCode DMTSSetRHSFunction(DM dm,TSRHSFunction func,void *ctx)
514: {
515: DMTS tsdm;
518: DMGetDMTSWrite(dm,&tsdm);
519: if (func) tsdm->ops->rhsfunction = func;
520: if (ctx) tsdm->rhsfunctionctx = ctx;
521: return 0;
522: }
524: /*@C
525: DMTSSetTransientVariable - sets function to transform from state to transient variables
527: Logically Collective
529: Input Parameters:
530: + dm - DM to be used with TS
531: . tvar - a function that transforms to transient variables
532: - ctx - a context for tvar
534: Calling sequence of tvar:
535: $ PetscErrorCode tvar(TS ts,Vec p,Vec c,void *ctx);
537: + ts - timestep context
538: . p - input vector (primitive form)
539: . c - output vector, transient variables (conservative form)
540: - ctx - [optional] user-defined function context
542: Level: advanced
544: Notes:
545: This is typically used to transform from primitive to conservative variables so that a time integrator (e.g., TSBDF)
546: can be conservative. In this context, primitive variables P are used to model the state (e.g., because they lead to
547: well-conditioned formulations even in limiting cases such as low-Mach or zero porosity). The transient variable is
548: C(P), specified by calling this function. An IFunction thus receives arguments (P, Cdot) and the IJacobian must be
549: evaluated via the chain rule, as in
551: dF/dP + shift * dF/dCdot dC/dP.
553: .seealso: TSSetTransientVariable(), DMTSGetTransientVariable(), DMTSSetIFunction(), DMTSSetIJacobian()
554: @*/
555: PetscErrorCode DMTSSetTransientVariable(DM dm,TSTransientVariable tvar,void *ctx)
556: {
557: DMTS dmts;
560: DMGetDMTSWrite(dm,&dmts);
561: dmts->ops->transientvar = tvar;
562: dmts->transientvarctx = ctx;
563: return 0;
564: }
566: /*@C
567: DMTSGetTransientVariable - gets function to transform from state to transient variables
569: Logically Collective
571: Input Parameter:
572: . dm - DM to be used with TS
574: Output Parameters:
575: + tvar - a function that transforms to transient variables
576: - ctx - a context for tvar
578: Level: advanced
580: .seealso: DMTSSetTransientVariable(), DMTSGetIFunction(), DMTSGetIJacobian()
581: @*/
582: PetscErrorCode DMTSGetTransientVariable(DM dm,TSTransientVariable *tvar,void *ctx)
583: {
584: DMTS dmts;
587: DMGetDMTS(dm,&dmts);
588: if (tvar) *tvar = dmts->ops->transientvar;
589: if (ctx) *(void**)ctx = dmts->transientvarctx;
590: return 0;
591: }
593: /*@C
594: DMTSGetSolutionFunction - gets the TS solution evaluation function
596: Not Collective
598: Input Parameter:
599: . dm - DM to be used with TS
601: Output Parameters:
602: + func - solution function evaluation function, see TSSetSolution() for calling sequence
603: - ctx - context for solution evaluation
605: Level: advanced
607: .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian(), DMTSSetSolutionFunction()
608: @*/
609: PetscErrorCode DMTSGetSolutionFunction(DM dm,TSSolutionFunction *func,void **ctx)
610: {
611: DMTS tsdm;
614: DMGetDMTS(dm,&tsdm);
615: if (func) *func = tsdm->ops->solution;
616: if (ctx) *ctx = tsdm->solutionctx;
617: return 0;
618: }
620: /*@C
621: DMTSSetSolutionFunction - set TS solution evaluation function
623: Not Collective
625: Input Parameters:
626: + dm - DM to be used with TS
627: . func - solution function evaluation routine
628: - ctx - context for solution evaluation
630: Calling sequence of f:
631: $ PetscErrorCode f(TS ts,PetscReal t,Vec u,void *ctx);
633: + ts - timestep context
634: . t - current timestep
635: . u - output vector
636: - ctx - [optional] user-defined function context
638: Level: advanced
640: Note:
641: TSSetSolutionFunction() is normally used, but it calls this function internally because the user context is actually
642: associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or
643: not. If DM took a more central role at some later date, this could become the primary method of setting the residual.
645: .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian(), DMTSGetSolutionFunction()
646: @*/
647: PetscErrorCode DMTSSetSolutionFunction(DM dm,TSSolutionFunction func,void *ctx)
648: {
649: DMTS tsdm;
652: DMGetDMTSWrite(dm,&tsdm);
653: if (func) tsdm->ops->solution = func;
654: if (ctx) tsdm->solutionctx = ctx;
655: return 0;
656: }
658: /*@C
659: DMTSSetForcingFunction - set TS forcing function evaluation function
661: Not Collective
663: Input Parameters:
664: + dm - DM to be used with TS
665: . f - forcing function evaluation routine
666: - ctx - context for solution evaluation
668: Calling sequence of func:
669: $ PetscErrorCode func (TS ts,PetscReal t,Vec f,void *ctx);
671: + ts - timestep context
672: . t - current timestep
673: . f - output vector
674: - ctx - [optional] user-defined function context
676: Level: advanced
678: Note:
679: TSSetForcingFunction() is normally used, but it calls this function internally because the user context is actually
680: associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or
681: not. If DM took a more central role at some later date, this could become the primary method of setting the residual.
683: .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian(), TSSetForcingFunction(), DMTSGetForcingFunction()
684: @*/
685: PetscErrorCode DMTSSetForcingFunction(DM dm,TSForcingFunction f,void *ctx)
686: {
687: DMTS tsdm;
690: DMGetDMTSWrite(dm,&tsdm);
691: if (f) tsdm->ops->forcing = f;
692: if (ctx) tsdm->forcingctx = ctx;
693: return 0;
694: }
696: /*@C
697: DMTSGetForcingFunction - get TS forcing function evaluation function
699: Not Collective
701: Input Parameter:
702: . dm - DM to be used with TS
704: Output Parameters:
705: + f - forcing function evaluation function; see TSForcingFunction for details
706: - ctx - context for solution evaluation
708: Level: advanced
710: Note:
711: TSSetForcingFunction() is normally used, but it calls this function internally because the user context is actually
712: associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or
713: not. If DM took a more central role at some later date, this could become the primary method of setting the residual.
715: .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian(), TSSetForcingFunction(), DMTSGetForcingFunction()
716: @*/
717: PetscErrorCode DMTSGetForcingFunction(DM dm,TSForcingFunction *f,void **ctx)
718: {
719: DMTS tsdm;
722: DMGetDMTSWrite(dm,&tsdm);
723: if (f) *f = tsdm->ops->forcing;
724: if (ctx) *ctx = tsdm->forcingctx;
725: return 0;
726: }
728: /*@C
729: DMTSGetRHSFunction - get TS explicit residual evaluation function
731: Not Collective
733: Input Parameter:
734: . dm - DM to be used with TS
736: Output Parameters:
737: + func - residual evaluation function, see TSSetRHSFunction() for calling sequence
738: - ctx - context for residual evaluation
740: Level: advanced
742: Note:
743: TSGetFunction() is normally used, but it calls this function internally because the user context is actually
744: associated with the DM.
746: .seealso: DMTSSetContext(), DMTSSetRHSFunction(), TSSetRHSFunction()
747: @*/
748: PetscErrorCode DMTSGetRHSFunction(DM dm,TSRHSFunction *func,void **ctx)
749: {
750: DMTS tsdm;
753: DMGetDMTS(dm,&tsdm);
754: if (func) *func = tsdm->ops->rhsfunction;
755: if (ctx) *ctx = tsdm->rhsfunctionctx;
756: return 0;
757: }
759: /*@C
760: DMTSSetIJacobian - set TS Jacobian evaluation function
762: Not Collective
764: Input Parameters:
765: + dm - DM to be used with TS
766: . func - Jacobian evaluation routine
767: - ctx - context for residual evaluation
769: Calling sequence of f:
770: $ PetscErrorCode f(TS ts,PetscReal t,Vec U,Vec U_t,PetscReal a,Mat Amat,Mat Pmat,void *ctx);
772: + t - time at step/stage being solved
773: . U - state vector
774: . U_t - time derivative of state vector
775: . a - shift
776: . Amat - (approximate) Jacobian of F(t,U,W+a*U), equivalent to dF/dU + a*dF/dU_t
777: . Pmat - matrix used for constructing preconditioner, usually the same as Amat
778: - ctx - [optional] user-defined context for matrix evaluation routine
780: Level: advanced
782: Note:
783: TSSetJacobian() is normally used, but it calls this function internally because the user context is actually
784: associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or
785: not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian.
787: .seealso: DMTSSetContext(), TSSetRHSFunction(), DMTSGetJacobian(), TSSetIJacobian(), TSSetIFunction()
788: @*/
789: PetscErrorCode DMTSSetIJacobian(DM dm,TSIJacobian func,void *ctx)
790: {
791: DMTS sdm;
794: DMGetDMTSWrite(dm,&sdm);
795: if (func) sdm->ops->ijacobian = func;
796: if (ctx) sdm->ijacobianctx = ctx;
797: return 0;
798: }
800: /*@C
801: DMTSGetIJacobian - get TS Jacobian evaluation function
803: Not Collective
805: Input Parameter:
806: . dm - DM to be used with TS
808: Output Parameters:
809: + func - Jacobian evaluation function, see TSSetIJacobian() for calling sequence
810: - ctx - context for residual evaluation
812: Level: advanced
814: Note:
815: TSGetJacobian() is normally used, but it calls this function internally because the user context is actually
816: associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or
817: not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian.
819: .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian()
820: @*/
821: PetscErrorCode DMTSGetIJacobian(DM dm,TSIJacobian *func,void **ctx)
822: {
823: DMTS tsdm;
826: DMGetDMTS(dm,&tsdm);
827: if (func) *func = tsdm->ops->ijacobian;
828: if (ctx) *ctx = tsdm->ijacobianctx;
829: return 0;
830: }
832: /*@C
833: DMTSSetRHSJacobian - set TS Jacobian evaluation function
835: Not Collective
837: Input Parameters:
838: + dm - DM to be used with TS
839: . func - Jacobian evaluation routine
840: - ctx - context for residual evaluation
842: Calling sequence of func:
843: $ PetscErrorCode func(TS ts,PetscReal t,Vec u,Mat A,Mat B,void *ctx);
845: + t - current timestep
846: . u - input vector
847: . Amat - (approximate) Jacobian matrix
848: . Pmat - matrix from which preconditioner is to be constructed (usually the same as Amat)
849: - ctx - [optional] user-defined context for matrix evaluation routine
851: Level: advanced
853: Note:
854: TSSetJacobian() is normally used, but it calls this function internally because the user context is actually
855: associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or
856: not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian.
858: .seealso: DMTSSetContext(), TSSetFunction(), DMTSGetJacobian(), TSSetRHSJacobian()
859: @*/
860: PetscErrorCode DMTSSetRHSJacobian(DM dm,TSRHSJacobian func,void *ctx)
861: {
862: DMTS tsdm;
865: DMGetDMTSWrite(dm,&tsdm);
866: if (func) tsdm->ops->rhsjacobian = func;
867: if (ctx) tsdm->rhsjacobianctx = ctx;
868: return 0;
869: }
871: /*@C
872: DMTSGetRHSJacobian - get TS Jacobian evaluation function
874: Not Collective
876: Input Parameter:
877: . dm - DM to be used with TS
879: Output Parameters:
880: + func - Jacobian evaluation function, see TSSetRHSJacobian() for calling sequence
881: - ctx - context for residual evaluation
883: Level: advanced
885: Note:
886: TSGetJacobian() is normally used, but it calls this function internally because the user context is actually
887: associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or
888: not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian.
890: .seealso: DMTSSetContext(), TSSetRHSFunction(), DMTSSetRHSJacobian(), TSSetRHSJacobian()
891: @*/
892: PetscErrorCode DMTSGetRHSJacobian(DM dm,TSRHSJacobian *func,void **ctx)
893: {
894: DMTS tsdm;
897: DMGetDMTS(dm,&tsdm);
898: if (func) *func = tsdm->ops->rhsjacobian;
899: if (ctx) *ctx = tsdm->rhsjacobianctx;
900: return 0;
901: }
903: /*@C
904: DMTSSetIFunctionSerialize - sets functions used to view and load a IFunction context
906: Not Collective
908: Input Parameters:
909: + dm - DM to be used with TS
910: . view - viewer function
911: - load - loading function
913: Level: advanced
915: .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian()
916: @*/
917: PetscErrorCode DMTSSetIFunctionSerialize(DM dm,PetscErrorCode (*view)(void*,PetscViewer),PetscErrorCode (*load)(void**,PetscViewer))
918: {
919: DMTS tsdm;
922: DMGetDMTSWrite(dm,&tsdm);
923: tsdm->ops->ifunctionview = view;
924: tsdm->ops->ifunctionload = load;
925: return 0;
926: }
928: /*@C
929: DMTSSetIJacobianSerialize - sets functions used to view and load a IJacobian context
931: Not Collective
933: Input Parameters:
934: + dm - DM to be used with TS
935: . view - viewer function
936: - load - loading function
938: Level: advanced
940: .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian()
941: @*/
942: PetscErrorCode DMTSSetIJacobianSerialize(DM dm,PetscErrorCode (*view)(void*,PetscViewer),PetscErrorCode (*load)(void**,PetscViewer))
943: {
944: DMTS tsdm;
947: DMGetDMTSWrite(dm,&tsdm);
948: tsdm->ops->ijacobianview = view;
949: tsdm->ops->ijacobianload = load;
950: return 0;
951: }