xref: /petsc/src/ts/impls/explicit/rk/rk.c (revision e4dd521c7a718087a78a4fcbe68c46ab2c9b5c3f)
1*e4dd521cSBarry Smith /*$Id: rk.c,v 0.1 2003/03/21 Asbjorn Hoiland Aarrestad$*/
2*e4dd521cSBarry Smith /*
3*e4dd521cSBarry Smith        Code for Timestepping with Runge Kutta
4*e4dd521cSBarry Smith 
5*e4dd521cSBarry Smith    Contributed by: Asbj�rn H�iland Aarrestad" <asbjorn@aarrestad.com>
6*e4dd521cSBarry Smith */
7*e4dd521cSBarry Smith #include "src/ts/tsimpl.h"                /*I   "petscts.h"   I*/
8*e4dd521cSBarry Smith 
9*e4dd521cSBarry Smith typedef struct {
10*e4dd521cSBarry Smith    Vec		y1,y2;  /* work wectors for the two rk permuations */
11*e4dd521cSBarry Smith    int		nok,nnok; /* counters for ok and not ok steps */
12*e4dd521cSBarry Smith    PetscReal	maxerror; /* variable to tell the maxerror allowed */
13*e4dd521cSBarry Smith    PetscReal    ferror; /* variable to tell (global maxerror)/(total time) */
14*e4dd521cSBarry Smith    Vec		tmp,tmp_y,*k; /* two temp vectors and the k vectors for rk */
15*e4dd521cSBarry Smith    PetscScalar	a[7][6]; /* rk scalars */
16*e4dd521cSBarry Smith    PetscScalar	b1[7],b2[7]; /* rk scalars */
17*e4dd521cSBarry Smith    PetscReal	c[7]; /* rk scalars */
18*e4dd521cSBarry Smith    int          p,s; /* variables to tell the size of the runge-kutta solver */
19*e4dd521cSBarry Smith } TS_Rk;
20*e4dd521cSBarry Smith 
21*e4dd521cSBarry Smith 
22*e4dd521cSBarry Smith 
23*e4dd521cSBarry Smith #undef __FUNCT__
24*e4dd521cSBarry Smith #define __FUNCT__ "TSSetUp_Rk"
25*e4dd521cSBarry Smith static int TSSetUp_Rk(TS ts)
26*e4dd521cSBarry Smith {
27*e4dd521cSBarry Smith   TS_Rk	*rk = (TS_Rk*)ts->data;
28*e4dd521cSBarry Smith   int	i,j,ierr;
29*e4dd521cSBarry Smith 
30*e4dd521cSBarry Smith   PetscFunctionBegin;
31*e4dd521cSBarry Smith   rk->nok = 0;
32*e4dd521cSBarry Smith   rk->nnok = 0;
33*e4dd521cSBarry Smith   rk->maxerror = ts->time_step;
34*e4dd521cSBarry Smith 
35*e4dd521cSBarry Smith   /* fixing maxerror: global vs local */
36*e4dd521cSBarry Smith   rk->ferror = rk->maxerror / (ts->max_time - ts->ptime);
37*e4dd521cSBarry Smith 
38*e4dd521cSBarry Smith   /* 34.0/45.0 gives double precision division */
39*e4dd521cSBarry Smith   /* defining variables needed for Runge-Kutta computing */
40*e4dd521cSBarry Smith   /* when changing below, please remember to change a, b1, b2 and c above! */
41*e4dd521cSBarry Smith   /* Found in table on page 171: Dormand-Prince 5(4) */
42*e4dd521cSBarry Smith 
43*e4dd521cSBarry Smith   /* are these right? */
44*e4dd521cSBarry Smith   rk->p=6;
45*e4dd521cSBarry Smith   rk->s=7;
46*e4dd521cSBarry Smith 
47*e4dd521cSBarry Smith   rk->a[1][0]=1.0/5.0;
48*e4dd521cSBarry Smith   rk->a[2][0]=3.0/40.0;
49*e4dd521cSBarry Smith   rk->a[2][1]=9.0/40.0;
50*e4dd521cSBarry Smith   rk->a[3][0]=44.0/45.0;
51*e4dd521cSBarry Smith   rk->a[3][1]=-56.0/15.0;
52*e4dd521cSBarry Smith   rk->a[3][2]=32.0/9.0;
53*e4dd521cSBarry Smith   rk->a[4][0]=19372.0/6561.0;
54*e4dd521cSBarry Smith   rk->a[4][1]=-25360.0/2187.0;
55*e4dd521cSBarry Smith   rk->a[4][2]=64448.0/6561.0;
56*e4dd521cSBarry Smith   rk->a[4][3]=-212.0/729.0;
57*e4dd521cSBarry Smith   rk->a[5][0]=9017.0/3168.0;
58*e4dd521cSBarry Smith   rk->a[5][1]=-355.0/33.0;
59*e4dd521cSBarry Smith   rk->a[5][2]=46732.0/5247.0;
60*e4dd521cSBarry Smith   rk->a[5][3]=49.0/176.0;
61*e4dd521cSBarry Smith   rk->a[5][4]=-5103.0/18656.0;
62*e4dd521cSBarry Smith   rk->a[6][0]=35.0/384.0;
63*e4dd521cSBarry Smith   rk->a[6][1]=0.0;
64*e4dd521cSBarry Smith   rk->a[6][2]=500.0/1113.0;
65*e4dd521cSBarry Smith   rk->a[6][3]=125.0/192.0;
66*e4dd521cSBarry Smith   rk->a[6][4]=-2187.0/6784.0;
67*e4dd521cSBarry Smith   rk->a[6][5]=11.0/84.0;
68*e4dd521cSBarry Smith 
69*e4dd521cSBarry Smith 
70*e4dd521cSBarry Smith   rk->c[0]=0.0;
71*e4dd521cSBarry Smith   rk->c[1]=1.0/5.0;
72*e4dd521cSBarry Smith   rk->c[2]=3.0/10.0;
73*e4dd521cSBarry Smith   rk->c[3]=4.0/5.0;
74*e4dd521cSBarry Smith   rk->c[4]=8.0/9.0;
75*e4dd521cSBarry Smith   rk->c[5]=1.0;
76*e4dd521cSBarry Smith   rk->c[6]=1.0;
77*e4dd521cSBarry Smith 
78*e4dd521cSBarry Smith   rk->b1[0]=35.0/384.0;
79*e4dd521cSBarry Smith   rk->b1[1]=0.0;
80*e4dd521cSBarry Smith   rk->b1[2]=500.0/1113.0;
81*e4dd521cSBarry Smith   rk->b1[3]=125.0/192.0;
82*e4dd521cSBarry Smith   rk->b1[4]=-2187.0/6784.0;
83*e4dd521cSBarry Smith   rk->b1[5]=11.0/84.0;
84*e4dd521cSBarry Smith   rk->b1[6]=0.0;
85*e4dd521cSBarry Smith 
86*e4dd521cSBarry Smith   rk->b2[0]=5179.0/57600.0;
87*e4dd521cSBarry Smith   rk->b2[1]=0.0;
88*e4dd521cSBarry Smith   rk->b2[2]=7571.0/16695.0;
89*e4dd521cSBarry Smith   rk->b2[3]=393.0/640.0;
90*e4dd521cSBarry Smith   rk->b2[4]=-92097.0/339200.0;
91*e4dd521cSBarry Smith   rk->b2[5]=187.0/2100.0;
92*e4dd521cSBarry Smith   rk->b2[6]=1.0/40.0;
93*e4dd521cSBarry Smith 
94*e4dd521cSBarry Smith 
95*e4dd521cSBarry Smith   /* Found in table on page 170: Fehlberg 4(5) */
96*e4dd521cSBarry Smith   /*
97*e4dd521cSBarry Smith   rk->p=5;
98*e4dd521cSBarry Smith   rk->s=6;
99*e4dd521cSBarry Smith 
100*e4dd521cSBarry Smith   rk->a[1][0]=1.0/4.0;
101*e4dd521cSBarry Smith   rk->a[2][0]=3.0/32.0;
102*e4dd521cSBarry Smith   rk->a[2][1]=9.0/32.0;
103*e4dd521cSBarry Smith   rk->a[3][0]=1932.0/2197.0;
104*e4dd521cSBarry Smith   rk->a[3][1]=-7200.0/2197.0;
105*e4dd521cSBarry Smith   rk->a[3][2]=7296.0/2197.0;
106*e4dd521cSBarry Smith   rk->a[4][0]=439.0/216.0;
107*e4dd521cSBarry Smith   rk->a[4][1]=-8.0;
108*e4dd521cSBarry Smith   rk->a[4][2]=3680.0/513.0;
109*e4dd521cSBarry Smith   rk->a[4][3]=-845.0/4104.0;
110*e4dd521cSBarry Smith   rk->a[5][0]=-8.0/27.0;
111*e4dd521cSBarry Smith   rk->a[5][1]=2.0;
112*e4dd521cSBarry Smith   rk->a[5][2]=-3544.0/2565.0;
113*e4dd521cSBarry Smith   rk->a[5][3]=1859.0/4104.0;
114*e4dd521cSBarry Smith   rk->a[5][4]=-11.0/40.0;
115*e4dd521cSBarry Smith 
116*e4dd521cSBarry Smith   rk->c[0]=0.0;
117*e4dd521cSBarry Smith   rk->c[1]=1.0/4.0;
118*e4dd521cSBarry Smith   rk->c[2]=3.0/8.0;
119*e4dd521cSBarry Smith   rk->c[3]=12.0/13.0;
120*e4dd521cSBarry Smith   rk->c[4]=1.0;
121*e4dd521cSBarry Smith   rk->c[5]=1.0/2.0;
122*e4dd521cSBarry Smith 
123*e4dd521cSBarry Smith   rk->b1[0]=25.0/216.0;
124*e4dd521cSBarry Smith   rk->b1[1]=0.0;
125*e4dd521cSBarry Smith   rk->b1[2]=1408.0/2565.0;
126*e4dd521cSBarry Smith   rk->b1[3]=2197.0/4104.0;
127*e4dd521cSBarry Smith   rk->b1[4]=-1.0/5.0;
128*e4dd521cSBarry Smith   rk->b1[5]=0.0;
129*e4dd521cSBarry Smith 
130*e4dd521cSBarry Smith   rk->b2[0]=16.0/135.0;
131*e4dd521cSBarry Smith   rk->b2[1]=0.0;
132*e4dd521cSBarry Smith   rk->b2[2]=6656.0/12825.0;
133*e4dd521cSBarry Smith   rk->b2[3]=28561.0/56430.0;
134*e4dd521cSBarry Smith   rk->b2[4]=-9.0/50.0;
135*e4dd521cSBarry Smith   rk->b2[5]=2.0/55.0;
136*e4dd521cSBarry Smith   */
137*e4dd521cSBarry Smith   /* Found in table on page 169: Merson 4("5") */
138*e4dd521cSBarry Smith   /*
139*e4dd521cSBarry Smith   rk->p=4;
140*e4dd521cSBarry Smith   rk->s=5;
141*e4dd521cSBarry Smith   rk->a[1][0] = 1.0/3.0;
142*e4dd521cSBarry Smith   rk->a[2][0] = 1.0/6.0;
143*e4dd521cSBarry Smith   rk->a[2][1] = 1.0/6.0;
144*e4dd521cSBarry Smith   rk->a[3][0] = 1.0/8.0;
145*e4dd521cSBarry Smith   rk->a[3][1] = 0.0;
146*e4dd521cSBarry Smith   rk->a[3][2] = 3.0/8.0;
147*e4dd521cSBarry Smith   rk->a[4][0] = 1.0/2.0;
148*e4dd521cSBarry Smith   rk->a[4][1] = 0.0;
149*e4dd521cSBarry Smith   rk->a[4][2] = -3.0/2.0;
150*e4dd521cSBarry Smith   rk->a[4][3] = 2.0;
151*e4dd521cSBarry Smith 
152*e4dd521cSBarry Smith   rk->c[0] = 0.0;
153*e4dd521cSBarry Smith   rk->c[1] = 1.0/3.0;
154*e4dd521cSBarry Smith   rk->c[2] = 1.0/3.0;
155*e4dd521cSBarry Smith   rk->c[3] = 0.5;
156*e4dd521cSBarry Smith   rk->c[4] = 1.0;
157*e4dd521cSBarry Smith 
158*e4dd521cSBarry Smith   rk->b1[0] = 1.0/2.0;
159*e4dd521cSBarry Smith   rk->b1[1] = 0.0;
160*e4dd521cSBarry Smith   rk->b1[2] = -3.0/2.0;
161*e4dd521cSBarry Smith   rk->b1[3] = 2.0;
162*e4dd521cSBarry Smith   rk->b1[4] = 0.0;
163*e4dd521cSBarry Smith 
164*e4dd521cSBarry Smith   rk->b2[0] = 1.0/6.0;
165*e4dd521cSBarry Smith   rk->b2[1] = 0.0;
166*e4dd521cSBarry Smith   rk->b2[2] = 0.0;
167*e4dd521cSBarry Smith   rk->b2[3] = 2.0/3.0;
168*e4dd521cSBarry Smith   rk->b2[4] = 1.0/6.0;
169*e4dd521cSBarry Smith   */
170*e4dd521cSBarry Smith 
171*e4dd521cSBarry Smith   /* making b2 -> e=b1-b2 */
172*e4dd521cSBarry Smith   /*
173*e4dd521cSBarry Smith   for(i=0;i<rk->s;i++){
174*e4dd521cSBarry Smith      rk->b2[i] = rk->b1[i] - rk->b2[i];
175*e4dd521cSBarry Smith      ierr = PetscPrintf(PETSC_COMM_WORLD,"%f \n",rk->b2[i]);CHKERRQ(ierr);
176*e4dd521cSBarry Smith   }
177*e4dd521cSBarry Smith   */
178*e4dd521cSBarry Smith   /* initializing vectors */
179*e4dd521cSBarry Smith   ierr = VecDuplicate(ts->vec_sol,&rk->y1);CHKERRQ(ierr);
180*e4dd521cSBarry Smith   ierr = VecDuplicate(ts->vec_sol,&rk->y2);CHKERRQ(ierr);
181*e4dd521cSBarry Smith   ierr = VecDuplicate(rk->y1,&rk->tmp);CHKERRQ(ierr);
182*e4dd521cSBarry Smith   ierr = VecDuplicate(rk->y1,&rk->tmp_y);CHKERRQ(ierr);
183*e4dd521cSBarry Smith   ierr = VecDuplicateVecs(rk->y1,rk->s,&rk->k);CHKERRQ(ierr);
184*e4dd521cSBarry Smith 
185*e4dd521cSBarry Smith   PetscFunctionReturn(0);
186*e4dd521cSBarry Smith }
187*e4dd521cSBarry Smith 
188*e4dd521cSBarry Smith #undef __FUNCT__
189*e4dd521cSBarry Smith #define __FUNCT__ "TSStep_Rk"
190*e4dd521cSBarry Smith static int TSStep_Rk(TS ts,int *steps,PetscReal *ptime)
191*e4dd521cSBarry Smith {
192*e4dd521cSBarry Smith   TS_Rk		*rk = (TS_Rk*)ts->data;
193*e4dd521cSBarry Smith   int		ierr,i,max_steps = ts->max_steps,dill=0;
194*e4dd521cSBarry Smith   PetscReal	dt = 0.001; /* fixed first step guess */
195*e4dd521cSBarry Smith   PetscReal	norm=0.0,dt_fac=0.0,fac = 0.0,ttmp=0.0;
196*e4dd521cSBarry Smith   PetscScalar	men = -1.0;
197*e4dd521cSBarry Smith   PetscViewer	view;
198*e4dd521cSBarry Smith 
199*e4dd521cSBarry Smith   ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD,"out/ch.m",&view);CHKERRQ(ierr);
200*e4dd521cSBarry Smith   ierr = PetscViewerSetFormat(view,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr);
201*e4dd521cSBarry Smith 
202*e4dd521cSBarry Smith   PetscFunctionBegin;
203*e4dd521cSBarry Smith 
204*e4dd521cSBarry Smith   ierr=VecCopy(ts->vec_sol,rk->y1);CHKERRQ(ierr);
205*e4dd521cSBarry Smith   *steps = -ts->steps;
206*e4dd521cSBarry Smith   /* trying to save the vector */
207*e4dd521cSBarry Smith   ierr = VecView(rk->y1,view);CHKERRQ(ierr);
208*e4dd521cSBarry Smith   ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
209*e4dd521cSBarry Smith   /* while loop to get from start to stop */
210*e4dd521cSBarry Smith   while (ts->ptime < ts->max_time){
211*e4dd521cSBarry Smith    /* calling rkqs */
212*e4dd521cSBarry Smith      /*
213*e4dd521cSBarry Smith        -- input
214*e4dd521cSBarry Smith        ts        - pointer to ts
215*e4dd521cSBarry Smith        ts->ptime - current time
216*e4dd521cSBarry Smith        dt        - try this timestep
217*e4dd521cSBarry Smith        y1        - solution for this step
218*e4dd521cSBarry Smith 
219*e4dd521cSBarry Smith        --output
220*e4dd521cSBarry Smith        y1        - suggested solution
221*e4dd521cSBarry Smith        y2        - check solution (runge - kutta second permutation)
222*e4dd521cSBarry Smith      */
223*e4dd521cSBarry Smith      ierr = TSRkqs(ts,ts->ptime,dt);CHKERRQ(ierr);
224*e4dd521cSBarry Smith    /* checking for maxerror */
225*e4dd521cSBarry Smith      /* Finding difference between y1 and y2 */
226*e4dd521cSBarry Smith      ierr = VecAYPX(&men,rk->y1,rk->y2);CHKERRQ(ierr); /* y2=y1+(-1*y2)*/
227*e4dd521cSBarry Smith 
228*e4dd521cSBarry Smith      /* comparing difference to maxerror */
229*e4dd521cSBarry Smith      /* CHECK THE NEXT LINE!!!!!!!!! */
230*e4dd521cSBarry Smith      ierr = VecNorm(rk->y2,NORM_2,&norm);CHKERRQ(ierr);
231*e4dd521cSBarry Smith      /* modifying maxerror to satisfy this timestep */
232*e4dd521cSBarry Smith      rk->maxerror = rk->ferror * dt;
233*e4dd521cSBarry Smith      /* ierr = PetscPrintf(PETSC_COMM_WORLD,"norm err: %f maxerror: %f dt: %f",norm,rk->maxerror,dt);CHKERRQ(ierr); */
234*e4dd521cSBarry Smith 
235*e4dd521cSBarry Smith    /* handling ok and not ok */
236*e4dd521cSBarry Smith      if(norm < rk->maxerror){
237*e4dd521cSBarry Smith 	/* if ok: */
238*e4dd521cSBarry Smith         ierr=VecCopy(rk->y1,ts->vec_sol);CHKERRQ(ierr); /* saves the suggested solution to current solution */
239*e4dd521cSBarry Smith         ts->ptime += dt; /* storing the new current time */
240*e4dd521cSBarry Smith 	rk->nok++;
241*e4dd521cSBarry Smith 	fac=5.0;
242*e4dd521cSBarry Smith 	/* trying to save the vector */
243*e4dd521cSBarry Smith         ierr = VecView(rk->y1,view);CHKERRQ(ierr);
244*e4dd521cSBarry Smith        /* calling monitor */
245*e4dd521cSBarry Smith        ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
246*e4dd521cSBarry Smith      }else{
247*e4dd521cSBarry Smith 	/* if not OK */
248*e4dd521cSBarry Smith 	rk->nnok++;
249*e4dd521cSBarry Smith 	fac=1.0;
250*e4dd521cSBarry Smith 	ierr=VecCopy(ts->vec_sol,rk->y1);CHKERRQ(ierr);  /* restores old solution */
251*e4dd521cSBarry Smith      }
252*e4dd521cSBarry Smith 
253*e4dd521cSBarry Smith      /*Computing next stepsize. See page 167 in Solving ODE 1
254*e4dd521cSBarry Smith       *
255*e4dd521cSBarry Smith       * h_new = h * min( facmax , max( facmin , fac * (tol/err)^(1/(p+1)) ) )
256*e4dd521cSBarry Smith       * facmax set above
257*e4dd521cSBarry Smith       * facmin
258*e4dd521cSBarry Smith       */
259*e4dd521cSBarry Smith 
260*e4dd521cSBarry Smith 
261*e4dd521cSBarry Smith 
262*e4dd521cSBarry Smith      dt_fac = exp(log((rk->maxerror) / norm) / ((rk->p) + 1) ) * 0.9 ;
263*e4dd521cSBarry Smith 
264*e4dd521cSBarry Smith      if(dt_fac > fac){
265*e4dd521cSBarry Smith         ierr = PetscPrintf(PETSC_COMM_WORLD,"changing fac %f\n",fac);
266*e4dd521cSBarry Smith 	dt_fac = fac;
267*e4dd521cSBarry Smith      }
268*e4dd521cSBarry Smith 
269*e4dd521cSBarry Smith      /* computing new dt */
270*e4dd521cSBarry Smith      dt = dt * dt_fac;
271*e4dd521cSBarry Smith 
272*e4dd521cSBarry Smith      if(ts->ptime+dt > ts->max_time){
273*e4dd521cSBarry Smith 	dt = ts->max_time - ts->ptime;
274*e4dd521cSBarry Smith      }
275*e4dd521cSBarry Smith 
276*e4dd521cSBarry Smith      if(dt < 1e-12){
277*e4dd521cSBarry Smith 	ierr = PetscPrintf(PETSC_COMM_WORLD,"Very small steps: %f\n",dt);CHKERRQ(ierr);
278*e4dd521cSBarry Smith 	dt = 1e-12;
279*e4dd521cSBarry Smith      }
280*e4dd521cSBarry Smith 
281*e4dd521cSBarry Smith      /* trying to purify h */
282*e4dd521cSBarry Smith      /* (did not give any visible result) */
283*e4dd521cSBarry Smith      ttmp = ts->ptime + dt;
284*e4dd521cSBarry Smith      dt = ttmp - ts->ptime;
285*e4dd521cSBarry Smith 
286*e4dd521cSBarry Smith      /* counting steps */
287*e4dd521cSBarry Smith      ts->steps++;
288*e4dd521cSBarry Smith   }
289*e4dd521cSBarry Smith 
290*e4dd521cSBarry Smith   ierr=VecCopy(rk->y1,ts->vec_sol);CHKERRQ(ierr);
291*e4dd521cSBarry Smith   *steps += ts->steps;
292*e4dd521cSBarry Smith   *ptime  = ts->ptime;
293*e4dd521cSBarry Smith 
294*e4dd521cSBarry Smith   PetscFunctionReturn(0);
295*e4dd521cSBarry Smith }
296*e4dd521cSBarry Smith /*------------------------------------------------------------*/
297*e4dd521cSBarry Smith #undef __FUNCT__
298*e4dd521cSBarry Smith #define __FUNCT__ "TSRkqs"
299*e4dd521cSBarry Smith int TSRkqs(TS ts,PetscReal t,PetscReal h)
300*e4dd521cSBarry Smith {
301*e4dd521cSBarry Smith   TS_Rk		*rk = (TS_Rk*)ts->data;
302*e4dd521cSBarry Smith   int		ierr;
303*e4dd521cSBarry Smith   PetscReal	tmp_t=t;
304*e4dd521cSBarry Smith   PetscScalar	null=0.0,tt=t,hh=h;
305*e4dd521cSBarry Smith 
306*e4dd521cSBarry Smith   /*  printf("h: %f, hh: %f",h,hh); */
307*e4dd521cSBarry Smith 
308*e4dd521cSBarry Smith   PetscFunctionBegin;
309*e4dd521cSBarry Smith 
310*e4dd521cSBarry Smith   /* k[0]=0  */
311*e4dd521cSBarry Smith   ierr = VecSet(&null,rk->k[0]);CHKERRQ(ierr);
312*e4dd521cSBarry Smith 
313*e4dd521cSBarry Smith   /* k[0] = derivs(t,y1) */
314*e4dd521cSBarry Smith   ierr = TSComputeRHSFunction(ts,t,rk->y1,rk->k[0]);CHKERRQ(ierr);
315*e4dd521cSBarry Smith   /* looping over runge-kutta variables */
316*e4dd521cSBarry Smith   /* building the k - array of vectors */
317*e4dd521cSBarry Smith   for(int j = 1 ; j < rk->s ; j++){
318*e4dd521cSBarry Smith 
319*e4dd521cSBarry Smith      /* rk->tmp = 0 */
320*e4dd521cSBarry Smith      ierr = VecSet(&null,rk->tmp);CHKERRQ(ierr);
321*e4dd521cSBarry Smith 
322*e4dd521cSBarry Smith      for(int l=0;l<j-1;l++){
323*e4dd521cSBarry Smith 	/* tmp += a(j,l)*k[l] */
324*e4dd521cSBarry Smith 	ierr = VecAXPY(&rk->a[j][l],rk->k[l],rk->tmp);CHKERRQ(ierr);
325*e4dd521cSBarry Smith      }
326*e4dd521cSBarry Smith 
327*e4dd521cSBarry Smith      /* k[j] = derivs(t+c(j)*h,y1+h*tmp,k(j)) */
328*e4dd521cSBarry Smith      /* I need the following helpers:
329*e4dd521cSBarry Smith 	PetscScalar  tmp_t=t+c(j)*h
330*e4dd521cSBarry Smith 	Vec          tmp_y=h*tmp+y1
331*e4dd521cSBarry Smith      */
332*e4dd521cSBarry Smith 
333*e4dd521cSBarry Smith      tmp_t = t + rk->c[j] * h;
334*e4dd521cSBarry Smith 
335*e4dd521cSBarry Smith      /* tmp_y = h * tmp + y1 */
336*e4dd521cSBarry Smith      ierr = VecWAXPY(&hh,rk->tmp,rk->y1,rk->tmp_y);CHKERRQ(ierr);
337*e4dd521cSBarry Smith 
338*e4dd521cSBarry Smith      /* rk->k[j]=0 */
339*e4dd521cSBarry Smith      ierr = VecSet(&null,rk->k[j]);CHKERRQ(ierr);
340*e4dd521cSBarry Smith      ierr = TSComputeRHSFunction(ts,tmp_t,rk->tmp_y,rk->k[j]);CHKERRQ(ierr);
341*e4dd521cSBarry Smith   }
342*e4dd521cSBarry Smith 
343*e4dd521cSBarry Smith   /* tmp=0 and tmp_y=0 */
344*e4dd521cSBarry Smith   ierr = VecSet(&null,rk->tmp);CHKERRQ(ierr);
345*e4dd521cSBarry Smith   ierr = VecSet(&null,rk->tmp_y);CHKERRQ(ierr);
346*e4dd521cSBarry Smith 
347*e4dd521cSBarry Smith   for(int j = 0 ; j < rk->s ; j++){
348*e4dd521cSBarry Smith      /* tmp=b1[j]*k[j]+tmp  */
349*e4dd521cSBarry Smith      ierr = VecAXPY(&rk->b1[j],rk->k[j],rk->tmp);CHKERRQ(ierr);
350*e4dd521cSBarry Smith      /* tmp_y=b2[j]*k[j]+tmp_y */
351*e4dd521cSBarry Smith      ierr = VecAXPY(&rk->b2[j],rk->k[j],rk->tmp_y);CHKERRQ(ierr);
352*e4dd521cSBarry Smith   }
353*e4dd521cSBarry Smith 
354*e4dd521cSBarry Smith 
355*e4dd521cSBarry Smith   /* y2 = hh*tmp_y + y1 */
356*e4dd521cSBarry Smith   ierr = VecWAXPY(&hh,rk->tmp_y,rk->y1,rk->y2);CHKERRQ(ierr);
357*e4dd521cSBarry Smith   /* ierr = VecAXPY(&hh,rk->tmp_y,rk->y2);CHKERRQ(ierr);*/
358*e4dd521cSBarry Smith   /* y1 = hh*tmp + y1 */
359*e4dd521cSBarry Smith   ierr = VecAXPY(&hh,rk->tmp,rk->y1);CHKERRQ(ierr);
360*e4dd521cSBarry Smith 
361*e4dd521cSBarry Smith   PetscFunctionReturn(0);
362*e4dd521cSBarry Smith }
363*e4dd521cSBarry Smith 
364*e4dd521cSBarry Smith /*------------------------------------------------------------*/
365*e4dd521cSBarry Smith #undef __FUNCT__
366*e4dd521cSBarry Smith #define __FUNCT__ "TSDestroy_Rk"
367*e4dd521cSBarry Smith static int TSDestroy_Rk(TS ts)
368*e4dd521cSBarry Smith {
369*e4dd521cSBarry Smith   TS_Rk *rk = (TS_Rk*)ts->data;
370*e4dd521cSBarry Smith   int      i,ierr;
371*e4dd521cSBarry Smith 
372*e4dd521cSBarry Smith   /* REMEMBER TO DESTROY ALL */
373*e4dd521cSBarry Smith 
374*e4dd521cSBarry Smith   PetscFunctionBegin;
375*e4dd521cSBarry Smith   if (rk->y1) {ierr = VecDestroy(rk->y1);CHKERRQ(ierr);}
376*e4dd521cSBarry Smith   if (rk->y2) {ierr = VecDestroy(rk->y2);CHKERRQ(ierr);}
377*e4dd521cSBarry Smith   if (rk->tmp) {ierr = VecDestroy(rk->tmp);CHKERRQ(ierr);}
378*e4dd521cSBarry Smith   if (rk->tmp_y) {ierr = VecDestroy(rk->tmp_y);CHKERRQ(ierr);}
379*e4dd521cSBarry Smith   for(i=0;i<rk->s;i++){
380*e4dd521cSBarry Smith      if (rk->k[i]) {ierr = VecDestroy(rk->k[i]);CHKERRQ(ierr);}
381*e4dd521cSBarry Smith   }
382*e4dd521cSBarry Smith   ierr = PetscFree(rk);CHKERRQ(ierr);
383*e4dd521cSBarry Smith   PetscFunctionReturn(0);
384*e4dd521cSBarry Smith }
385*e4dd521cSBarry Smith /*------------------------------------------------------------*/
386*e4dd521cSBarry Smith 
387*e4dd521cSBarry Smith #undef __FUNCT__
388*e4dd521cSBarry Smith #define __FUNCT__ "TSSetFromOptions_Rk"
389*e4dd521cSBarry Smith static int TSSetFromOptions_Rk(TS ts)
390*e4dd521cSBarry Smith {
391*e4dd521cSBarry Smith   PetscFunctionBegin;
392*e4dd521cSBarry Smith   PetscFunctionReturn(0);
393*e4dd521cSBarry Smith }
394*e4dd521cSBarry Smith 
395*e4dd521cSBarry Smith #undef __FUNCT__
396*e4dd521cSBarry Smith #define __FUNCT__ "TSView_Rk"
397*e4dd521cSBarry Smith static int TSView_Rk(TS ts,PetscViewer viewer)
398*e4dd521cSBarry Smith {
399*e4dd521cSBarry Smith    TS_Rk *rk = (TS_Rk*)ts->data;
400*e4dd521cSBarry Smith    int ierr;
401*e4dd521cSBarry Smith    PetscFunctionBegin;
402*e4dd521cSBarry Smith    ierr = PetscPrintf(PETSC_COMM_WORLD,"  number of ok steps: %d\n",rk->nok);CHKERRQ(ierr);
403*e4dd521cSBarry Smith    ierr = PetscPrintf(PETSC_COMM_WORLD,"  mumber of rejected steps: %d\n",rk->nnok);CHKERRQ(ierr);
404*e4dd521cSBarry Smith    PetscFunctionReturn(0);
405*e4dd521cSBarry Smith }
406*e4dd521cSBarry Smith 
407*e4dd521cSBarry Smith /* ------------------------------------------------------------ */
408*e4dd521cSBarry Smith EXTERN_C_BEGIN
409*e4dd521cSBarry Smith #undef __FUNCT__
410*e4dd521cSBarry Smith #define __FUNCT__ "TSCreate_Rk"
411*e4dd521cSBarry Smith int TSCreate_Rk(TS ts)
412*e4dd521cSBarry Smith {
413*e4dd521cSBarry Smith   TS_Rk    *rk;
414*e4dd521cSBarry Smith   int      ierr;
415*e4dd521cSBarry Smith 
416*e4dd521cSBarry Smith   PetscFunctionBegin;
417*e4dd521cSBarry Smith   ts->ops->setup           = TSSetUp_Rk;
418*e4dd521cSBarry Smith   ts->ops->step            = TSStep_Rk;
419*e4dd521cSBarry Smith   ts->ops->destroy         = TSDestroy_Rk;
420*e4dd521cSBarry Smith   ts->ops->setfromoptions  = TSSetFromOptions_Rk;
421*e4dd521cSBarry Smith   ts->ops->view            = TSView_Rk;
422*e4dd521cSBarry Smith 
423*e4dd521cSBarry Smith   ierr = PetscNew(TS_Rk,&rk);CHKERRQ(ierr);
424*e4dd521cSBarry Smith   PetscLogObjectMemory(ts,sizeof(TS_Rk));
425*e4dd521cSBarry Smith   ts->data = (void*)rk;
426*e4dd521cSBarry Smith 
427*e4dd521cSBarry Smith   PetscFunctionReturn(0);
428*e4dd521cSBarry Smith }
429*e4dd521cSBarry Smith EXTERN_C_END
430*e4dd521cSBarry Smith 
431*e4dd521cSBarry Smith 
432*e4dd521cSBarry Smith 
433*e4dd521cSBarry Smith 
434