Actual source code: dmts.c
petsc-3.14.6 2021-03-30
1: #include <petsc/private/tsimpl.h>
2: #include <petsc/private/dmimpl.h>
4: static PetscErrorCode DMTSDestroy(DMTS *kdm)
5: {
9: if (!*kdm) return(0);
11: if (--((PetscObject)(*kdm))->refct > 0) {*kdm = NULL; return(0);}
12: if ((*kdm)->ops->destroy) {((*kdm)->ops->destroy)(*kdm);}
13: PetscHeaderDestroy(kdm);
14: return(0);
15: }
17: PetscErrorCode DMTSLoad(DMTS kdm,PetscViewer viewer)
18: {
22: PetscViewerBinaryRead(viewer,&kdm->ops->ifunction,1,NULL,PETSC_FUNCTION);
23: PetscViewerBinaryRead(viewer,&kdm->ops->ifunctionview,1,NULL,PETSC_FUNCTION);
24: PetscViewerBinaryRead(viewer,&kdm->ops->ifunctionload,1,NULL,PETSC_FUNCTION);
25: if (kdm->ops->ifunctionload) {
26: (*kdm->ops->ifunctionload)(&kdm->ifunctionctx,viewer);
27: }
28: PetscViewerBinaryRead(viewer,&kdm->ops->ijacobian,1,NULL,PETSC_FUNCTION);
29: PetscViewerBinaryRead(viewer,&kdm->ops->ijacobianview,1,NULL,PETSC_FUNCTION);
30: PetscViewerBinaryRead(viewer,&kdm->ops->ijacobianload,1,NULL,PETSC_FUNCTION);
31: if (kdm->ops->ijacobianload) {
32: (*kdm->ops->ijacobianload)(&kdm->ijacobianctx,viewer);
33: }
34: return(0);
35: }
37: PetscErrorCode DMTSView(DMTS kdm,PetscViewer viewer)
38: {
40: PetscBool isascii,isbinary;
43: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
44: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);
45: if (isascii) {
46: #if defined(PETSC_SERIALIZE_FUNCTIONS)
47: const char *fname;
49: PetscFPTFind(kdm->ops->ifunction,&fname);
50: if (fname) {
51: PetscViewerASCIIPrintf(viewer," IFunction used by TS: %s\n",fname);
52: }
53: PetscFPTFind(kdm->ops->ijacobian,&fname);
54: if (fname) {
55: PetscViewerASCIIPrintf(viewer," IJacobian function used by TS: %s\n",fname);
56: }
57: #endif
58: } else if (isbinary) {
59: struct {
60: TSIFunction ifunction;
61: } funcstruct;
62: struct {
63: PetscErrorCode (*ifunctionview)(void*,PetscViewer);
64: } funcviewstruct;
65: struct {
66: PetscErrorCode (*ifunctionload)(void**,PetscViewer);
67: } funcloadstruct;
68: struct {
69: TSIJacobian ijacobian;
70: } jacstruct;
71: struct {
72: PetscErrorCode (*ijacobianview)(void*,PetscViewer);
73: } jacviewstruct;
74: struct {
75: PetscErrorCode (*ijacobianload)(void**,PetscViewer);
76: } jacloadstruct;
78: funcstruct.ifunction = kdm->ops->ifunction;
79: funcviewstruct.ifunctionview = kdm->ops->ifunctionview;
80: funcloadstruct.ifunctionload = kdm->ops->ifunctionload;
81: PetscViewerBinaryWrite(viewer,&funcstruct,1,PETSC_FUNCTION);
82: PetscViewerBinaryWrite(viewer,&funcviewstruct,1,PETSC_FUNCTION);
83: PetscViewerBinaryWrite(viewer,&funcloadstruct,1,PETSC_FUNCTION);
84: if (kdm->ops->ifunctionview) {
85: (*kdm->ops->ifunctionview)(kdm->ifunctionctx,viewer);
86: }
87: jacstruct.ijacobian = kdm->ops->ijacobian;
88: jacviewstruct.ijacobianview = kdm->ops->ijacobianview;
89: jacloadstruct.ijacobianload = kdm->ops->ijacobianload;
90: PetscViewerBinaryWrite(viewer,&jacstruct,1,PETSC_FUNCTION);
91: PetscViewerBinaryWrite(viewer,&jacviewstruct,1,PETSC_FUNCTION);
92: PetscViewerBinaryWrite(viewer,&jacloadstruct,1,PETSC_FUNCTION);
93: if (kdm->ops->ijacobianview) {
94: (*kdm->ops->ijacobianview)(kdm->ijacobianctx,viewer);
95: }
96: }
97: return(0);
98: }
100: static PetscErrorCode DMTSCreate(MPI_Comm comm,DMTS *kdm)
101: {
105: TSInitializePackage();
106: PetscHeaderCreate(*kdm, DMTS_CLASSID, "DMTS", "DMTS", "DMTS", comm, DMTSDestroy, DMTSView);
107: return(0);
108: }
110: /* Attaches the DMTS to the coarse level.
111: * Under what conditions should we copy versus duplicate?
112: */
113: static PetscErrorCode DMCoarsenHook_DMTS(DM dm,DM dmc,void *ctx)
114: {
118: DMCopyDMTS(dm,dmc);
119: return(0);
120: }
122: /* This could restrict auxiliary information to the coarse level.
123: */
124: static PetscErrorCode DMRestrictHook_DMTS(DM dm,Mat Restrict,Vec rscale,Mat Inject,DM dmc,void *ctx)
125: {
128: return(0);
129: }
131: static PetscErrorCode DMSubDomainHook_DMTS(DM dm,DM subdm,void *ctx)
132: {
136: DMCopyDMTS(dm,subdm);
137: return(0);
138: }
140: /* This could restrict auxiliary information to the coarse level.
141: */
142: static PetscErrorCode DMSubDomainRestrictHook_DMTS(DM dm,VecScatter gscat,VecScatter lscat,DM subdm,void *ctx)
143: {
145: return(0);
146: }
148: /*@C
149: DMTSCopy - copies the information in a DMTS to another DMTS
151: Not Collective
153: Input Argument:
154: + kdm - Original DMTS
155: - nkdm - DMTS to receive the data, should have been created with DMTSCreate()
157: Level: developer
159: .seealso: DMTSCreate(), DMTSDestroy()
160: @*/
161: PetscErrorCode DMTSCopy(DMTS kdm,DMTS nkdm)
162: {
168: nkdm->ops->rhsfunction = kdm->ops->rhsfunction;
169: nkdm->ops->rhsjacobian = kdm->ops->rhsjacobian;
170: nkdm->ops->ifunction = kdm->ops->ifunction;
171: nkdm->ops->ijacobian = kdm->ops->ijacobian;
172: nkdm->ops->i2function = kdm->ops->i2function;
173: nkdm->ops->i2jacobian = kdm->ops->i2jacobian;
174: nkdm->ops->solution = kdm->ops->solution;
175: nkdm->ops->destroy = kdm->ops->destroy;
176: nkdm->ops->duplicate = kdm->ops->duplicate;
178: nkdm->rhsfunctionctx = kdm->rhsfunctionctx;
179: nkdm->rhsjacobianctx = kdm->rhsjacobianctx;
180: nkdm->ifunctionctx = kdm->ifunctionctx;
181: nkdm->ijacobianctx = kdm->ijacobianctx;
182: nkdm->i2functionctx = kdm->i2functionctx;
183: nkdm->i2jacobianctx = kdm->i2jacobianctx;
184: nkdm->solutionctx = kdm->solutionctx;
186: nkdm->data = kdm->data;
188: /*
189: nkdm->fortran_func_pointers[0] = kdm->fortran_func_pointers[0];
190: nkdm->fortran_func_pointers[1] = kdm->fortran_func_pointers[1];
191: nkdm->fortran_func_pointers[2] = kdm->fortran_func_pointers[2];
192: */
194: /* implementation specific copy hooks */
195: if (kdm->ops->duplicate) {(*kdm->ops->duplicate)(kdm,nkdm);}
196: return(0);
197: }
199: /*@C
200: DMGetDMTS - get read-only private DMTS context from a DM
202: Not Collective
204: Input Argument:
205: . dm - DM to be used with TS
207: Output Argument:
208: . tsdm - private DMTS context
210: Level: developer
212: Notes:
213: Use DMGetDMTSWrite() if write access is needed. The DMTSSetXXX API should be used wherever possible.
215: .seealso: DMGetDMTSWrite()
216: @*/
217: PetscErrorCode DMGetDMTS(DM dm,DMTS *tsdm)
218: {
223: *tsdm = (DMTS) dm->dmts;
224: if (!*tsdm) {
225: PetscInfo(dm,"Creating new DMTS\n");
226: DMTSCreate(PetscObjectComm((PetscObject)dm),tsdm);
227: dm->dmts = (PetscObject) *tsdm;
228: (*tsdm)->originaldm = dm;
229: DMCoarsenHookAdd(dm,DMCoarsenHook_DMTS,DMRestrictHook_DMTS,NULL);
230: DMSubDomainHookAdd(dm,DMSubDomainHook_DMTS,DMSubDomainRestrictHook_DMTS,NULL);
231: }
232: return(0);
233: }
235: /*@C
236: DMGetDMTSWrite - get write access to private DMTS context from a DM
238: Not Collective
240: Input Argument:
241: . dm - DM to be used with TS
243: Output Argument:
244: . tsdm - private DMTS context
246: Level: developer
248: .seealso: DMGetDMTS()
249: @*/
250: PetscErrorCode DMGetDMTSWrite(DM dm,DMTS *tsdm)
251: {
253: DMTS sdm;
257: DMGetDMTS(dm,&sdm);
258: if (!sdm->originaldm) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"DMTS has a NULL originaldm");
259: if (sdm->originaldm != dm) { /* Copy on write */
260: DMTS oldsdm = sdm;
261: PetscInfo(dm,"Copying DMTS due to write\n");
262: DMTSCreate(PetscObjectComm((PetscObject)dm),&sdm);
263: DMTSCopy(oldsdm,sdm);
264: DMTSDestroy((DMTS*)&dm->dmts);
265: dm->dmts = (PetscObject) sdm;
266: sdm->originaldm = dm;
267: }
268: *tsdm = sdm;
269: return(0);
270: }
272: /*@C
273: DMCopyDMTS - copies a DM context to a new DM
275: Logically Collective
277: Input Arguments:
278: + dmsrc - DM to obtain context from
279: - dmdest - DM to add context to
281: Level: developer
283: Note:
284: The context is copied by reference. This function does not ensure that a context exists.
286: .seealso: DMGetDMTS(), TSSetDM()
287: @*/
288: PetscErrorCode DMCopyDMTS(DM dmsrc,DM dmdest)
289: {
295: DMTSDestroy((DMTS*)&dmdest->dmts);
296: dmdest->dmts = dmsrc->dmts;
297: PetscObjectReference(dmdest->dmts);
298: DMCoarsenHookAdd(dmdest,DMCoarsenHook_DMTS,DMRestrictHook_DMTS,NULL);
299: DMSubDomainHookAdd(dmdest,DMSubDomainHook_DMTS,DMSubDomainRestrictHook_DMTS,NULL);
300: return(0);
301: }
303: /*@C
304: DMTSSetIFunction - set TS implicit function evaluation function
306: Not Collective
308: Input Arguments:
309: + dm - DM to be used with TS
310: . func - function evaluating f(t,u,u_t)
311: - ctx - context for residual evaluation
313: Calling sequence of func:
314: $ PetscErrorCode func(TS ts,PetscReal t,Vec u,Vec u_t,Vec F,ctx);
316: + t - time at step/stage being solved
317: . u - state vector
318: . u_t - time derivative of state vector
319: . F - function vector
320: - ctx - [optional] user-defined context for matrix evaluation routine
322: Level: advanced
324: Note:
325: TSSetFunction() is normally used, but it calls this function internally because the user context is actually
326: associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or
327: not. If DM took a more central role at some later date, this could become the primary method of setting the residual.
329: .seealso: DMTSSetContext(), TSSetIFunction(), DMTSSetJacobian()
330: @*/
331: PetscErrorCode DMTSSetIFunction(DM dm,TSIFunction func,void *ctx)
332: {
334: DMTS tsdm;
338: DMGetDMTSWrite(dm,&tsdm);
339: if (func) tsdm->ops->ifunction = func;
340: if (ctx) tsdm->ifunctionctx = ctx;
341: return(0);
342: }
344: /*@C
345: DMTSGetIFunction - get TS implicit residual evaluation function
347: Not Collective
349: Input Argument:
350: . dm - DM to be used with TS
352: Output Arguments:
353: + func - function evaluation function, see TSSetIFunction() for calling sequence
354: - ctx - context for residual evaluation
356: Level: advanced
358: Note:
359: TSGetFunction() is normally used, but it calls this function internally because the user context is actually
360: associated with the DM.
362: .seealso: DMTSSetContext(), DMTSSetFunction(), TSSetFunction()
363: @*/
364: PetscErrorCode DMTSGetIFunction(DM dm,TSIFunction *func,void **ctx)
365: {
367: DMTS tsdm;
371: DMGetDMTS(dm,&tsdm);
372: if (func) *func = tsdm->ops->ifunction;
373: if (ctx) *ctx = tsdm->ifunctionctx;
374: return(0);
375: }
377: /*@C
378: DMTSSetI2Function - set TS implicit function evaluation function for 2nd order systems
380: Not Collective
382: Input Arguments:
383: + dm - DM to be used with TS
384: . fun - function evaluation routine
385: - ctx - context for residual evaluation
387: Calling sequence of fun:
388: $ PetscErrorCode fun(TS ts,PetscReal t,Vec U,Vec U_t,Vec U_tt,Vec F,ctx);
390: + t - time at step/stage being solved
391: . U - state vector
392: . U_t - time derivative of state vector
393: . U_tt - second time derivative of state vector
394: . F - function vector
395: - ctx - [optional] user-defined context for matrix evaluation routine (may be NULL)
397: Level: advanced
399: Note:
400: TSSetI2Function() is normally used, but it calls this function internally because the user context is actually
401: associated with the DM.
403: .seealso: TSSetI2Function()
404: @*/
405: PetscErrorCode DMTSSetI2Function(DM dm,TSI2Function fun,void *ctx)
406: {
407: DMTS tsdm;
412: DMGetDMTSWrite(dm,&tsdm);
413: if (fun) tsdm->ops->i2function = fun;
414: if (ctx) tsdm->i2functionctx = ctx;
415: return(0);
416: }
418: /*@C
419: DMTSGetI2Function - get TS implicit residual evaluation function for 2nd order systems
421: Not Collective
423: Input Argument:
424: . dm - DM to be used with TS
426: Output Arguments:
427: + fun - function evaluation function, see TSSetI2Function() for calling sequence
428: - ctx - context for residual evaluation
430: Level: advanced
432: Note:
433: TSGetI2Function() is normally used, but it calls this function internally because the user context is actually
434: associated with the DM.
436: .seealso: DMTSSetI2Function(),TSGetI2Function()
437: @*/
438: PetscErrorCode DMTSGetI2Function(DM dm,TSI2Function *fun,void **ctx)
439: {
440: DMTS tsdm;
445: DMGetDMTS(dm,&tsdm);
446: if (fun) *fun = tsdm->ops->i2function;
447: if (ctx) *ctx = tsdm->i2functionctx;
448: return(0);
449: }
451: /*@C
452: DMTSSetI2Jacobian - set TS implicit Jacobian evaluation function for 2nd order systems
454: Not Collective
456: Input Arguments:
457: + dm - DM to be used with TS
458: . fun - Jacobian evaluation routine
459: - ctx - context for Jacobian evaluation
461: Calling sequence of jac:
462: $ PetscErrorCode jac(TS ts,PetscReal t,Vec U,Vec U_t,Vec U_tt,PetscReal v,PetscReal a,Mat J,Mat P,void *ctx);
464: + t - time at step/stage being solved
465: . U - state vector
466: . U_t - time derivative of state vector
467: . U_tt - second time derivative of state vector
468: . v - shift for U_t
469: . a - shift for U_tt
470: . 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
471: . P - preconditioning matrix for J, may be same as J
472: - ctx - [optional] user-defined context for matrix evaluation routine
474: Level: advanced
476: Note:
477: TSSetI2Jacobian() is normally used, but it calls this function internally because the user context is actually
478: associated with the DM.
480: .seealso: TSSetI2Jacobian()
481: @*/
482: PetscErrorCode DMTSSetI2Jacobian(DM dm,TSI2Jacobian jac,void *ctx)
483: {
484: DMTS tsdm;
489: DMGetDMTSWrite(dm,&tsdm);
490: if (jac) tsdm->ops->i2jacobian = jac;
491: if (ctx) tsdm->i2jacobianctx = ctx;
492: return(0);
493: }
495: /*@C
496: DMTSGetI2Jacobian - get TS implicit Jacobian evaluation function for 2nd order systems
498: Not Collective
500: Input Argument:
501: . dm - DM to be used with TS
503: Output Arguments:
504: + jac - Jacobian evaluation function, see TSSetI2Jacobian() for calling sequence
505: - ctx - context for Jacobian evaluation
507: Level: advanced
509: Note:
510: TSGetI2Jacobian() is normally used, but it calls this function internally because the user context is actually
511: associated with the DM.
513: .seealso: DMTSSetI2Jacobian(),TSGetI2Jacobian()
514: @*/
515: PetscErrorCode DMTSGetI2Jacobian(DM dm,TSI2Jacobian *jac,void **ctx)
516: {
517: DMTS tsdm;
522: DMGetDMTS(dm,&tsdm);
523: if (jac) *jac = tsdm->ops->i2jacobian;
524: if (ctx) *ctx = tsdm->i2jacobianctx;
525: return(0);
526: }
528: /*@C
529: DMTSSetRHSFunction - set TS explicit residual evaluation function
531: Not Collective
533: Input Arguments:
534: + dm - DM to be used with TS
535: . func - RHS function evaluation routine
536: - ctx - context for residual evaluation
538: Calling sequence of func:
539: $ PetscErrorCode func(TS ts,PetscReal t,Vec u,Vec F,void *ctx);
541: + ts - timestep context
542: . t - current timestep
543: . u - input vector
544: . F - function vector
545: - ctx - [optional] user-defined function context
547: Level: advanced
549: Note:
550: TSSetRSHFunction() is normally used, but it calls this function internally because the user context is actually
551: associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or
552: not. If DM took a more central role at some later date, this could become the primary method of setting the residual.
554: .seealso: DMTSSetContext(), TSSetRHSFunction(), DMTSSetJacobian()
555: @*/
556: PetscErrorCode DMTSSetRHSFunction(DM dm,TSRHSFunction func,void *ctx)
557: {
559: DMTS tsdm;
563: DMGetDMTSWrite(dm,&tsdm);
564: if (func) tsdm->ops->rhsfunction = func;
565: if (ctx) tsdm->rhsfunctionctx = ctx;
566: return(0);
567: }
569: /*@C
570: DMTSSetTransientVariable - sets function to transform from state to transient variables
572: Logically Collective
574: Input Arguments:
575: + dm - DM to be used with TS
576: . tvar - a function that transforms to transient variables
577: - ctx - a context for tvar
579: Calling sequence of tvar:
580: $ PetscErrorCode tvar(TS ts,Vec p,Vec c,void *ctx);
582: + ts - timestep context
583: . p - input vector (primative form)
584: . c - output vector, transient variables (conservative form)
585: - ctx - [optional] user-defined function context
587: Level: advanced
589: Notes:
590: This is typically used to transform from primitive to conservative variables so that a time integrator (e.g., TSBDF)
591: can be conservative. In this context, primitive variables P are used to model the state (e.g., because they lead to
592: well-conditioned formulations even in limiting cases such as low-Mach or zero porosity). The transient variable is
593: C(P), specified by calling this function. An IFunction thus receives arguments (P, Cdot) and the IJacobian must be
594: evaluated via the chain rule, as in
596: dF/dP + shift * dF/dCdot dC/dP.
598: .seealso: TSSetTransientVariable(), DMTSGetTransientVariable(), DMTSSetIFunction(), DMTSSetIJacobian()
599: @*/
600: PetscErrorCode DMTSSetTransientVariable(DM dm,TSTransientVariable tvar,void *ctx)
601: {
603: DMTS dmts;
607: DMGetDMTSWrite(dm,&dmts);
608: dmts->ops->transientvar = tvar;
609: dmts->transientvarctx = ctx;
610: return(0);
611: }
613: /*@C
614: DMTSGetTransientVariable - gets function to transform from state to transient variables
616: Logically Collective
618: Input Arguments:
619: . dm - DM to be used with TS
621: Output Arguments:
622: + tvar - a function that transforms to transient variables
623: - ctx - a context for tvar
625: Level: advanced
627: .seealso: DMTSSetTransientVariable(), DMTSGetIFunction(), DMTSGetIJacobian()
628: @*/
629: PetscErrorCode DMTSGetTransientVariable(DM dm,TSTransientVariable *tvar,void *ctx)
630: {
632: DMTS dmts;
636: DMGetDMTS(dm,&dmts);
637: if (tvar) *tvar = dmts->ops->transientvar;
638: if (ctx) *(void**)ctx = dmts->transientvarctx;
639: return(0);
640: }
642: /*@C
643: DMTSGetSolutionFunction - gets the TS solution evaluation function
645: Not Collective
647: Input Arguments:
648: . dm - DM to be used with TS
650: Output Parameters:
651: + func - solution function evaluation function, see TSSetSolution() for calling sequence
652: - ctx - context for solution evaluation
654: Level: advanced
656: .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian(), DMTSSetSolutionFunction()
657: @*/
658: PetscErrorCode DMTSGetSolutionFunction(DM dm,TSSolutionFunction *func,void **ctx)
659: {
661: DMTS tsdm;
665: DMGetDMTS(dm,&tsdm);
666: if (func) *func = tsdm->ops->solution;
667: if (ctx) *ctx = tsdm->solutionctx;
668: return(0);
669: }
671: /*@C
672: DMTSSetSolutionFunction - set TS solution evaluation function
674: Not Collective
676: Input Arguments:
677: + dm - DM to be used with TS
678: . func - solution function evaluation routine
679: - ctx - context for solution evaluation
681: Calling sequence of f:
682: $ PetscErrorCode f(TS ts,PetscReal t,Vec u,void *ctx);
684: + ts - timestep context
685: . t - current timestep
686: . u - output vector
687: - ctx - [optional] user-defined function context
689: Level: advanced
691: Note:
692: TSSetSolutionFunction() is normally used, but it calls this function internally because the user context is actually
693: associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or
694: not. If DM took a more central role at some later date, this could become the primary method of setting the residual.
696: .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian(), DMTSGetSolutionFunction()
697: @*/
698: PetscErrorCode DMTSSetSolutionFunction(DM dm,TSSolutionFunction func,void *ctx)
699: {
701: DMTS tsdm;
705: DMGetDMTSWrite(dm,&tsdm);
706: if (func) tsdm->ops->solution = func;
707: if (ctx) tsdm->solutionctx = ctx;
708: return(0);
709: }
711: /*@C
712: DMTSSetForcingFunction - set TS forcing function evaluation function
714: Not Collective
716: Input Arguments:
717: + dm - DM to be used with TS
718: . f - forcing function evaluation routine
719: - ctx - context for solution evaluation
721: Calling sequence of func:
722: $ PetscErrorCode func (TS ts,PetscReal t,Vec f,void *ctx);
724: + ts - timestep context
725: . t - current timestep
726: . f - output vector
727: - ctx - [optional] user-defined function context
729: Level: advanced
731: Note:
732: TSSetForcingFunction() is normally used, but it calls this function internally because the user context is actually
733: associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or
734: not. If DM took a more central role at some later date, this could become the primary method of setting the residual.
736: .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian(), TSSetForcingFunction(), DMTSGetForcingFunction()
737: @*/
738: PetscErrorCode DMTSSetForcingFunction(DM dm,TSForcingFunction f,void *ctx)
739: {
741: DMTS tsdm;
745: DMGetDMTSWrite(dm,&tsdm);
746: if (f) tsdm->ops->forcing = f;
747: if (ctx) tsdm->forcingctx = ctx;
748: return(0);
749: }
752: /*@C
753: DMTSGetForcingFunction - get TS forcing function evaluation function
755: Not Collective
757: Input Argument:
758: . dm - DM to be used with TS
760: Output Arguments:
761: + f - forcing function evaluation function; see TSForcingFunction for details
762: - ctx - context for solution evaluation
764: Level: advanced
766: Note:
767: TSSetForcingFunction() is normally used, but it calls this function internally because the user context is actually
768: associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or
769: not. If DM took a more central role at some later date, this could become the primary method of setting the residual.
771: .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian(), TSSetForcingFunction(), DMTSGetForcingFunction()
772: @*/
773: PetscErrorCode DMTSGetForcingFunction(DM dm,TSForcingFunction *f,void **ctx)
774: {
776: DMTS tsdm;
780: DMGetDMTSWrite(dm,&tsdm);
781: if (f) *f = tsdm->ops->forcing;
782: if (ctx) *ctx = tsdm->forcingctx;
783: return(0);
784: }
786: /*@C
787: DMTSGetRHSFunction - get TS explicit residual evaluation function
789: Not Collective
791: Input Argument:
792: . dm - DM to be used with TS
794: Output Arguments:
795: + func - residual evaluation function, see TSSetRHSFunction() for calling sequence
796: - ctx - context for residual evaluation
798: Level: advanced
800: Note:
801: TSGetFunction() is normally used, but it calls this function internally because the user context is actually
802: associated with the DM.
804: .seealso: DMTSSetContext(), DMTSSetRHSFunction(), TSSetRHSFunction()
805: @*/
806: PetscErrorCode DMTSGetRHSFunction(DM dm,TSRHSFunction *func,void **ctx)
807: {
809: DMTS tsdm;
813: DMGetDMTS(dm,&tsdm);
814: if (func) *func = tsdm->ops->rhsfunction;
815: if (ctx) *ctx = tsdm->rhsfunctionctx;
816: return(0);
817: }
819: /*@C
820: DMTSSetIJacobian - set TS Jacobian evaluation function
822: Not Collective
824: Input Argument:
825: + dm - DM to be used with TS
826: . func - Jacobian evaluation routine
827: - ctx - context for residual evaluation
829: Calling sequence of f:
830: $ PetscErrorCode f(TS ts,PetscReal t,Vec U,Vec U_t,PetscReal a,Mat Amat,Mat Pmat,void *ctx);
832: + t - time at step/stage being solved
833: . U - state vector
834: . U_t - time derivative of state vector
835: . a - shift
836: . Amat - (approximate) Jacobian of F(t,U,W+a*U), equivalent to dF/dU + a*dF/dU_t
837: . Pmat - matrix used for constructing preconditioner, usually the same as Amat
838: - ctx - [optional] user-defined context for matrix evaluation routine
840: Level: advanced
842: Note:
843: TSSetJacobian() is normally used, but it calls this function internally because the user context is actually
844: associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or
845: not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian.
847: .seealso: DMTSSetContext(), TSSetRHSFunction(), DMTSGetJacobian(), TSSetIJacobian(), TSSetIFunction()
848: @*/
849: PetscErrorCode DMTSSetIJacobian(DM dm,TSIJacobian func,void *ctx)
850: {
852: DMTS sdm;
856: DMGetDMTSWrite(dm,&sdm);
857: if (func) sdm->ops->ijacobian = func;
858: if (ctx) sdm->ijacobianctx = ctx;
859: return(0);
860: }
862: /*@C
863: DMTSGetIJacobian - get TS Jacobian evaluation function
865: Not Collective
867: Input Argument:
868: . dm - DM to be used with TS
870: Output Arguments:
871: + func - Jacobian evaluation function, see TSSetIJacobian() for calling sequence
872: - ctx - context for residual evaluation
874: Level: advanced
876: Note:
877: TSGetJacobian() is normally used, but it calls this function internally because the user context is actually
878: associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or
879: not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian.
881: .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian()
882: @*/
883: PetscErrorCode DMTSGetIJacobian(DM dm,TSIJacobian *func,void **ctx)
884: {
886: DMTS tsdm;
890: DMGetDMTS(dm,&tsdm);
891: if (func) *func = tsdm->ops->ijacobian;
892: if (ctx) *ctx = tsdm->ijacobianctx;
893: return(0);
894: }
896: /*@C
897: DMTSSetRHSJacobian - set TS Jacobian evaluation function
899: Not Collective
901: Input Argument:
902: + dm - DM to be used with TS
903: . func - Jacobian evaluation routine
904: - ctx - context for residual evaluation
906: Calling sequence of func:
907: $ PetscErrorCode func(TS ts,PetscReal t,Vec u,Mat A,Mat B,void *ctx);
909: + t - current timestep
910: . u - input vector
911: . Amat - (approximate) Jacobian matrix
912: . Pmat - matrix from which preconditioner is to be constructed (usually the same as Amat)
913: - ctx - [optional] user-defined context for matrix evaluation routine
915: Level: advanced
917: Note:
918: TSSetJacobian() is normally used, but it calls this function internally because the user context is actually
919: associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or
920: not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian.
922: .seealso: DMTSSetContext(), TSSetFunction(), DMTSGetJacobian(), TSSetRHSJacobian()
923: @*/
924: PetscErrorCode DMTSSetRHSJacobian(DM dm,TSRHSJacobian func,void *ctx)
925: {
927: DMTS tsdm;
931: DMGetDMTSWrite(dm,&tsdm);
932: if (func) tsdm->ops->rhsjacobian = func;
933: if (ctx) tsdm->rhsjacobianctx = ctx;
934: return(0);
935: }
937: /*@C
938: DMTSGetRHSJacobian - get TS Jacobian evaluation function
940: Not Collective
942: Input Argument:
943: . dm - DM to be used with TS
945: Output Arguments:
946: + func - Jacobian evaluation function, see TSSetRHSJacobian() for calling sequence
947: - ctx - context for residual evaluation
949: Level: advanced
951: Note:
952: TSGetJacobian() is normally used, but it calls this function internally because the user context is actually
953: associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or
954: not. If DM took a more central role at some later date, this could become the primary method of setting the Jacobian.
956: .seealso: DMTSSetContext(), TSSetRHSFunction(), DMTSSetRHSJacobian(), TSSetRHSJacobian()
957: @*/
958: PetscErrorCode DMTSGetRHSJacobian(DM dm,TSRHSJacobian *func,void **ctx)
959: {
961: DMTS tsdm;
965: DMGetDMTS(dm,&tsdm);
966: if (func) *func = tsdm->ops->rhsjacobian;
967: if (ctx) *ctx = tsdm->rhsjacobianctx;
968: return(0);
969: }
971: /*@C
972: DMTSSetIFunctionSerialize - sets functions used to view and load a IFunction context
974: Not Collective
976: Input Arguments:
977: + dm - DM to be used with TS
978: . view - viewer function
979: - load - loading function
981: Level: advanced
983: .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian()
984: @*/
985: PetscErrorCode DMTSSetIFunctionSerialize(DM dm,PetscErrorCode (*view)(void*,PetscViewer),PetscErrorCode (*load)(void**,PetscViewer))
986: {
988: DMTS tsdm;
992: DMGetDMTSWrite(dm,&tsdm);
993: tsdm->ops->ifunctionview = view;
994: tsdm->ops->ifunctionload = load;
995: return(0);
996: }
998: /*@C
999: DMTSSetIJacobianSerialize - sets functions used to view and load a IJacobian context
1001: Not Collective
1003: Input Arguments:
1004: + dm - DM to be used with TS
1005: . view - viewer function
1006: - load - loading function
1008: Level: advanced
1010: .seealso: DMTSSetContext(), TSSetFunction(), DMTSSetJacobian()
1011: @*/
1012: PetscErrorCode DMTSSetIJacobianSerialize(DM dm,PetscErrorCode (*view)(void*,PetscViewer),PetscErrorCode (*load)(void**,PetscViewer))
1013: {
1015: DMTS tsdm;
1019: DMGetDMTSWrite(dm,&tsdm);
1020: tsdm->ops->ijacobianview = view;
1021: tsdm->ops->ijacobianload = load;
1022: return(0);
1023: }