xref: /petsc/src/ts/impls/explicit/rk/rk.c (revision 6849ba73f22fecb8f92ef896a42e4e8bd4cd6965)
1e4dd521cSBarry Smith /*
226edb414Sasbjorn  * Code for Timestepping with Runge Kutta
326edb414Sasbjorn  *
426edb414Sasbjorn  * Written by
526edb414Sasbjorn  * Asbjorn Hoiland Aarrestad
626edb414Sasbjorn  * asbjorn@aarrestad.com
726edb414Sasbjorn  * http://asbjorn.aarrestad.com/
826edb414Sasbjorn  *
9e4dd521cSBarry Smith  */
10e4dd521cSBarry Smith #include "src/ts/tsimpl.h"                /*I   "petscts.h"   I*/
112cdf8120Sasbjorn #include "time.h"
12e4dd521cSBarry Smith 
13e4dd521cSBarry Smith typedef struct {
14e4dd521cSBarry Smith    Vec		y1,y2;  /* work wectors for the two rk permuations */
15e4dd521cSBarry Smith    int		nok,nnok; /* counters for ok and not ok steps */
16e4dd521cSBarry Smith    PetscReal	maxerror; /* variable to tell the maxerror allowed */
17e4dd521cSBarry Smith    PetscReal    ferror; /* variable to tell (global maxerror)/(total time) */
18262ff7bbSBarry Smith    PetscReal    tolerance; /* initial value set for maxerror by user */
19e4dd521cSBarry Smith    Vec		tmp,tmp_y,*k; /* two temp vectors and the k vectors for rk */
20e4dd521cSBarry Smith    PetscScalar	a[7][6]; /* rk scalars */
21e4dd521cSBarry Smith    PetscScalar	b1[7],b2[7]; /* rk scalars */
22e4dd521cSBarry Smith    PetscReal	c[7]; /* rk scalars */
23e4dd521cSBarry Smith    int          p,s; /* variables to tell the size of the runge-kutta solver */
242cdf8120Sasbjorn    clock_t      start,end; /* variables to mesure cpu time */
25e4dd521cSBarry Smith } TS_Rk;
26e4dd521cSBarry Smith 
27262ff7bbSBarry Smith EXTERN_C_BEGIN
28262ff7bbSBarry Smith #undef __FUNCT__
29262ff7bbSBarry Smith #define __FUNCT__ "TSRKSetTolerance_RK"
30dfbe8321SBarry Smith PetscErrorCode TSRKSetTolerance_RK(TS ts,PetscReal aabs)
31262ff7bbSBarry Smith {
32262ff7bbSBarry Smith   TS_Rk *rk = (TS_Rk*)ts->data;
33262ff7bbSBarry Smith 
34262ff7bbSBarry Smith   PetscFunctionBegin;
35262ff7bbSBarry Smith   rk->tolerance = aabs;
36262ff7bbSBarry Smith   PetscFunctionReturn(0);
37262ff7bbSBarry Smith }
38262ff7bbSBarry Smith EXTERN_C_END
39262ff7bbSBarry Smith 
40262ff7bbSBarry Smith #undef __FUNCT__
41262ff7bbSBarry Smith #define __FUNCT__ "TSRKSetTolerance"
42262ff7bbSBarry Smith /*@
43262ff7bbSBarry Smith    TSRKSetTolerance - Sets the total error the RK explicit time integrators
44262ff7bbSBarry Smith                       will allow over the given time interval.
45262ff7bbSBarry Smith 
46262ff7bbSBarry Smith    Collective on TS
47262ff7bbSBarry Smith 
48262ff7bbSBarry Smith    Input parameters:
49262ff7bbSBarry Smith +    ts  - the time-step context
50262ff7bbSBarry Smith -    aabs - the absolute tolerance
51262ff7bbSBarry Smith 
52262ff7bbSBarry Smith    Level: intermediate
53262ff7bbSBarry Smith 
54262ff7bbSBarry Smith .keywords: RK, tolerance
55262ff7bbSBarry Smith 
56262ff7bbSBarry Smith .seealso: TSPVodeSetTolerance()
57262ff7bbSBarry Smith 
58262ff7bbSBarry Smith @*/
59dfbe8321SBarry Smith PetscErrorCode TSRKSetTolerance(TS ts,PetscReal aabs)
60262ff7bbSBarry Smith {
61dfbe8321SBarry Smith   PetscErrorCode ierr,(*f)(TS,PetscReal);
62262ff7bbSBarry Smith 
63262ff7bbSBarry Smith   PetscFunctionBegin;
64262ff7bbSBarry Smith   ierr = PetscObjectQueryFunction((PetscObject)ts,"TSRKSetTolerance_C",(void (**)(void))&f);CHKERRQ(ierr);
65262ff7bbSBarry Smith   if (f) {
66262ff7bbSBarry Smith     ierr = (*f)(ts,aabs);CHKERRQ(ierr);
67262ff7bbSBarry Smith   }
68262ff7bbSBarry Smith   PetscFunctionReturn(0);
69262ff7bbSBarry Smith }
70e4dd521cSBarry Smith 
71e4dd521cSBarry Smith 
72e4dd521cSBarry Smith #undef __FUNCT__
73e4dd521cSBarry Smith #define __FUNCT__ "TSSetUp_Rk"
74*6849ba73SBarry Smith static PetscErrorCode TSSetUp_Rk(TS ts)
75e4dd521cSBarry Smith {
76e4dd521cSBarry Smith   TS_Rk	*rk = (TS_Rk*)ts->data;
7735b76a18SSatish Balay   int	ierr;
78e4dd521cSBarry Smith 
79e4dd521cSBarry Smith   PetscFunctionBegin;
80e4dd521cSBarry Smith   rk->nok      = 0;
81e4dd521cSBarry Smith   rk->nnok     = 0;
82262ff7bbSBarry Smith   rk->maxerror = rk->tolerance;
83e4dd521cSBarry Smith 
84e4dd521cSBarry Smith   /* fixing maxerror: global vs local */
85e4dd521cSBarry Smith   rk->ferror = rk->maxerror / (ts->max_time - ts->ptime);
86e4dd521cSBarry Smith 
87e4dd521cSBarry Smith   /* 34.0/45.0 gives double precision division */
88e4dd521cSBarry Smith   /* defining variables needed for Runge-Kutta computing */
89e4dd521cSBarry Smith   /* when changing below, please remember to change a, b1, b2 and c above! */
90e4dd521cSBarry Smith   /* Found in table on page 171: Dormand-Prince 5(4) */
91e4dd521cSBarry Smith 
92e4dd521cSBarry Smith   /* are these right? */
93e4dd521cSBarry Smith   rk->p=6;
94e4dd521cSBarry Smith   rk->s=7;
95e4dd521cSBarry Smith 
96e4dd521cSBarry Smith   rk->a[1][0]=1.0/5.0;
97e4dd521cSBarry Smith   rk->a[2][0]=3.0/40.0;
98e4dd521cSBarry Smith   rk->a[2][1]=9.0/40.0;
99e4dd521cSBarry Smith   rk->a[3][0]=44.0/45.0;
100e4dd521cSBarry Smith   rk->a[3][1]=-56.0/15.0;
101e4dd521cSBarry Smith   rk->a[3][2]=32.0/9.0;
102e4dd521cSBarry Smith   rk->a[4][0]=19372.0/6561.0;
103e4dd521cSBarry Smith   rk->a[4][1]=-25360.0/2187.0;
104e4dd521cSBarry Smith   rk->a[4][2]=64448.0/6561.0;
105e4dd521cSBarry Smith   rk->a[4][3]=-212.0/729.0;
106e4dd521cSBarry Smith   rk->a[5][0]=9017.0/3168.0;
107e4dd521cSBarry Smith   rk->a[5][1]=-355.0/33.0;
108e4dd521cSBarry Smith   rk->a[5][2]=46732.0/5247.0;
109e4dd521cSBarry Smith   rk->a[5][3]=49.0/176.0;
110e4dd521cSBarry Smith   rk->a[5][4]=-5103.0/18656.0;
111e4dd521cSBarry Smith   rk->a[6][0]=35.0/384.0;
112e4dd521cSBarry Smith   rk->a[6][1]=0.0;
113e4dd521cSBarry Smith   rk->a[6][2]=500.0/1113.0;
114e4dd521cSBarry Smith   rk->a[6][3]=125.0/192.0;
115e4dd521cSBarry Smith   rk->a[6][4]=-2187.0/6784.0;
116e4dd521cSBarry Smith   rk->a[6][5]=11.0/84.0;
117e4dd521cSBarry Smith 
118e4dd521cSBarry Smith 
119e4dd521cSBarry Smith   rk->c[0]=0.0;
120e4dd521cSBarry Smith   rk->c[1]=1.0/5.0;
121e4dd521cSBarry Smith   rk->c[2]=3.0/10.0;
122e4dd521cSBarry Smith   rk->c[3]=4.0/5.0;
123e4dd521cSBarry Smith   rk->c[4]=8.0/9.0;
124e4dd521cSBarry Smith   rk->c[5]=1.0;
125e4dd521cSBarry Smith   rk->c[6]=1.0;
126e4dd521cSBarry Smith 
127e4dd521cSBarry Smith   rk->b1[0]=35.0/384.0;
128e4dd521cSBarry Smith   rk->b1[1]=0.0;
129e4dd521cSBarry Smith   rk->b1[2]=500.0/1113.0;
130e4dd521cSBarry Smith   rk->b1[3]=125.0/192.0;
131e4dd521cSBarry Smith   rk->b1[4]=-2187.0/6784.0;
132e4dd521cSBarry Smith   rk->b1[5]=11.0/84.0;
133e4dd521cSBarry Smith   rk->b1[6]=0.0;
134e4dd521cSBarry Smith 
135e4dd521cSBarry Smith   rk->b2[0]=5179.0/57600.0;
136e4dd521cSBarry Smith   rk->b2[1]=0.0;
137e4dd521cSBarry Smith   rk->b2[2]=7571.0/16695.0;
138e4dd521cSBarry Smith   rk->b2[3]=393.0/640.0;
139e4dd521cSBarry Smith   rk->b2[4]=-92097.0/339200.0;
140e4dd521cSBarry Smith   rk->b2[5]=187.0/2100.0;
141e4dd521cSBarry Smith   rk->b2[6]=1.0/40.0;
142e4dd521cSBarry Smith 
143e4dd521cSBarry Smith 
144e4dd521cSBarry Smith   /* Found in table on page 170: Fehlberg 4(5) */
145e4dd521cSBarry Smith   /*
146e4dd521cSBarry Smith   rk->p=5;
147e4dd521cSBarry Smith   rk->s=6;
148e4dd521cSBarry Smith 
149e4dd521cSBarry Smith   rk->a[1][0]=1.0/4.0;
150e4dd521cSBarry Smith   rk->a[2][0]=3.0/32.0;
151e4dd521cSBarry Smith   rk->a[2][1]=9.0/32.0;
152e4dd521cSBarry Smith   rk->a[3][0]=1932.0/2197.0;
153e4dd521cSBarry Smith   rk->a[3][1]=-7200.0/2197.0;
154e4dd521cSBarry Smith   rk->a[3][2]=7296.0/2197.0;
155e4dd521cSBarry Smith   rk->a[4][0]=439.0/216.0;
156e4dd521cSBarry Smith   rk->a[4][1]=-8.0;
157e4dd521cSBarry Smith   rk->a[4][2]=3680.0/513.0;
158e4dd521cSBarry Smith   rk->a[4][3]=-845.0/4104.0;
159e4dd521cSBarry Smith   rk->a[5][0]=-8.0/27.0;
160e4dd521cSBarry Smith   rk->a[5][1]=2.0;
161e4dd521cSBarry Smith   rk->a[5][2]=-3544.0/2565.0;
162e4dd521cSBarry Smith   rk->a[5][3]=1859.0/4104.0;
163e4dd521cSBarry Smith   rk->a[5][4]=-11.0/40.0;
164e4dd521cSBarry Smith 
165e4dd521cSBarry Smith   rk->c[0]=0.0;
166e4dd521cSBarry Smith   rk->c[1]=1.0/4.0;
167e4dd521cSBarry Smith   rk->c[2]=3.0/8.0;
168e4dd521cSBarry Smith   rk->c[3]=12.0/13.0;
169e4dd521cSBarry Smith   rk->c[4]=1.0;
170e4dd521cSBarry Smith   rk->c[5]=1.0/2.0;
171e4dd521cSBarry Smith 
172e4dd521cSBarry Smith   rk->b1[0]=25.0/216.0;
173e4dd521cSBarry Smith   rk->b1[1]=0.0;
174e4dd521cSBarry Smith   rk->b1[2]=1408.0/2565.0;
175e4dd521cSBarry Smith   rk->b1[3]=2197.0/4104.0;
176e4dd521cSBarry Smith   rk->b1[4]=-1.0/5.0;
177e4dd521cSBarry Smith   rk->b1[5]=0.0;
178e4dd521cSBarry Smith 
179e4dd521cSBarry Smith   rk->b2[0]=16.0/135.0;
180e4dd521cSBarry Smith   rk->b2[1]=0.0;
181e4dd521cSBarry Smith   rk->b2[2]=6656.0/12825.0;
182e4dd521cSBarry Smith   rk->b2[3]=28561.0/56430.0;
183e4dd521cSBarry Smith   rk->b2[4]=-9.0/50.0;
184e4dd521cSBarry Smith   rk->b2[5]=2.0/55.0;
185e4dd521cSBarry Smith   */
186e4dd521cSBarry Smith   /* Found in table on page 169: Merson 4("5") */
187e4dd521cSBarry Smith   /*
188e4dd521cSBarry Smith   rk->p=4;
189e4dd521cSBarry Smith   rk->s=5;
190e4dd521cSBarry Smith   rk->a[1][0] = 1.0/3.0;
191e4dd521cSBarry Smith   rk->a[2][0] = 1.0/6.0;
192e4dd521cSBarry Smith   rk->a[2][1] = 1.0/6.0;
193e4dd521cSBarry Smith   rk->a[3][0] = 1.0/8.0;
194e4dd521cSBarry Smith   rk->a[3][1] = 0.0;
195e4dd521cSBarry Smith   rk->a[3][2] = 3.0/8.0;
196e4dd521cSBarry Smith   rk->a[4][0] = 1.0/2.0;
197e4dd521cSBarry Smith   rk->a[4][1] = 0.0;
198e4dd521cSBarry Smith   rk->a[4][2] = -3.0/2.0;
199e4dd521cSBarry Smith   rk->a[4][3] = 2.0;
200e4dd521cSBarry Smith 
201e4dd521cSBarry Smith   rk->c[0] = 0.0;
202e4dd521cSBarry Smith   rk->c[1] = 1.0/3.0;
203e4dd521cSBarry Smith   rk->c[2] = 1.0/3.0;
204e4dd521cSBarry Smith   rk->c[3] = 0.5;
205e4dd521cSBarry Smith   rk->c[4] = 1.0;
206e4dd521cSBarry Smith 
207e4dd521cSBarry Smith   rk->b1[0] = 1.0/2.0;
208e4dd521cSBarry Smith   rk->b1[1] = 0.0;
209e4dd521cSBarry Smith   rk->b1[2] = -3.0/2.0;
210e4dd521cSBarry Smith   rk->b1[3] = 2.0;
211e4dd521cSBarry Smith   rk->b1[4] = 0.0;
212e4dd521cSBarry Smith 
213e4dd521cSBarry Smith   rk->b2[0] = 1.0/6.0;
214e4dd521cSBarry Smith   rk->b2[1] = 0.0;
215e4dd521cSBarry Smith   rk->b2[2] = 0.0;
216e4dd521cSBarry Smith   rk->b2[3] = 2.0/3.0;
217e4dd521cSBarry Smith   rk->b2[4] = 1.0/6.0;
218e4dd521cSBarry Smith   */
219e4dd521cSBarry Smith 
220e4dd521cSBarry Smith   /* making b2 -> e=b1-b2 */
221e4dd521cSBarry Smith   /*
222e4dd521cSBarry Smith     for(i=0;i<rk->s;i++){
22326edb414Sasbjorn      rk->b2[i] = (rk->b1[i]) - (rk->b2[i]);
224e4dd521cSBarry Smith   }
225e4dd521cSBarry Smith   */
22626edb414Sasbjorn   rk->b2[0]=71.0/57600.0;
22726edb414Sasbjorn   rk->b2[1]=0.0;
22826edb414Sasbjorn   rk->b2[2]=-71.0/16695.0;
22926edb414Sasbjorn   rk->b2[3]=71.0/1920.0;
23026edb414Sasbjorn   rk->b2[4]=-17253.0/339200.0;
23126edb414Sasbjorn   rk->b2[5]=22.0/525.0;
23226edb414Sasbjorn   rk->b2[6]=-1.0/40.0;
23326edb414Sasbjorn 
234e4dd521cSBarry Smith   /* initializing vectors */
235e4dd521cSBarry Smith   ierr = VecDuplicate(ts->vec_sol,&rk->y1);CHKERRQ(ierr);
236e4dd521cSBarry Smith   ierr = VecDuplicate(ts->vec_sol,&rk->y2);CHKERRQ(ierr);
237e4dd521cSBarry Smith   ierr = VecDuplicate(rk->y1,&rk->tmp);CHKERRQ(ierr);
238e4dd521cSBarry Smith   ierr = VecDuplicate(rk->y1,&rk->tmp_y);CHKERRQ(ierr);
239e4dd521cSBarry Smith   ierr = VecDuplicateVecs(rk->y1,rk->s,&rk->k);CHKERRQ(ierr);
240e4dd521cSBarry Smith 
241e4dd521cSBarry Smith   PetscFunctionReturn(0);
242e4dd521cSBarry Smith }
243e4dd521cSBarry Smith 
244db046809SBarry Smith /*------------------------------------------------------------*/
245db046809SBarry Smith #undef __FUNCT__
246db046809SBarry Smith #define __FUNCT__ "TSRkqs"
247dfbe8321SBarry Smith PetscErrorCode TSRkqs(TS ts,PetscReal t,PetscReal h)
248db046809SBarry Smith {
249db046809SBarry Smith   TS_Rk		*rk = (TS_Rk*)ts->data;
250*6849ba73SBarry Smith   PetscErrorCode ierr;
251*6849ba73SBarry Smith   int		j,l;
252db046809SBarry Smith   PetscReal	tmp_t=t;
253db046809SBarry Smith   PetscScalar	null=0.0,hh=h;
254db046809SBarry Smith 
255db046809SBarry Smith   /*  printf("h: %f, hh: %f",h,hh); */
256db046809SBarry Smith 
257db046809SBarry Smith   PetscFunctionBegin;
258db046809SBarry Smith 
259db046809SBarry Smith   /* k[0]=0  */
260db046809SBarry Smith   ierr = VecSet(&null,rk->k[0]);CHKERRQ(ierr);
261db046809SBarry Smith 
262db046809SBarry Smith   /* k[0] = derivs(t,y1) */
263db046809SBarry Smith   ierr = TSComputeRHSFunction(ts,t,rk->y1,rk->k[0]);CHKERRQ(ierr);
264db046809SBarry Smith   /* looping over runge-kutta variables */
265db046809SBarry Smith   /* building the k - array of vectors */
266db046809SBarry Smith   for(j = 1 ; j < rk->s ; j++){
267db046809SBarry Smith 
268db046809SBarry Smith      /* rk->tmp = 0 */
269db046809SBarry Smith      ierr = VecSet(&null,rk->tmp);CHKERRQ(ierr);
270db046809SBarry Smith 
271db046809SBarry Smith      for(l=0;l<j;l++){
272db046809SBarry Smith 	/* tmp += a(j,l)*k[l] */
273db046809SBarry Smith 	/* ierr = PetscPrintf(PETSC_COMM_WORLD,"a(%i,%i)=%f \n",j,l,rk->a[j][l]);CHKERRQ(ierr); */
274db046809SBarry Smith 	ierr = VecAXPY(&rk->a[j][l],rk->k[l],rk->tmp);CHKERRQ(ierr);
275db046809SBarry Smith      }
276db046809SBarry Smith 
277db046809SBarry Smith      /* ierr = VecView(rk->tmp,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); */
278db046809SBarry Smith 
279db046809SBarry Smith      /* k[j] = derivs(t+c(j)*h,y1+h*tmp,k(j)) */
280db046809SBarry Smith      /* I need the following helpers:
281db046809SBarry Smith 	PetscScalar  tmp_t=t+c(j)*h
282db046809SBarry Smith 	Vec          tmp_y=h*tmp+y1
283db046809SBarry Smith      */
284db046809SBarry Smith 
285db046809SBarry Smith      tmp_t = t + rk->c[j] * h;
286db046809SBarry Smith 
287db046809SBarry Smith      /* tmp_y = h * tmp + y1 */
288db046809SBarry Smith      ierr = VecWAXPY(&hh,rk->tmp,rk->y1,rk->tmp_y);CHKERRQ(ierr);
289db046809SBarry Smith 
290db046809SBarry Smith      /* rk->k[j]=0 */
291db046809SBarry Smith      ierr = VecSet(&null,rk->k[j]);CHKERRQ(ierr);
292db046809SBarry Smith      ierr = TSComputeRHSFunction(ts,tmp_t,rk->tmp_y,rk->k[j]);CHKERRQ(ierr);
293db046809SBarry Smith   }
294db046809SBarry Smith 
295db046809SBarry Smith   /* tmp=0 and tmp_y=0 */
296db046809SBarry Smith   ierr = VecSet(&null,rk->tmp);CHKERRQ(ierr);
297db046809SBarry Smith   ierr = VecSet(&null,rk->tmp_y);CHKERRQ(ierr);
298db046809SBarry Smith 
299db046809SBarry Smith   for(j = 0 ; j < rk->s ; j++){
300db046809SBarry Smith      /* tmp=b1[j]*k[j]+tmp  */
301db046809SBarry Smith      ierr = VecAXPY(&rk->b1[j],rk->k[j],rk->tmp);CHKERRQ(ierr);
302db046809SBarry Smith      /* tmp_y=b2[j]*k[j]+tmp_y */
303db046809SBarry Smith      ierr = VecAXPY(&rk->b2[j],rk->k[j],rk->tmp_y);CHKERRQ(ierr);
304db046809SBarry Smith   }
305db046809SBarry Smith 
306db046809SBarry Smith   /* y2 = hh * tmp_y */
307db046809SBarry Smith   ierr = VecSet(&null,rk->y2);CHKERRQ(ierr);
308db046809SBarry Smith   ierr = VecAXPY(&hh,rk->tmp_y,rk->y2);CHKERRQ(ierr);
309db046809SBarry Smith   /* y1 = hh*tmp + y1 */
310db046809SBarry Smith   ierr = VecAXPY(&hh,rk->tmp,rk->y1);CHKERRQ(ierr);
311db046809SBarry Smith   /* Finding difference between y1 and y2 */
312db046809SBarry Smith 
313db046809SBarry Smith   PetscFunctionReturn(0);
314db046809SBarry Smith }
315db046809SBarry Smith 
316e4dd521cSBarry Smith #undef __FUNCT__
317e4dd521cSBarry Smith #define __FUNCT__ "TSStep_Rk"
318*6849ba73SBarry Smith static PetscErrorCode TSStep_Rk(TS ts,int *steps,PetscReal *ptime)
319e4dd521cSBarry Smith {
320e4dd521cSBarry Smith   TS_Rk		*rk = (TS_Rk*)ts->data;
32135b76a18SSatish Balay   int		ierr;
322e4dd521cSBarry Smith   PetscReal	dt = 0.001; /* fixed first step guess */
323b0dd9724SMatthew Knepley   PetscReal	norm=0.0,dt_fac=0.0,fac = 0.0/*,ttmp=0.0*/;
324e4dd521cSBarry Smith 
325e4dd521cSBarry Smith   PetscFunctionBegin;
3262cdf8120Sasbjorn   rk->start=clock();
327e4dd521cSBarry Smith   ierr=VecCopy(ts->vec_sol,rk->y1);CHKERRQ(ierr);
328e4dd521cSBarry Smith   *steps = -ts->steps;
329e4dd521cSBarry Smith   /* trying to save the vector */
330e4dd521cSBarry Smith   ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
331e4dd521cSBarry Smith   /* while loop to get from start to stop */
332e4dd521cSBarry Smith   while (ts->ptime < ts->max_time){
333e4dd521cSBarry Smith    /* calling rkqs */
334e4dd521cSBarry Smith      /*
335e4dd521cSBarry Smith        -- input
336e4dd521cSBarry Smith        ts        - pointer to ts
337e4dd521cSBarry Smith        ts->ptime - current time
338e4dd521cSBarry Smith        dt        - try this timestep
339e4dd521cSBarry Smith        y1        - solution for this step
340e4dd521cSBarry Smith 
341e4dd521cSBarry Smith        --output
342e4dd521cSBarry Smith        y1        - suggested solution
343e4dd521cSBarry Smith        y2        - check solution (runge - kutta second permutation)
344e4dd521cSBarry Smith      */
345e4dd521cSBarry Smith      ierr = TSRkqs(ts,ts->ptime,dt);CHKERRQ(ierr);
346e4dd521cSBarry Smith    /* checking for maxerror */
347e4dd521cSBarry Smith      /* comparing difference to maxerror */
348e4dd521cSBarry Smith      ierr = VecNorm(rk->y2,NORM_2,&norm);CHKERRQ(ierr);
349e4dd521cSBarry Smith      /* modifying maxerror to satisfy this timestep */
350e4dd521cSBarry Smith      rk->maxerror = rk->ferror * dt;
351e4dd521cSBarry Smith      /* ierr = PetscPrintf(PETSC_COMM_WORLD,"norm err: %f maxerror: %f dt: %f",norm,rk->maxerror,dt);CHKERRQ(ierr); */
352e4dd521cSBarry Smith 
353e4dd521cSBarry Smith    /* handling ok and not ok */
354e4dd521cSBarry Smith      if(norm < rk->maxerror){
355e4dd521cSBarry Smith 	/* if ok: */
356e4dd521cSBarry Smith         ierr=VecCopy(rk->y1,ts->vec_sol);CHKERRQ(ierr); /* saves the suggested solution to current solution */
357e4dd521cSBarry Smith         ts->ptime += dt; /* storing the new current time */
358e4dd521cSBarry Smith 	rk->nok++;
359e4dd521cSBarry Smith 	fac=5.0;
360e4dd521cSBarry Smith 	/* trying to save the vector */
361e4dd521cSBarry Smith        /* calling monitor */
362e4dd521cSBarry Smith        ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
363e4dd521cSBarry Smith      }else{
364e4dd521cSBarry Smith 	/* if not OK */
365e4dd521cSBarry Smith 	rk->nnok++;
366e4dd521cSBarry Smith 	fac=1.0;
367e4dd521cSBarry Smith 	ierr=VecCopy(ts->vec_sol,rk->y1);CHKERRQ(ierr);  /* restores old solution */
368e4dd521cSBarry Smith      }
369e4dd521cSBarry Smith 
370e4dd521cSBarry Smith      /*Computing next stepsize. See page 167 in Solving ODE 1
371e4dd521cSBarry Smith       *
372e4dd521cSBarry Smith       * h_new = h * min( facmax , max( facmin , fac * (tol/err)^(1/(p+1)) ) )
373e4dd521cSBarry Smith       * facmax set above
374e4dd521cSBarry Smith       * facmin
375e4dd521cSBarry Smith       */
376e4dd521cSBarry Smith      dt_fac = exp(log((rk->maxerror) / norm) / ((rk->p) + 1) ) * 0.9 ;
377e4dd521cSBarry Smith 
378e4dd521cSBarry Smith      if(dt_fac > fac){
3792cdf8120Sasbjorn         /*ierr = PetscPrintf(PETSC_COMM_WORLD,"changing fac %f\n",fac);*/
380e4dd521cSBarry Smith 	dt_fac = fac;
381e4dd521cSBarry Smith      }
382e4dd521cSBarry Smith 
383e4dd521cSBarry Smith      /* computing new dt */
384e4dd521cSBarry Smith      dt = dt * dt_fac;
385e4dd521cSBarry Smith 
386e4dd521cSBarry Smith      if(ts->ptime+dt > ts->max_time){
387e4dd521cSBarry Smith 	dt = ts->max_time - ts->ptime;
388e4dd521cSBarry Smith      }
389e4dd521cSBarry Smith 
3902cdf8120Sasbjorn      if(dt < 1e-14){
391e4dd521cSBarry Smith 	ierr = PetscPrintf(PETSC_COMM_WORLD,"Very small steps: %f\n",dt);CHKERRQ(ierr);
3922cdf8120Sasbjorn 	dt = 1e-14;
393e4dd521cSBarry Smith      }
394e4dd521cSBarry Smith 
395e4dd521cSBarry Smith      /* trying to purify h */
396e4dd521cSBarry Smith      /* (did not give any visible result) */
3972cdf8120Sasbjorn      /* ttmp = ts->ptime + dt;
3982cdf8120Sasbjorn 	dt = ttmp - ts->ptime; */
399e4dd521cSBarry Smith 
400e4dd521cSBarry Smith      /* counting steps */
401e4dd521cSBarry Smith      ts->steps++;
402e4dd521cSBarry Smith   }
403e4dd521cSBarry Smith 
404e4dd521cSBarry Smith   ierr=VecCopy(rk->y1,ts->vec_sol);CHKERRQ(ierr);
405e4dd521cSBarry Smith   *steps += ts->steps;
406e4dd521cSBarry Smith   *ptime  = ts->ptime;
4072cdf8120Sasbjorn   rk->end=clock();
408e4dd521cSBarry Smith   PetscFunctionReturn(0);
409e4dd521cSBarry Smith }
410e4dd521cSBarry Smith 
411e4dd521cSBarry Smith /*------------------------------------------------------------*/
412e4dd521cSBarry Smith #undef __FUNCT__
413e4dd521cSBarry Smith #define __FUNCT__ "TSDestroy_Rk"
414*6849ba73SBarry Smith static PetscErrorCode TSDestroy_Rk(TS ts)
415e4dd521cSBarry Smith {
416e4dd521cSBarry Smith   TS_Rk *rk = (TS_Rk*)ts->data;
417*6849ba73SBarry Smith   PetscErrorCode ierr;
418*6849ba73SBarry Smith   int   i;
419e4dd521cSBarry Smith 
420e4dd521cSBarry Smith   /* REMEMBER TO DESTROY ALL */
421e4dd521cSBarry Smith 
422e4dd521cSBarry Smith   PetscFunctionBegin;
423e4dd521cSBarry Smith   if (rk->y1) {ierr = VecDestroy(rk->y1);CHKERRQ(ierr);}
424e4dd521cSBarry Smith   if (rk->y2) {ierr = VecDestroy(rk->y2);CHKERRQ(ierr);}
425e4dd521cSBarry Smith   if (rk->tmp) {ierr = VecDestroy(rk->tmp);CHKERRQ(ierr);}
426e4dd521cSBarry Smith   if (rk->tmp_y) {ierr = VecDestroy(rk->tmp_y);CHKERRQ(ierr);}
427e4dd521cSBarry Smith   for(i=0;i<rk->s;i++){
428e4dd521cSBarry Smith      if (rk->k[i]) {ierr = VecDestroy(rk->k[i]);CHKERRQ(ierr);}
429e4dd521cSBarry Smith   }
430e4dd521cSBarry Smith   ierr = PetscFree(rk);CHKERRQ(ierr);
431e4dd521cSBarry Smith   PetscFunctionReturn(0);
432e4dd521cSBarry Smith }
433e4dd521cSBarry Smith /*------------------------------------------------------------*/
434e4dd521cSBarry Smith 
435e4dd521cSBarry Smith #undef __FUNCT__
436e4dd521cSBarry Smith #define __FUNCT__ "TSSetFromOptions_Rk"
437*6849ba73SBarry Smith static PetscErrorCode TSSetFromOptions_Rk(TS ts)
438e4dd521cSBarry Smith {
439262ff7bbSBarry Smith   TS_Rk *rk = (TS_Rk*)ts->data;
440dfbe8321SBarry Smith   PetscErrorCode ierr;
441262ff7bbSBarry Smith 
442e4dd521cSBarry Smith   PetscFunctionBegin;
443262ff7bbSBarry Smith   ierr = PetscOptionsHead("RK ODE solver options");CHKERRQ(ierr);
444262ff7bbSBarry Smith     ierr = PetscOptionsReal("-ts_rk_tol","Tolerance for convergence","TSRKSetTolerance",rk->tolerance,&rk->tolerance,PETSC_NULL);CHKERRQ(ierr);
445262ff7bbSBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
446e4dd521cSBarry Smith   PetscFunctionReturn(0);
447e4dd521cSBarry Smith }
448e4dd521cSBarry Smith 
449e4dd521cSBarry Smith #undef __FUNCT__
450e4dd521cSBarry Smith #define __FUNCT__ "TSView_Rk"
451*6849ba73SBarry Smith static PetscErrorCode TSView_Rk(TS ts,PetscViewer viewer)
452e4dd521cSBarry Smith {
453e4dd521cSBarry Smith    TS_Rk *rk = (TS_Rk*)ts->data;
454dfbe8321SBarry Smith    PetscErrorCode ierr;
455b0dd9724SMatthew Knepley    /*double elapsed;*/
4562cdf8120Sasbjorn 
457e4dd521cSBarry Smith    PetscFunctionBegin;
458e4dd521cSBarry Smith    ierr = PetscPrintf(PETSC_COMM_WORLD,"  number of ok steps: %d\n",rk->nok);CHKERRQ(ierr);
4592cdf8120Sasbjorn    ierr = PetscPrintf(PETSC_COMM_WORLD,"  number of rejected steps: %d\n",rk->nnok);CHKERRQ(ierr);
4602cdf8120Sasbjorn    /*   elapsed = ((double) (rk->end - rk->start)) / CLOCKS_PER_SEC;
4612cdf8120Sasbjorn 
4622cdf8120Sasbjorn    ierr = PetscPrintf(PETSC_COMM_WORLD,"  CPU time used (in seconds): %f\n",elapsed);CHKERRQ(ierr); */
463e4dd521cSBarry Smith    PetscFunctionReturn(0);
464e4dd521cSBarry Smith }
465e4dd521cSBarry Smith 
466e4dd521cSBarry Smith /* ------------------------------------------------------------ */
467ebe3b25bSBarry Smith /*MC
468ebe3b25bSBarry Smith       TS_RK - ODE solver using the explicit Runge-Kutta methods
469ebe3b25bSBarry Smith 
470ebe3b25bSBarry Smith    Options Database:
471ebe3b25bSBarry Smith .  -ts_rk_tol <tol> Tolerance for convergence
472ebe3b25bSBarry Smith 
473ebe3b25bSBarry Smith   Contributed by: Asbjorn Hoiland Aarrestad, asbjorn@aarrestad.com, http://asbjorn.aarrestad.com/
474ebe3b25bSBarry Smith 
475d41222bbSBarry Smith   Level: beginner
476d41222bbSBarry Smith 
477ebe3b25bSBarry Smith .seealso:  TSCreate(), TS, TSSetType(), TS_EULER, TSRKSetTolerance()
478ebe3b25bSBarry Smith 
479ebe3b25bSBarry Smith M*/
480ebe3b25bSBarry Smith 
481e4dd521cSBarry Smith EXTERN_C_BEGIN
482e4dd521cSBarry Smith #undef __FUNCT__
483e4dd521cSBarry Smith #define __FUNCT__ "TSCreate_Rk"
484dfbe8321SBarry Smith PetscErrorCode TSCreate_Rk(TS ts)
485e4dd521cSBarry Smith {
486e4dd521cSBarry Smith   TS_Rk    *rk;
487dfbe8321SBarry Smith   PetscErrorCode ierr;
488e4dd521cSBarry Smith 
489e4dd521cSBarry Smith   PetscFunctionBegin;
490e4dd521cSBarry Smith   ts->ops->setup           = TSSetUp_Rk;
491e4dd521cSBarry Smith   ts->ops->step            = TSStep_Rk;
492e4dd521cSBarry Smith   ts->ops->destroy         = TSDestroy_Rk;
493e4dd521cSBarry Smith   ts->ops->setfromoptions  = TSSetFromOptions_Rk;
494e4dd521cSBarry Smith   ts->ops->view            = TSView_Rk;
495e4dd521cSBarry Smith 
496e4dd521cSBarry Smith   ierr = PetscNew(TS_Rk,&rk);CHKERRQ(ierr);
497e4dd521cSBarry Smith   PetscLogObjectMemory(ts,sizeof(TS_Rk));
498e4dd521cSBarry Smith   ts->data = (void*)rk;
499e4dd521cSBarry Smith 
500262ff7bbSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRKSetTolerance_C","TSRKSetTolerance_RK",
501262ff7bbSBarry Smith                                            TSRKSetTolerance_RK);CHKERRQ(ierr);
502262ff7bbSBarry Smith 
503e4dd521cSBarry Smith   PetscFunctionReturn(0);
504e4dd521cSBarry Smith }
505e4dd521cSBarry Smith EXTERN_C_END
506e4dd521cSBarry Smith 
507e4dd521cSBarry Smith 
508e4dd521cSBarry Smith 
509e4dd521cSBarry Smith 
510