xref: /petsc/src/ts/impls/explicit/rk/rk.c (revision c5eb91543d2ee8daf880d93389b892228ddada03)
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  */
127c4f633dSBarry Smith #include "private/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 */
265f70b478SJed Brown } 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 {
335f70b478SJed Brown   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 
473f9fe445SBarry Smith    Logically 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 
570f3b3ca1SHong Zhang .seealso: TSSundialsSetTolerance()
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;
65*c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(ts,aabs,2);
66262ff7bbSBarry Smith   ierr = PetscObjectQueryFunction((PetscObject)ts,"TSRKSetTolerance_C",(void (**)(void))&f);CHKERRQ(ierr);
67262ff7bbSBarry Smith   if (f) {
68262ff7bbSBarry Smith     ierr = (*f)(ts,aabs);CHKERRQ(ierr);
69262ff7bbSBarry Smith   }
70262ff7bbSBarry Smith   PetscFunctionReturn(0);
71262ff7bbSBarry Smith }
72e4dd521cSBarry Smith 
73e4dd521cSBarry Smith 
74e4dd521cSBarry Smith #undef __FUNCT__
755f70b478SJed Brown #define __FUNCT__ "TSSetUp_RK"
765f70b478SJed Brown static PetscErrorCode TSSetUp_RK(TS ts)
77e4dd521cSBarry Smith {
785f70b478SJed Brown   TS_RK          *rk = (TS_RK*)ts->data;
79a7cc72afSBarry Smith   PetscErrorCode ierr;
80e4dd521cSBarry Smith 
81e4dd521cSBarry Smith   PetscFunctionBegin;
82e4dd521cSBarry Smith   rk->nok      = 0;
83e4dd521cSBarry Smith   rk->nnok     = 0;
84262ff7bbSBarry Smith   rk->maxerror = rk->tolerance;
85e4dd521cSBarry Smith 
86e4dd521cSBarry Smith   /* fixing maxerror: global vs local */
87e4dd521cSBarry Smith   rk->ferror = rk->maxerror / (ts->max_time - ts->ptime);
88e4dd521cSBarry Smith 
89e4dd521cSBarry Smith   /* 34.0/45.0 gives double precision division */
90e4dd521cSBarry Smith   /* defining variables needed for Runge-Kutta computing */
91e4dd521cSBarry Smith   /* when changing below, please remember to change a, b1, b2 and c above! */
92e4dd521cSBarry Smith   /* Found in table on page 171: Dormand-Prince 5(4) */
93e4dd521cSBarry Smith 
94e4dd521cSBarry Smith   /* are these right? */
95e4dd521cSBarry Smith   rk->p=6;
96e4dd521cSBarry Smith   rk->s=7;
97e4dd521cSBarry Smith 
98e4dd521cSBarry Smith   rk->a[1][0]=1.0/5.0;
99e4dd521cSBarry Smith   rk->a[2][0]=3.0/40.0;
100e4dd521cSBarry Smith   rk->a[2][1]=9.0/40.0;
101e4dd521cSBarry Smith   rk->a[3][0]=44.0/45.0;
102e4dd521cSBarry Smith   rk->a[3][1]=-56.0/15.0;
103e4dd521cSBarry Smith   rk->a[3][2]=32.0/9.0;
104e4dd521cSBarry Smith   rk->a[4][0]=19372.0/6561.0;
105e4dd521cSBarry Smith   rk->a[4][1]=-25360.0/2187.0;
106e4dd521cSBarry Smith   rk->a[4][2]=64448.0/6561.0;
107e4dd521cSBarry Smith   rk->a[4][3]=-212.0/729.0;
108e4dd521cSBarry Smith   rk->a[5][0]=9017.0/3168.0;
109e4dd521cSBarry Smith   rk->a[5][1]=-355.0/33.0;
110e4dd521cSBarry Smith   rk->a[5][2]=46732.0/5247.0;
111e4dd521cSBarry Smith   rk->a[5][3]=49.0/176.0;
112e4dd521cSBarry Smith   rk->a[5][4]=-5103.0/18656.0;
113e4dd521cSBarry Smith   rk->a[6][0]=35.0/384.0;
114e4dd521cSBarry Smith   rk->a[6][1]=0.0;
115e4dd521cSBarry Smith   rk->a[6][2]=500.0/1113.0;
116e4dd521cSBarry Smith   rk->a[6][3]=125.0/192.0;
117e4dd521cSBarry Smith   rk->a[6][4]=-2187.0/6784.0;
118e4dd521cSBarry Smith   rk->a[6][5]=11.0/84.0;
119e4dd521cSBarry Smith 
120e4dd521cSBarry Smith 
121e4dd521cSBarry Smith   rk->c[0]=0.0;
122e4dd521cSBarry Smith   rk->c[1]=1.0/5.0;
123e4dd521cSBarry Smith   rk->c[2]=3.0/10.0;
124e4dd521cSBarry Smith   rk->c[3]=4.0/5.0;
125e4dd521cSBarry Smith   rk->c[4]=8.0/9.0;
126e4dd521cSBarry Smith   rk->c[5]=1.0;
127e4dd521cSBarry Smith   rk->c[6]=1.0;
128e4dd521cSBarry Smith 
129e4dd521cSBarry Smith   rk->b1[0]=35.0/384.0;
130e4dd521cSBarry Smith   rk->b1[1]=0.0;
131e4dd521cSBarry Smith   rk->b1[2]=500.0/1113.0;
132e4dd521cSBarry Smith   rk->b1[3]=125.0/192.0;
133e4dd521cSBarry Smith   rk->b1[4]=-2187.0/6784.0;
134e4dd521cSBarry Smith   rk->b1[5]=11.0/84.0;
135e4dd521cSBarry Smith   rk->b1[6]=0.0;
136e4dd521cSBarry Smith 
137e4dd521cSBarry Smith   rk->b2[0]=5179.0/57600.0;
138e4dd521cSBarry Smith   rk->b2[1]=0.0;
139e4dd521cSBarry Smith   rk->b2[2]=7571.0/16695.0;
140e4dd521cSBarry Smith   rk->b2[3]=393.0/640.0;
141e4dd521cSBarry Smith   rk->b2[4]=-92097.0/339200.0;
142e4dd521cSBarry Smith   rk->b2[5]=187.0/2100.0;
143e4dd521cSBarry Smith   rk->b2[6]=1.0/40.0;
144e4dd521cSBarry Smith 
145e4dd521cSBarry Smith 
146e4dd521cSBarry Smith   /* Found in table on page 170: Fehlberg 4(5) */
147e4dd521cSBarry Smith   /*
148e4dd521cSBarry Smith   rk->p=5;
149e4dd521cSBarry Smith   rk->s=6;
150e4dd521cSBarry Smith 
151e4dd521cSBarry Smith   rk->a[1][0]=1.0/4.0;
152e4dd521cSBarry Smith   rk->a[2][0]=3.0/32.0;
153e4dd521cSBarry Smith   rk->a[2][1]=9.0/32.0;
154e4dd521cSBarry Smith   rk->a[3][0]=1932.0/2197.0;
155e4dd521cSBarry Smith   rk->a[3][1]=-7200.0/2197.0;
156e4dd521cSBarry Smith   rk->a[3][2]=7296.0/2197.0;
157e4dd521cSBarry Smith   rk->a[4][0]=439.0/216.0;
158e4dd521cSBarry Smith   rk->a[4][1]=-8.0;
159e4dd521cSBarry Smith   rk->a[4][2]=3680.0/513.0;
160e4dd521cSBarry Smith   rk->a[4][3]=-845.0/4104.0;
161e4dd521cSBarry Smith   rk->a[5][0]=-8.0/27.0;
162e4dd521cSBarry Smith   rk->a[5][1]=2.0;
163e4dd521cSBarry Smith   rk->a[5][2]=-3544.0/2565.0;
164e4dd521cSBarry Smith   rk->a[5][3]=1859.0/4104.0;
165e4dd521cSBarry Smith   rk->a[5][4]=-11.0/40.0;
166e4dd521cSBarry Smith 
167e4dd521cSBarry Smith   rk->c[0]=0.0;
168e4dd521cSBarry Smith   rk->c[1]=1.0/4.0;
169e4dd521cSBarry Smith   rk->c[2]=3.0/8.0;
170e4dd521cSBarry Smith   rk->c[3]=12.0/13.0;
171e4dd521cSBarry Smith   rk->c[4]=1.0;
172e4dd521cSBarry Smith   rk->c[5]=1.0/2.0;
173e4dd521cSBarry Smith 
174e4dd521cSBarry Smith   rk->b1[0]=25.0/216.0;
175e4dd521cSBarry Smith   rk->b1[1]=0.0;
176e4dd521cSBarry Smith   rk->b1[2]=1408.0/2565.0;
177e4dd521cSBarry Smith   rk->b1[3]=2197.0/4104.0;
178e4dd521cSBarry Smith   rk->b1[4]=-1.0/5.0;
179e4dd521cSBarry Smith   rk->b1[5]=0.0;
180e4dd521cSBarry Smith 
181e4dd521cSBarry Smith   rk->b2[0]=16.0/135.0;
182e4dd521cSBarry Smith   rk->b2[1]=0.0;
183e4dd521cSBarry Smith   rk->b2[2]=6656.0/12825.0;
184e4dd521cSBarry Smith   rk->b2[3]=28561.0/56430.0;
185e4dd521cSBarry Smith   rk->b2[4]=-9.0/50.0;
186e4dd521cSBarry Smith   rk->b2[5]=2.0/55.0;
187e4dd521cSBarry Smith   */
188e4dd521cSBarry Smith   /* Found in table on page 169: Merson 4("5") */
189e4dd521cSBarry Smith   /*
190e4dd521cSBarry Smith   rk->p=4;
191e4dd521cSBarry Smith   rk->s=5;
192e4dd521cSBarry Smith   rk->a[1][0] = 1.0/3.0;
193e4dd521cSBarry Smith   rk->a[2][0] = 1.0/6.0;
194e4dd521cSBarry Smith   rk->a[2][1] = 1.0/6.0;
195e4dd521cSBarry Smith   rk->a[3][0] = 1.0/8.0;
196e4dd521cSBarry Smith   rk->a[3][1] = 0.0;
197e4dd521cSBarry Smith   rk->a[3][2] = 3.0/8.0;
198e4dd521cSBarry Smith   rk->a[4][0] = 1.0/2.0;
199e4dd521cSBarry Smith   rk->a[4][1] = 0.0;
200e4dd521cSBarry Smith   rk->a[4][2] = -3.0/2.0;
201e4dd521cSBarry Smith   rk->a[4][3] = 2.0;
202e4dd521cSBarry Smith 
203e4dd521cSBarry Smith   rk->c[0] = 0.0;
204e4dd521cSBarry Smith   rk->c[1] = 1.0/3.0;
205e4dd521cSBarry Smith   rk->c[2] = 1.0/3.0;
206e4dd521cSBarry Smith   rk->c[3] = 0.5;
207e4dd521cSBarry Smith   rk->c[4] = 1.0;
208e4dd521cSBarry Smith 
209e4dd521cSBarry Smith   rk->b1[0] = 1.0/2.0;
210e4dd521cSBarry Smith   rk->b1[1] = 0.0;
211e4dd521cSBarry Smith   rk->b1[2] = -3.0/2.0;
212e4dd521cSBarry Smith   rk->b1[3] = 2.0;
213e4dd521cSBarry Smith   rk->b1[4] = 0.0;
214e4dd521cSBarry Smith 
215e4dd521cSBarry Smith   rk->b2[0] = 1.0/6.0;
216e4dd521cSBarry Smith   rk->b2[1] = 0.0;
217e4dd521cSBarry Smith   rk->b2[2] = 0.0;
218e4dd521cSBarry Smith   rk->b2[3] = 2.0/3.0;
219e4dd521cSBarry Smith   rk->b2[4] = 1.0/6.0;
220e4dd521cSBarry Smith   */
221e4dd521cSBarry Smith 
222e4dd521cSBarry Smith   /* making b2 -> e=b1-b2 */
223e4dd521cSBarry Smith   /*
224e4dd521cSBarry Smith     for(i=0;i<rk->s;i++){
22526edb414Sasbjorn      rk->b2[i] = (rk->b1[i]) - (rk->b2[i]);
226e4dd521cSBarry Smith   }
227e4dd521cSBarry Smith   */
22826edb414Sasbjorn   rk->b2[0]=71.0/57600.0;
22926edb414Sasbjorn   rk->b2[1]=0.0;
23026edb414Sasbjorn   rk->b2[2]=-71.0/16695.0;
23126edb414Sasbjorn   rk->b2[3]=71.0/1920.0;
23226edb414Sasbjorn   rk->b2[4]=-17253.0/339200.0;
23326edb414Sasbjorn   rk->b2[5]=22.0/525.0;
23426edb414Sasbjorn   rk->b2[6]=-1.0/40.0;
23526edb414Sasbjorn 
236e4dd521cSBarry Smith   /* initializing vectors */
237e4dd521cSBarry Smith   ierr = VecDuplicate(ts->vec_sol,&rk->y1);CHKERRQ(ierr);
238e4dd521cSBarry Smith   ierr = VecDuplicate(ts->vec_sol,&rk->y2);CHKERRQ(ierr);
239e4dd521cSBarry Smith   ierr = VecDuplicate(rk->y1,&rk->tmp);CHKERRQ(ierr);
240e4dd521cSBarry Smith   ierr = VecDuplicate(rk->y1,&rk->tmp_y);CHKERRQ(ierr);
241e4dd521cSBarry Smith   ierr = VecDuplicateVecs(rk->y1,rk->s,&rk->k);CHKERRQ(ierr);
242e4dd521cSBarry Smith 
243e4dd521cSBarry Smith   PetscFunctionReturn(0);
244e4dd521cSBarry Smith }
245e4dd521cSBarry Smith 
246db046809SBarry Smith /*------------------------------------------------------------*/
247db046809SBarry Smith #undef __FUNCT__
2485f70b478SJed Brown #define __FUNCT__ "TSRKqs"
2495f70b478SJed Brown PetscErrorCode TSRKqs(TS ts,PetscReal t,PetscReal h)
250db046809SBarry Smith {
2515f70b478SJed Brown   TS_RK          *rk = (TS_RK*)ts->data;
2526849ba73SBarry Smith   PetscErrorCode ierr;
253a7cc72afSBarry Smith   PetscInt       j,l;
254db046809SBarry Smith   PetscReal      tmp_t=t;
255b05257ddSBarry Smith   PetscScalar    hh=h;
256db046809SBarry Smith 
257db046809SBarry Smith   PetscFunctionBegin;
258db046809SBarry Smith   /* k[0]=0  */
259b05257ddSBarry Smith   ierr = VecSet(rk->k[0],0.0);CHKERRQ(ierr);
260db046809SBarry Smith 
261db046809SBarry Smith   /* k[0] = derivs(t,y1) */
262db046809SBarry Smith   ierr = TSComputeRHSFunction(ts,t,rk->y1,rk->k[0]);CHKERRQ(ierr);
263db046809SBarry Smith   /* looping over runge-kutta variables */
264db046809SBarry Smith   /* building the k - array of vectors */
265db046809SBarry Smith   for(j = 1 ; j < rk->s ; j++){
266db046809SBarry Smith 
267db046809SBarry Smith      /* rk->tmp = 0 */
268b05257ddSBarry Smith      ierr = VecSet(rk->tmp,0.0);CHKERRQ(ierr);
269db046809SBarry Smith 
270db046809SBarry Smith      for(l=0;l<j;l++){
271db046809SBarry Smith         /* tmp += a(j,l)*k[l] */
2722dcb1b2aSMatthew Knepley        ierr = VecAXPY(rk->tmp,rk->a[j][l],rk->k[l]);CHKERRQ(ierr);
273db046809SBarry Smith      }
274db046809SBarry Smith 
275db046809SBarry Smith      /* ierr = VecView(rk->tmp,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); */
276db046809SBarry Smith 
277db046809SBarry Smith      /* k[j] = derivs(t+c(j)*h,y1+h*tmp,k(j)) */
278db046809SBarry Smith      /* I need the following helpers:
279db046809SBarry Smith         PetscScalar  tmp_t=t+c(j)*h
280db046809SBarry Smith         Vec          tmp_y=h*tmp+y1
281db046809SBarry Smith      */
282db046809SBarry Smith 
283db046809SBarry Smith      tmp_t = t + rk->c[j] * h;
284db046809SBarry Smith 
285db046809SBarry Smith      /* tmp_y = h * tmp + y1 */
2862dcb1b2aSMatthew Knepley      ierr = VecWAXPY(rk->tmp_y,hh,rk->tmp,rk->y1);CHKERRQ(ierr);
287db046809SBarry Smith 
288db046809SBarry Smith      /* rk->k[j]=0 */
289b05257ddSBarry Smith      ierr = VecSet(rk->k[j],0.0);CHKERRQ(ierr);
290db046809SBarry Smith      ierr = TSComputeRHSFunction(ts,tmp_t,rk->tmp_y,rk->k[j]);CHKERRQ(ierr);
291db046809SBarry Smith   }
292db046809SBarry Smith 
293db046809SBarry Smith   /* tmp=0 and tmp_y=0 */
294b05257ddSBarry Smith   ierr = VecSet(rk->tmp,0.0);CHKERRQ(ierr);
295b05257ddSBarry Smith   ierr = VecSet(rk->tmp_y,0.0);CHKERRQ(ierr);
296db046809SBarry Smith 
297db046809SBarry Smith   for(j = 0 ; j < rk->s ; j++){
298db046809SBarry Smith      /* tmp=b1[j]*k[j]+tmp  */
2992dcb1b2aSMatthew Knepley     ierr = VecAXPY(rk->tmp,rk->b1[j],rk->k[j]);CHKERRQ(ierr);
300db046809SBarry Smith      /* tmp_y=b2[j]*k[j]+tmp_y */
3012dcb1b2aSMatthew Knepley     ierr = VecAXPY(rk->tmp_y,rk->b2[j],rk->k[j]);CHKERRQ(ierr);
302db046809SBarry Smith   }
303db046809SBarry Smith 
304db046809SBarry Smith   /* y2 = hh * tmp_y */
305b05257ddSBarry Smith   ierr = VecSet(rk->y2,0.0);CHKERRQ(ierr);
3062dcb1b2aSMatthew Knepley   ierr = VecAXPY(rk->y2,hh,rk->tmp_y);CHKERRQ(ierr);
307db046809SBarry Smith   /* y1 = hh*tmp + y1 */
3082dcb1b2aSMatthew Knepley   ierr = VecAXPY(rk->y1,hh,rk->tmp);CHKERRQ(ierr);
309db046809SBarry Smith   /* Finding difference between y1 and y2 */
310db046809SBarry Smith   PetscFunctionReturn(0);
311db046809SBarry Smith }
312db046809SBarry Smith 
313e4dd521cSBarry Smith #undef __FUNCT__
3145f70b478SJed Brown #define __FUNCT__ "TSStep_RK"
3155f70b478SJed Brown static PetscErrorCode TSStep_RK(TS ts,PetscInt *steps,PetscReal *ptime)
316e4dd521cSBarry Smith {
3175f70b478SJed Brown   TS_RK          *rk = (TS_RK*)ts->data;
318a7cc72afSBarry Smith   PetscErrorCode ierr;
319b0dd9724SMatthew Knepley   PetscReal      norm=0.0,dt_fac=0.0,fac = 0.0/*,ttmp=0.0*/;
320e3caeda6SBarry Smith   PetscInt       i, max_steps = ts->max_steps;
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 */
328e3caeda6SBarry Smith   for (i = 0; i < max_steps; i++) {
3293f2090d5SJed Brown     ierr = TSPreStep(ts);CHKERRQ(ierr); /* Note that this is called once per STEP, not once per STAGE. */
330e4dd521cSBarry Smith    /* calling rkqs */
331e4dd521cSBarry Smith      /*
332e4dd521cSBarry Smith        -- input
333e4dd521cSBarry Smith        ts        - pointer to ts
334e4dd521cSBarry Smith        ts->ptime - current time
335b05257ddSBarry Smith        ts->time_step        - try this timestep
336e4dd521cSBarry Smith        y1        - solution for this step
337e4dd521cSBarry Smith 
338e4dd521cSBarry Smith        --output
339e4dd521cSBarry Smith        y1        - suggested solution
340e4dd521cSBarry Smith        y2        - check solution (runge - kutta second permutation)
341e4dd521cSBarry Smith      */
3425f70b478SJed Brown      ierr = TSRKqs(ts,ts->ptime,ts->time_step);CHKERRQ(ierr);
343e3caeda6SBarry Smith      /* counting steps */
344e3caeda6SBarry Smith      ts->steps++;
345e4dd521cSBarry Smith    /* checking for maxerror */
346e4dd521cSBarry Smith      /* comparing difference to maxerror */
347e4dd521cSBarry Smith      ierr = VecNorm(rk->y2,NORM_2,&norm);CHKERRQ(ierr);
348e4dd521cSBarry Smith      /* modifying maxerror to satisfy this timestep */
349b05257ddSBarry Smith      rk->maxerror = rk->ferror * ts->time_step;
350b05257ddSBarry Smith      /* ierr = PetscPrintf(PETSC_COMM_WORLD,"norm err: %f maxerror: %f dt: %f",norm,rk->maxerror,ts->time_step);CHKERRQ(ierr); */
351e4dd521cSBarry Smith 
352e4dd521cSBarry Smith    /* handling ok and not ok */
353e4dd521cSBarry Smith      if (norm < rk->maxerror){
354e4dd521cSBarry Smith         /* if ok: */
355e4dd521cSBarry Smith         ierr=VecCopy(rk->y1,ts->vec_sol);CHKERRQ(ierr); /* saves the suggested solution to current solution */
356b05257ddSBarry Smith         ts->ptime += ts->time_step; /* storing the new current time */
357e4dd521cSBarry Smith         rk->nok++;
358e4dd521cSBarry Smith         fac=5.0;
359e4dd521cSBarry Smith         /* trying to save the vector */
3603f2090d5SJed Brown         ierr = TSPostStep(ts);CHKERRQ(ierr);
361e4dd521cSBarry Smith         ierr = TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol);CHKERRQ(ierr);
362e3caeda6SBarry Smith         if (ts->ptime >= ts->max_time) break;
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 
383b05257ddSBarry Smith      /* computing new ts->time_step */
384b05257ddSBarry Smith      ts->time_step = ts->time_step * dt_fac;
385e4dd521cSBarry Smith 
386b05257ddSBarry Smith      if (ts->ptime+ts->time_step > ts->max_time){
387b05257ddSBarry Smith         ts->time_step = ts->max_time - ts->ptime;
388e4dd521cSBarry Smith      }
389e4dd521cSBarry Smith 
390b05257ddSBarry Smith      if (ts->time_step < 1e-14){
391b05257ddSBarry Smith         ierr = PetscPrintf(PETSC_COMM_WORLD,"Very small steps: %f\n",ts->time_step);CHKERRQ(ierr);
392b05257ddSBarry Smith         ts->time_step = 1e-14;
393e4dd521cSBarry Smith      }
394e4dd521cSBarry Smith 
395e4dd521cSBarry Smith      /* trying to purify h */
396e4dd521cSBarry Smith      /* (did not give any visible result) */
397b05257ddSBarry Smith      /* ttmp = ts->ptime + ts->time_step;
398b05257ddSBarry Smith         ts->time_step = ttmp - ts->ptime; */
399e4dd521cSBarry Smith 
400e4dd521cSBarry Smith   }
401e4dd521cSBarry Smith 
402e4dd521cSBarry Smith   ierr=VecCopy(rk->y1,ts->vec_sol);CHKERRQ(ierr);
403e4dd521cSBarry Smith   *steps += ts->steps;
404e4dd521cSBarry Smith   *ptime  = ts->ptime;
405e4dd521cSBarry Smith   PetscFunctionReturn(0);
406e4dd521cSBarry Smith }
407e4dd521cSBarry Smith 
408e4dd521cSBarry Smith /*------------------------------------------------------------*/
409e4dd521cSBarry Smith #undef __FUNCT__
4105f70b478SJed Brown #define __FUNCT__ "TSDestroy_RK"
4115f70b478SJed Brown static PetscErrorCode TSDestroy_RK(TS ts)
412e4dd521cSBarry Smith {
4135f70b478SJed Brown   TS_RK          *rk = (TS_RK*)ts->data;
4146849ba73SBarry Smith   PetscErrorCode ierr;
415a7cc72afSBarry Smith   PetscInt       i;
416e4dd521cSBarry Smith 
417e4dd521cSBarry Smith   /* REMEMBER TO DESTROY ALL */
418e4dd521cSBarry Smith 
419e4dd521cSBarry Smith   PetscFunctionBegin;
420e4dd521cSBarry Smith   if (rk->y1) {ierr = VecDestroy(rk->y1);CHKERRQ(ierr);}
421e4dd521cSBarry Smith   if (rk->y2) {ierr = VecDestroy(rk->y2);CHKERRQ(ierr);}
422e4dd521cSBarry Smith   if (rk->tmp) {ierr = VecDestroy(rk->tmp);CHKERRQ(ierr);}
423e4dd521cSBarry Smith   if (rk->tmp_y) {ierr = VecDestroy(rk->tmp_y);CHKERRQ(ierr);}
424e4dd521cSBarry Smith   for(i=0;i<rk->s;i++){
425e4dd521cSBarry Smith      if (rk->k[i]) {ierr = VecDestroy(rk->k[i]);CHKERRQ(ierr);}
426e4dd521cSBarry Smith   }
427e4dd521cSBarry Smith   ierr = PetscFree(rk);CHKERRQ(ierr);
428e4dd521cSBarry Smith   PetscFunctionReturn(0);
429e4dd521cSBarry Smith }
430e4dd521cSBarry Smith /*------------------------------------------------------------*/
431e4dd521cSBarry Smith 
432e4dd521cSBarry Smith #undef __FUNCT__
4335f70b478SJed Brown #define __FUNCT__ "TSSetFromOptions_RK"
4345f70b478SJed Brown static PetscErrorCode TSSetFromOptions_RK(TS ts)
435e4dd521cSBarry Smith {
4365f70b478SJed Brown   TS_RK          *rk = (TS_RK*)ts->data;
437dfbe8321SBarry Smith   PetscErrorCode ierr;
438262ff7bbSBarry Smith 
439e4dd521cSBarry Smith   PetscFunctionBegin;
440262ff7bbSBarry Smith   ierr = PetscOptionsHead("RK ODE solver options");CHKERRQ(ierr);
441262ff7bbSBarry Smith     ierr = PetscOptionsReal("-ts_rk_tol","Tolerance for convergence","TSRKSetTolerance",rk->tolerance,&rk->tolerance,PETSC_NULL);CHKERRQ(ierr);
442262ff7bbSBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
443e4dd521cSBarry Smith   PetscFunctionReturn(0);
444e4dd521cSBarry Smith }
445e4dd521cSBarry Smith 
446e4dd521cSBarry Smith #undef __FUNCT__
4475f70b478SJed Brown #define __FUNCT__ "TSView_RK"
4485f70b478SJed Brown static PetscErrorCode TSView_RK(TS ts,PetscViewer viewer)
449e4dd521cSBarry Smith {
4505f70b478SJed Brown    TS_RK          *rk = (TS_RK*)ts->data;
451dfbe8321SBarry Smith    PetscErrorCode ierr;
4522cdf8120Sasbjorn 
453e4dd521cSBarry Smith    PetscFunctionBegin;
45477431f27SBarry Smith    ierr = PetscPrintf(PETSC_COMM_WORLD,"  number of ok steps: %D\n",rk->nok);CHKERRQ(ierr);
45577431f27SBarry Smith    ierr = PetscPrintf(PETSC_COMM_WORLD,"  number of rejected steps: %D\n",rk->nnok);CHKERRQ(ierr);
456e4dd521cSBarry Smith    PetscFunctionReturn(0);
457e4dd521cSBarry Smith }
458e4dd521cSBarry Smith 
459e4dd521cSBarry Smith /* ------------------------------------------------------------ */
460ebe3b25bSBarry Smith /*MC
46196f5712cSJed Brown       TSRK - ODE solver using the explicit Runge-Kutta methods
462ebe3b25bSBarry Smith 
463ebe3b25bSBarry Smith    Options Database:
464ebe3b25bSBarry Smith .  -ts_rk_tol <tol> Tolerance for convergence
465ebe3b25bSBarry Smith 
466ebe3b25bSBarry Smith   Contributed by: Asbjorn Hoiland Aarrestad, asbjorn@aarrestad.com, http://asbjorn.aarrestad.com/
467ebe3b25bSBarry Smith 
468d41222bbSBarry Smith   Level: beginner
469d41222bbSBarry Smith 
4709596e0b4SJed Brown .seealso:  TSCreate(), TS, TSSetType(), TSEULER, TSRKSetTolerance()
471ebe3b25bSBarry Smith 
472ebe3b25bSBarry Smith M*/
473ebe3b25bSBarry Smith 
474e4dd521cSBarry Smith EXTERN_C_BEGIN
475e4dd521cSBarry Smith #undef __FUNCT__
4765f70b478SJed Brown #define __FUNCT__ "TSCreate_RK"
4775f70b478SJed Brown PetscErrorCode PETSCTS_DLLEXPORT TSCreate_RK(TS ts)
478e4dd521cSBarry Smith {
4795f70b478SJed Brown   TS_RK          *rk;
480dfbe8321SBarry Smith   PetscErrorCode ierr;
481e4dd521cSBarry Smith 
482e4dd521cSBarry Smith   PetscFunctionBegin;
4835f70b478SJed Brown   ts->ops->setup           = TSSetUp_RK;
4845f70b478SJed Brown   ts->ops->step            = TSStep_RK;
4855f70b478SJed Brown   ts->ops->destroy         = TSDestroy_RK;
4865f70b478SJed Brown   ts->ops->setfromoptions  = TSSetFromOptions_RK;
4875f70b478SJed Brown   ts->ops->view            = TSView_RK;
488e4dd521cSBarry Smith 
4895f70b478SJed Brown   ierr = PetscNewLog(ts,TS_RK,&rk);CHKERRQ(ierr);
490e4dd521cSBarry Smith   ts->data = (void*)rk;
491e4dd521cSBarry Smith 
492a7cc72afSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRKSetTolerance_C","TSRKSetTolerance_RK",TSRKSetTolerance_RK);CHKERRQ(ierr);
493262ff7bbSBarry Smith 
494e4dd521cSBarry Smith   PetscFunctionReturn(0);
495e4dd521cSBarry Smith }
496e4dd521cSBarry Smith EXTERN_C_END
497e4dd521cSBarry Smith 
498e4dd521cSBarry Smith 
499e4dd521cSBarry Smith 
500e4dd521cSBarry Smith 
501