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