xref: /petsc/src/ts/impls/explicit/ssp/ssp.c (revision 2b8d69ca7ea5fe9190df62c1dce3bbd66fce84dd)
1 /*
2        Code for Timestepping with explicit SSP.
3 */
4 #include <petsc/private/tsimpl.h>                /*I   "petscts.h"   I*/
5 
6 PetscFunctionList TSSSPList = 0;
7 static PetscBool TSSSPPackageInitialized;
8 
9 typedef struct {
10   PetscErrorCode (*onestep)(TS,PetscReal,PetscReal,Vec);
11   char           *type_name;
12   PetscInt       nstages;
13   Vec            *work;
14   PetscInt       nwork;
15   PetscBool      workout;
16 } TS_SSP;
17 
18 
19 #undef __FUNCT__
20 #define __FUNCT__ "TSSSPGetWorkVectors"
21 static PetscErrorCode TSSSPGetWorkVectors(TS ts,PetscInt n,Vec **work)
22 {
23   TS_SSP         *ssp = (TS_SSP*)ts->data;
24   PetscErrorCode ierr;
25 
26   PetscFunctionBegin;
27   if (ssp->workout) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Work vectors already gotten");
28   if (ssp->nwork < n) {
29     if (ssp->nwork > 0) {
30       ierr = VecDestroyVecs(ssp->nwork,&ssp->work);CHKERRQ(ierr);
31     }
32     ierr = VecDuplicateVecs(ts->vec_sol,n,&ssp->work);CHKERRQ(ierr);
33     ssp->nwork = n;
34   }
35   *work = ssp->work;
36   ssp->workout = PETSC_TRUE;
37   PetscFunctionReturn(0);
38 }
39 
40 #undef __FUNCT__
41 #define __FUNCT__ "TSSSPRestoreWorkVectors"
42 static PetscErrorCode TSSSPRestoreWorkVectors(TS ts,PetscInt n,Vec **work)
43 {
44   TS_SSP *ssp = (TS_SSP*)ts->data;
45 
46   PetscFunctionBegin;
47   if (!ssp->workout) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Work vectors have not been gotten");
48   if (*work != ssp->work) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Wrong work vectors checked out");
49   ssp->workout = PETSC_FALSE;
50   *work = NULL;
51   PetscFunctionReturn(0);
52 }
53 
54 #undef __FUNCT__
55 #define __FUNCT__ "TSSSPStep_RK_2"
56 /*MC
57    TSSSPRKS2 - Optimal second order SSP Runge-Kutta method, low-storage, c_eff=(s-1)/s
58 
59    Pseudocode 2 of Ketcheson 2008
60 
61    Level: beginner
62 
63 .seealso: TSSSP, TSSSPSetType(), TSSSPSetNumStages()
64 M*/
65 static PetscErrorCode TSSSPStep_RK_2(TS ts,PetscReal t0,PetscReal dt,Vec sol)
66 {
67   TS_SSP         *ssp = (TS_SSP*)ts->data;
68   Vec            *work,F;
69   PetscInt       i,s;
70   PetscErrorCode ierr;
71 
72   PetscFunctionBegin;
73   s    = ssp->nstages;
74   ierr = TSSSPGetWorkVectors(ts,2,&work);CHKERRQ(ierr);
75   F    = work[1];
76   ierr = VecCopy(sol,work[0]);CHKERRQ(ierr);
77   for (i=0; i<s-1; i++) {
78     PetscReal stage_time = t0+dt*(i/(s-1.));
79     ierr = TSPreStage(ts,stage_time);CHKERRQ(ierr);
80     ierr = TSComputeRHSFunction(ts,stage_time,work[0],F);CHKERRQ(ierr);
81     ierr = VecAXPY(work[0],dt/(s-1.),F);CHKERRQ(ierr);
82   }
83   ierr = TSComputeRHSFunction(ts,t0+dt,work[0],F);CHKERRQ(ierr);
84   ierr = VecAXPBYPCZ(sol,(s-1.)/s,dt/s,1./s,work[0],F);CHKERRQ(ierr);
85   ierr = TSSSPRestoreWorkVectors(ts,2,&work);CHKERRQ(ierr);
86   PetscFunctionReturn(0);
87 }
88 
89 #undef __FUNCT__
90 #define __FUNCT__ "TSSSPStep_RK_3"
91 /*MC
92    TSSSPRKS3 - Optimal third order SSP Runge-Kutta, low-storage, c_eff=(PetscSqrtReal(s)-1)/PetscSqrtReal(s), where PetscSqrtReal(s) is an integer
93 
94    Pseudocode 2 of Ketcheson 2008
95 
96    Level: beginner
97 
98 .seealso: TSSSP, TSSSPSetType(), TSSSPSetNumStages()
99 M*/
100 static PetscErrorCode TSSSPStep_RK_3(TS ts,PetscReal t0,PetscReal dt,Vec sol)
101 {
102   TS_SSP         *ssp = (TS_SSP*)ts->data;
103   Vec            *work,F;
104   PetscInt       i,s,n,r;
105   PetscReal      c,stage_time;
106   PetscErrorCode ierr;
107 
108   PetscFunctionBegin;
109   s = ssp->nstages;
110   n = (PetscInt)(PetscSqrtReal((PetscReal)s)+0.001);
111   r = s-n;
112   if (n*n != s) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for optimal third order schemes with %d stages, must be a square number at least 4",s);
113   ierr = TSSSPGetWorkVectors(ts,3,&work);CHKERRQ(ierr);
114   F    = work[2];
115   ierr = VecCopy(sol,work[0]);CHKERRQ(ierr);
116   for (i=0; i<(n-1)*(n-2)/2; i++) {
117     c          = (i<n*(n+1)/2) ? 1.*i/(s-n) : (1.*i-n)/(s-n);
118     stage_time = t0+c*dt;
119     ierr       = TSPreStage(ts,stage_time);CHKERRQ(ierr);
120     ierr       = TSComputeRHSFunction(ts,stage_time,work[0],F);CHKERRQ(ierr);
121     ierr       = VecAXPY(work[0],dt/r,F);CHKERRQ(ierr);
122   }
123   ierr = VecCopy(work[0],work[1]);CHKERRQ(ierr);
124   for (; i<n*(n+1)/2-1; i++) {
125     c          = (i<n*(n+1)/2) ? 1.*i/(s-n) : (1.*i-n)/(s-n);
126     stage_time = t0+c*dt;
127     ierr       = TSPreStage(ts,stage_time);CHKERRQ(ierr);
128     ierr       = TSComputeRHSFunction(ts,stage_time,work[0],F);CHKERRQ(ierr);
129     ierr       = VecAXPY(work[0],dt/r,F);CHKERRQ(ierr);
130   }
131   {
132     c          = (i<n*(n+1)/2) ? 1.*i/(s-n) : (1.*i-n)/(s-n);
133     stage_time = t0+c*dt;
134     ierr       = TSPreStage(ts,stage_time);CHKERRQ(ierr);
135     ierr       = TSComputeRHSFunction(ts,stage_time,work[0],F);CHKERRQ(ierr);
136     ierr       = VecAXPBYPCZ(work[0],1.*n/(2*n-1.),(n-1.)*dt/(r*(2*n-1)),(n-1.)/(2*n-1.),work[1],F);CHKERRQ(ierr);
137     i++;
138   }
139   for (; i<s; i++) {
140     c          = (i<n*(n+1)/2) ? 1.*i/(s-n) : (1.*i-n)/(s-n);
141     stage_time = t0+c*dt;
142     ierr       = TSPreStage(ts,stage_time);CHKERRQ(ierr);
143     ierr       = TSComputeRHSFunction(ts,stage_time,work[0],F);CHKERRQ(ierr);
144     ierr       = VecAXPY(work[0],dt/r,F);CHKERRQ(ierr);
145   }
146   ierr = VecCopy(work[0],sol);CHKERRQ(ierr);
147   ierr = TSSSPRestoreWorkVectors(ts,3,&work);CHKERRQ(ierr);
148   PetscFunctionReturn(0);
149 }
150 
151 #undef __FUNCT__
152 #define __FUNCT__ "TSSSPStep_RK_10_4"
153 /*MC
154    TSSSPRKS104 - Optimal fourth order SSP Runge-Kutta, low-storage (2N), c_eff=0.6
155 
156    SSPRK(10,4), Pseudocode 3 of Ketcheson 2008
157 
158    Level: beginner
159 
160 .seealso: TSSSP, TSSSPSetType()
161 M*/
162 static PetscErrorCode TSSSPStep_RK_10_4(TS ts,PetscReal t0,PetscReal dt,Vec sol)
163 {
164   const PetscReal c[10] = {0, 1./6, 2./6, 3./6, 4./6, 2./6, 3./6, 4./6, 5./6, 1};
165   Vec             *work,F;
166   PetscInt        i;
167   PetscReal       stage_time;
168   PetscErrorCode  ierr;
169 
170   PetscFunctionBegin;
171   ierr = TSSSPGetWorkVectors(ts,3,&work);CHKERRQ(ierr);
172   F    = work[2];
173   ierr = VecCopy(sol,work[0]);CHKERRQ(ierr);
174   for (i=0; i<5; i++) {
175     stage_time = t0+c[i]*dt;
176     ierr       = TSPreStage(ts,stage_time);CHKERRQ(ierr);
177     ierr       = TSComputeRHSFunction(ts,stage_time,work[0],F);CHKERRQ(ierr);
178     ierr       = VecAXPY(work[0],dt/6,F);CHKERRQ(ierr);
179   }
180   ierr = VecAXPBYPCZ(work[1],1./25,9./25,0,sol,work[0]);CHKERRQ(ierr);
181   ierr = VecAXPBY(work[0],15,-5,work[1]);CHKERRQ(ierr);
182   for (; i<9; i++) {
183     stage_time = t0+c[i]*dt;
184     ierr       = TSPreStage(ts,stage_time);CHKERRQ(ierr);
185     ierr       = TSComputeRHSFunction(ts,stage_time,work[0],F);CHKERRQ(ierr);
186     ierr       = VecAXPY(work[0],dt/6,F);CHKERRQ(ierr);
187   }
188   stage_time = t0+dt;
189   ierr       = TSPreStage(ts,stage_time);CHKERRQ(ierr);
190   ierr       = TSComputeRHSFunction(ts,stage_time,work[0],F);CHKERRQ(ierr);
191   ierr       = VecAXPBYPCZ(work[1],3./5,dt/10,1,work[0],F);CHKERRQ(ierr);
192   ierr       = VecCopy(work[1],sol);CHKERRQ(ierr);
193   ierr       = TSSSPRestoreWorkVectors(ts,3,&work);CHKERRQ(ierr);
194   PetscFunctionReturn(0);
195 }
196 
197 
198 #undef __FUNCT__
199 #define __FUNCT__ "TSSetUp_SSP"
200 static PetscErrorCode TSSetUp_SSP(TS ts)
201 {
202 
203   PetscFunctionBegin;
204   PetscFunctionReturn(0);
205 }
206 
207 #undef __FUNCT__
208 #define __FUNCT__ "TSStep_SSP"
209 static PetscErrorCode TSStep_SSP(TS ts)
210 {
211   TS_SSP         *ssp = (TS_SSP*)ts->data;
212   Vec            sol  = ts->vec_sol;
213   PetscErrorCode ierr;
214 
215   PetscFunctionBegin;
216   ierr = TSPreStep(ts);CHKERRQ(ierr);
217   ierr = (*ssp->onestep)(ts,ts->ptime,ts->time_step,sol);CHKERRQ(ierr);
218   ts->ptime += ts->time_step;
219   ts->steps++;
220   PetscFunctionReturn(0);
221 }
222 /*------------------------------------------------------------*/
223 #undef __FUNCT__
224 #define __FUNCT__ "TSReset_SSP"
225 static PetscErrorCode TSReset_SSP(TS ts)
226 {
227   TS_SSP         *ssp = (TS_SSP*)ts->data;
228   PetscErrorCode ierr;
229 
230   PetscFunctionBegin;
231   if (ssp->work) {ierr = VecDestroyVecs(ssp->nwork,&ssp->work);CHKERRQ(ierr);}
232   ssp->nwork   = 0;
233   ssp->workout = PETSC_FALSE;
234   PetscFunctionReturn(0);
235 }
236 
237 #undef __FUNCT__
238 #define __FUNCT__ "TSDestroy_SSP"
239 static PetscErrorCode TSDestroy_SSP(TS ts)
240 {
241   TS_SSP         *ssp = (TS_SSP*)ts->data;
242   PetscErrorCode ierr;
243 
244   PetscFunctionBegin;
245   ierr = TSReset_SSP(ts);CHKERRQ(ierr);
246   ierr = PetscFree(ssp->type_name);CHKERRQ(ierr);
247   ierr = PetscFree(ts->data);CHKERRQ(ierr);
248   ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSSPGetType_C",NULL);CHKERRQ(ierr);
249   ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSSPSetType_C",NULL);CHKERRQ(ierr);
250   ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSSPGetNumStages_C",NULL);CHKERRQ(ierr);
251   ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSSPSetNumStages_C",NULL);CHKERRQ(ierr);
252   PetscFunctionReturn(0);
253 }
254 /*------------------------------------------------------------*/
255 
256 #undef __FUNCT__
257 #define __FUNCT__ "TSSSPSetType"
258 /*@C
259    TSSSPSetType - set the SSP time integration scheme to use
260 
261    Logically Collective
262 
263    Input Arguments:
264    ts - time stepping object
265    type - type of scheme to use
266 
267    Options Database Keys:
268    -ts_ssp_type <rks2>: Type of SSP method (one of) rks2 rks3 rk104
269    -ts_ssp_nstages <5>: Number of stages
270 
271    Level: beginner
272 
273 .seealso: TSSSP, TSSSPGetType(), TSSSPSetNumStages(), TSSSPRKS2, TSSSPRKS3, TSSSPRK104
274 @*/
275 PetscErrorCode TSSSPSetType(TS ts,TSSSPType type)
276 {
277   PetscErrorCode ierr;
278 
279   PetscFunctionBegin;
280   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
281   ierr = PetscTryMethod(ts,"TSSSPSetType_C",(TS,TSSSPType),(ts,type));CHKERRQ(ierr);
282   PetscFunctionReturn(0);
283 }
284 
285 #undef __FUNCT__
286 #define __FUNCT__ "TSSSPGetType"
287 /*@C
288    TSSSPGetType - get the SSP time integration scheme
289 
290    Logically Collective
291 
292    Input Argument:
293    ts - time stepping object
294 
295    Output Argument:
296    type - type of scheme being used
297 
298    Level: beginner
299 
300 .seealso: TSSSP, TSSSPSettype(), TSSSPSetNumStages(), TSSSPRKS2, TSSSPRKS3, TSSSPRK104
301 @*/
302 PetscErrorCode TSSSPGetType(TS ts,TSSSPType *type)
303 {
304   PetscErrorCode ierr;
305 
306   PetscFunctionBegin;
307   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
308   ierr = PetscTryMethod(ts,"TSSSPGetType_C",(TS,TSSSPType*),(ts,type));CHKERRQ(ierr);
309   PetscFunctionReturn(0);
310 }
311 
312 #undef __FUNCT__
313 #define __FUNCT__ "TSSSPSetNumStages"
314 /*@
315    TSSSPSetNumStages - set the number of stages to use with the SSP method
316 
317    Logically Collective
318 
319    Input Arguments:
320    ts - time stepping object
321    nstages - number of stages
322 
323    Options Database Keys:
324    -ts_ssp_type <rks2>: NumStages of SSP method (one of) rks2 rks3 rk104
325    -ts_ssp_nstages <5>: Number of stages
326 
327    Level: beginner
328 
329 .seealso: TSSSP, TSSSPGetNumStages(), TSSSPSetNumStages(), TSSSPRKS2, TSSSPRKS3, TSSSPRK104
330 @*/
331 PetscErrorCode TSSSPSetNumStages(TS ts,PetscInt nstages)
332 {
333   PetscErrorCode ierr;
334 
335   PetscFunctionBegin;
336   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
337   ierr = PetscTryMethod(ts,"TSSSPSetNumStages_C",(TS,PetscInt),(ts,nstages));CHKERRQ(ierr);
338   PetscFunctionReturn(0);
339 }
340 
341 #undef __FUNCT__
342 #define __FUNCT__ "TSSSPGetNumStages"
343 /*@
344    TSSSPGetNumStages - get the number of stages in the SSP time integration scheme
345 
346    Logically Collective
347 
348    Input Argument:
349    ts - time stepping object
350 
351    Output Argument:
352    nstages - number of stages
353 
354    Level: beginner
355 
356 .seealso: TSSSP, TSSSPGetType(), TSSSPSetNumStages(), TSSSPRKS2, TSSSPRKS3, TSSSPRK104
357 @*/
358 PetscErrorCode TSSSPGetNumStages(TS ts,PetscInt *nstages)
359 {
360   PetscErrorCode ierr;
361 
362   PetscFunctionBegin;
363   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
364   ierr = PetscTryMethod(ts,"TSSSPGetNumStages_C",(TS,PetscInt*),(ts,nstages));CHKERRQ(ierr);
365   PetscFunctionReturn(0);
366 }
367 
368 #undef __FUNCT__
369 #define __FUNCT__ "TSSSPSetType_SSP"
370 static PetscErrorCode TSSSPSetType_SSP(TS ts,TSSSPType type)
371 {
372   PetscErrorCode ierr,(*r)(TS,PetscReal,PetscReal,Vec);
373   TS_SSP         *ssp = (TS_SSP*)ts->data;
374 
375   PetscFunctionBegin;
376   ierr = PetscFunctionListFind(TSSSPList,type,&r);CHKERRQ(ierr);
377   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown TS_SSP type %s given",type);
378   ssp->onestep = r;
379   ierr = PetscFree(ssp->type_name);CHKERRQ(ierr);
380   ierr = PetscStrallocpy(type,&ssp->type_name);CHKERRQ(ierr);
381   PetscFunctionReturn(0);
382 }
383 #undef __FUNCT__
384 #define __FUNCT__ "TSSSPGetType_SSP"
385 static PetscErrorCode TSSSPGetType_SSP(TS ts,TSSSPType *type)
386 {
387   TS_SSP *ssp = (TS_SSP*)ts->data;
388 
389   PetscFunctionBegin;
390   *type = ssp->type_name;
391   PetscFunctionReturn(0);
392 }
393 #undef __FUNCT__
394 #define __FUNCT__ "TSSSPSetNumStages_SSP"
395 static PetscErrorCode TSSSPSetNumStages_SSP(TS ts,PetscInt nstages)
396 {
397   TS_SSP *ssp = (TS_SSP*)ts->data;
398 
399   PetscFunctionBegin;
400   ssp->nstages = nstages;
401   PetscFunctionReturn(0);
402 }
403 #undef __FUNCT__
404 #define __FUNCT__ "TSSSPGetNumStages_SSP"
405 static PetscErrorCode TSSSPGetNumStages_SSP(TS ts,PetscInt *nstages)
406 {
407   TS_SSP *ssp = (TS_SSP*)ts->data;
408 
409   PetscFunctionBegin;
410   *nstages = ssp->nstages;
411   PetscFunctionReturn(0);
412 }
413 
414 #undef __FUNCT__
415 #define __FUNCT__ "TSSetFromOptions_SSP"
416 static PetscErrorCode TSSetFromOptions_SSP(PetscOptionItems *PetscOptionsObject,TS ts)
417 {
418   char           tname[256] = TSSSPRKS2;
419   TS_SSP         *ssp       = (TS_SSP*)ts->data;
420   PetscErrorCode ierr;
421   PetscBool      flg;
422 
423   PetscFunctionBegin;
424   ierr = PetscOptionsHead(PetscOptionsObject,"SSP ODE solver options");CHKERRQ(ierr);
425   {
426     ierr = PetscOptionsFList("-ts_ssp_type","Type of SSP method","TSSSPSetType",TSSSPList,tname,tname,sizeof(tname),&flg);CHKERRQ(ierr);
427     if (flg) {
428       ierr = TSSSPSetType(ts,tname);CHKERRQ(ierr);
429     }
430     ierr = PetscOptionsInt("-ts_ssp_nstages","Number of stages","TSSSPSetNumStages",ssp->nstages,&ssp->nstages,NULL);CHKERRQ(ierr);
431   }
432   ierr = PetscOptionsTail();CHKERRQ(ierr);
433   PetscFunctionReturn(0);
434 }
435 
436 #undef __FUNCT__
437 #define __FUNCT__ "TSView_SSP"
438 static PetscErrorCode TSView_SSP(TS ts,PetscViewer viewer)
439 {
440   PetscFunctionBegin;
441   PetscFunctionReturn(0);
442 }
443 
444 /* ------------------------------------------------------------ */
445 
446 /*MC
447       TSSSP - Explicit strong stability preserving ODE solver
448 
449   Most hyperbolic conservation laws have exact solutions that are total variation diminishing (TVD) or total variation
450   bounded (TVB) although these solutions often contain discontinuities.  Spatial discretizations such as Godunov's
451   scheme and high-resolution finite volume methods (TVD limiters, ENO/WENO) are designed to preserve these properties,
452   but they are usually formulated using a forward Euler time discretization or by coupling the space and time
453   discretization as in the classical Lax-Wendroff scheme.  When the space and time discretization is coupled, it is very
454   difficult to produce schemes with high temporal accuracy while preserving TVD properties.  An alternative is the
455   semidiscrete formulation where we choose a spatial discretization that is TVD with forward Euler and then choose a
456   time discretization that preserves the TVD property.  Such integrators are called strong stability preserving (SSP).
457 
458   Let c_eff be the minimum number of function evaluations required to step as far as one step of forward Euler while
459   still being SSP.  Some theoretical bounds
460 
461   1. There are no explicit methods with c_eff > 1.
462 
463   2. There are no explicit methods beyond order 4 (for nonlinear problems) and c_eff > 0.
464 
465   3. There are no implicit methods with order greater than 1 and c_eff > 2.
466 
467   This integrator provides Runge-Kutta methods of order 2, 3, and 4 with maximal values of c_eff.  More stages allows
468   for larger values of c_eff which improves efficiency.  These implementations are low-memory and only use 2 or 3 work
469   vectors regardless of the total number of stages, so e.g. 25-stage 3rd order methods may be an excellent choice.
470 
471   Methods can be chosen with -ts_ssp_type {rks2,rks3,rk104}
472 
473   rks2: Second order methods with any number s>1 of stages.  c_eff = (s-1)/s
474 
475   rks3: Third order methods with s=n^2 stages, n>1.  c_eff = (s-n)/s
476 
477   rk104: A 10-stage fourth order method.  c_eff = 0.6
478 
479   Level: beginner
480 
481   References:
482 +  1. - Ketcheson, Highly efficient strong stability preserving Runge Kutta methods with low storage implementations, SISC, 2008.
483 -  2. - Gottlieb, Ketcheson, and Shu, High order strong stability preserving time discretizations, J Scientific Computing, 2009.
484 
485 .seealso:  TSCreate(), TS, TSSetType()
486 
487 M*/
488 #undef __FUNCT__
489 #define __FUNCT__ "TSCreate_SSP"
490 PETSC_EXTERN PetscErrorCode TSCreate_SSP(TS ts)
491 {
492   TS_SSP         *ssp;
493   PetscErrorCode ierr;
494 
495   PetscFunctionBegin;
496   ierr = TSSSPInitializePackage();CHKERRQ(ierr);
497 
498   ts->ops->setup          = TSSetUp_SSP;
499   ts->ops->step           = TSStep_SSP;
500   ts->ops->reset          = TSReset_SSP;
501   ts->ops->destroy        = TSDestroy_SSP;
502   ts->ops->setfromoptions = TSSetFromOptions_SSP;
503   ts->ops->view           = TSView_SSP;
504 
505   ierr = PetscNewLog(ts,&ssp);CHKERRQ(ierr);
506   ts->data = (void*)ssp;
507 
508   ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSSPGetType_C",TSSSPGetType_SSP);CHKERRQ(ierr);
509   ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSSPSetType_C",TSSSPSetType_SSP);CHKERRQ(ierr);
510   ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSSPGetNumStages_C",TSSSPGetNumStages_SSP);CHKERRQ(ierr);
511   ierr = PetscObjectComposeFunction((PetscObject)ts,"TSSSPSetNumStages_C",TSSSPSetNumStages_SSP);CHKERRQ(ierr);
512 
513   ierr = TSSSPSetType(ts,TSSSPRKS2);CHKERRQ(ierr);
514   ssp->nstages = 5;
515   PetscFunctionReturn(0);
516 }
517 
518 #undef __FUNCT__
519 #define __FUNCT__ "TSSSPInitializePackage"
520 /*@C
521   TSSSPInitializePackage - This function initializes everything in the TSSSP package. It is called
522   from PetscDLLibraryRegister() when using dynamic libraries, and on the first call to TSCreate_SSP()
523   when using static libraries.
524 
525   Level: developer
526 
527 .keywords: TS, TSSSP, initialize, package
528 .seealso: PetscInitialize()
529 @*/
530 PetscErrorCode TSSSPInitializePackage(void)
531 {
532   PetscErrorCode ierr;
533 
534   PetscFunctionBegin;
535   if (TSSSPPackageInitialized) PetscFunctionReturn(0);
536   TSSSPPackageInitialized = PETSC_TRUE;
537   ierr = PetscFunctionListAdd(&TSSSPList,TSSSPRKS2, TSSSPStep_RK_2);CHKERRQ(ierr);
538   ierr = PetscFunctionListAdd(&TSSSPList,TSSSPRKS3, TSSSPStep_RK_3);CHKERRQ(ierr);
539   ierr = PetscFunctionListAdd(&TSSSPList,TSSSPRK104,TSSSPStep_RK_10_4);CHKERRQ(ierr);
540   ierr = PetscRegisterFinalize(TSSSPFinalizePackage);CHKERRQ(ierr);
541   PetscFunctionReturn(0);
542 }
543 
544 #undef __FUNCT__
545 #define __FUNCT__ "TSSSPFinalizePackage"
546 /*@C
547   TSSSPFinalizePackage - This function destroys everything in the TSSSP package. It is
548   called from PetscFinalize().
549 
550   Level: developer
551 
552 .keywords: Petsc, destroy, package
553 .seealso: PetscFinalize()
554 @*/
555 PetscErrorCode TSSSPFinalizePackage(void)
556 {
557   PetscErrorCode ierr;
558 
559   PetscFunctionBegin;
560   TSSSPPackageInitialized = PETSC_FALSE;
561   ierr = PetscFunctionListDestroy(&TSSSPList);CHKERRQ(ierr);
562   PetscFunctionReturn(0);
563 }
564