126edb414Sasbjorn /*$Id: rk.c,v 0.1 2003/06/03 Asbjorn Hoiland Aarrestad$*/ 2e4dd521cSBarry Smith /* 326edb414Sasbjorn * Code for Timestepping with Runge Kutta 426edb414Sasbjorn * 526edb414Sasbjorn * Written by 626edb414Sasbjorn * Asbjorn Hoiland Aarrestad 726edb414Sasbjorn * asbjorn@aarrestad.com 826edb414Sasbjorn * http://asbjorn.aarrestad.com/ 926edb414Sasbjorn * 10e4dd521cSBarry Smith */ 11e4dd521cSBarry Smith #include "src/ts/tsimpl.h" /*I "petscts.h" I*/ 122cdf8120Sasbjorn #include "time.h" 13e4dd521cSBarry Smith 14e4dd521cSBarry Smith typedef struct { 15e4dd521cSBarry Smith Vec y1,y2; /* work wectors for the two rk permuations */ 16e4dd521cSBarry Smith int nok,nnok; /* counters for ok and not ok steps */ 17e4dd521cSBarry Smith PetscReal maxerror; /* variable to tell the maxerror allowed */ 18e4dd521cSBarry Smith PetscReal ferror; /* variable to tell (global maxerror)/(total time) */ 19262ff7bbSBarry Smith PetscReal tolerance; /* initial value set for maxerror by user */ 20e4dd521cSBarry Smith Vec tmp,tmp_y,*k; /* two temp vectors and the k vectors for rk */ 21e4dd521cSBarry Smith PetscScalar a[7][6]; /* rk scalars */ 22e4dd521cSBarry Smith PetscScalar b1[7],b2[7]; /* rk scalars */ 23e4dd521cSBarry Smith PetscReal c[7]; /* rk scalars */ 24e4dd521cSBarry Smith int p,s; /* variables to tell the size of the runge-kutta solver */ 252cdf8120Sasbjorn clock_t start,end; /* variables to mesure cpu time */ 26e4dd521cSBarry Smith } TS_Rk; 27e4dd521cSBarry Smith 28262ff7bbSBarry Smith EXTERN_C_BEGIN 29262ff7bbSBarry Smith #undef __FUNCT__ 30262ff7bbSBarry Smith #define __FUNCT__ "TSRKSetTolerance_RK" 31262ff7bbSBarry Smith int 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 @*/ 60262ff7bbSBarry Smith int TSRKSetTolerance(TS ts,PetscReal aabs) 61262ff7bbSBarry Smith { 62262ff7bbSBarry Smith int 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" 75e4dd521cSBarry Smith static int TSSetUp_Rk(TS ts) 76e4dd521cSBarry Smith { 77e4dd521cSBarry Smith TS_Rk *rk = (TS_Rk*)ts->data; 7835b76a18SSatish Balay int 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" 248db046809SBarry Smith int TSRkqs(TS ts,PetscReal t,PetscReal h) 249db046809SBarry Smith { 250db046809SBarry Smith TS_Rk *rk = (TS_Rk*)ts->data; 251db046809SBarry Smith int ierr,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" 318e4dd521cSBarry Smith static int 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" 414e4dd521cSBarry Smith static int TSDestroy_Rk(TS ts) 415e4dd521cSBarry Smith { 416e4dd521cSBarry Smith TS_Rk *rk = (TS_Rk*)ts->data; 417e4dd521cSBarry Smith int i,ierr; 418e4dd521cSBarry Smith 419e4dd521cSBarry Smith /* REMEMBER TO DESTROY ALL */ 420e4dd521cSBarry Smith 421e4dd521cSBarry Smith PetscFunctionBegin; 422e4dd521cSBarry Smith if (rk->y1) {ierr = VecDestroy(rk->y1);CHKERRQ(ierr);} 423e4dd521cSBarry Smith if (rk->y2) {ierr = VecDestroy(rk->y2);CHKERRQ(ierr);} 424e4dd521cSBarry Smith if (rk->tmp) {ierr = VecDestroy(rk->tmp);CHKERRQ(ierr);} 425e4dd521cSBarry Smith if (rk->tmp_y) {ierr = VecDestroy(rk->tmp_y);CHKERRQ(ierr);} 426e4dd521cSBarry Smith for(i=0;i<rk->s;i++){ 427e4dd521cSBarry Smith if (rk->k[i]) {ierr = VecDestroy(rk->k[i]);CHKERRQ(ierr);} 428e4dd521cSBarry Smith } 429e4dd521cSBarry Smith ierr = PetscFree(rk);CHKERRQ(ierr); 430e4dd521cSBarry Smith PetscFunctionReturn(0); 431e4dd521cSBarry Smith } 432e4dd521cSBarry Smith /*------------------------------------------------------------*/ 433e4dd521cSBarry Smith 434e4dd521cSBarry Smith #undef __FUNCT__ 435e4dd521cSBarry Smith #define __FUNCT__ "TSSetFromOptions_Rk" 436e4dd521cSBarry Smith static int TSSetFromOptions_Rk(TS ts) 437e4dd521cSBarry Smith { 438262ff7bbSBarry Smith TS_Rk *rk = (TS_Rk*)ts->data; 439262ff7bbSBarry Smith int ierr; 440262ff7bbSBarry Smith 441e4dd521cSBarry Smith PetscFunctionBegin; 442262ff7bbSBarry Smith ierr = PetscOptionsHead("RK ODE solver options");CHKERRQ(ierr); 443262ff7bbSBarry Smith ierr = PetscOptionsReal("-ts_rk_tol","Tolerance for convergence","TSRKSetTolerance",rk->tolerance,&rk->tolerance,PETSC_NULL);CHKERRQ(ierr); 444262ff7bbSBarry Smith ierr = PetscOptionsTail();CHKERRQ(ierr); 445e4dd521cSBarry Smith PetscFunctionReturn(0); 446e4dd521cSBarry Smith } 447e4dd521cSBarry Smith 448e4dd521cSBarry Smith #undef __FUNCT__ 449e4dd521cSBarry Smith #define __FUNCT__ "TSView_Rk" 450e4dd521cSBarry Smith static int TSView_Rk(TS ts,PetscViewer viewer) 451e4dd521cSBarry Smith { 452e4dd521cSBarry Smith TS_Rk *rk = (TS_Rk*)ts->data; 453e4dd521cSBarry Smith int ierr; 454b0dd9724SMatthew Knepley /*double elapsed;*/ 4552cdf8120Sasbjorn 456e4dd521cSBarry Smith PetscFunctionBegin; 457e4dd521cSBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD," number of ok steps: %d\n",rk->nok);CHKERRQ(ierr); 4582cdf8120Sasbjorn ierr = PetscPrintf(PETSC_COMM_WORLD," number of rejected steps: %d\n",rk->nnok);CHKERRQ(ierr); 4592cdf8120Sasbjorn /* elapsed = ((double) (rk->end - rk->start)) / CLOCKS_PER_SEC; 4602cdf8120Sasbjorn 4612cdf8120Sasbjorn ierr = PetscPrintf(PETSC_COMM_WORLD," CPU time used (in seconds): %f\n",elapsed);CHKERRQ(ierr); */ 462e4dd521cSBarry Smith PetscFunctionReturn(0); 463e4dd521cSBarry Smith } 464e4dd521cSBarry Smith 465e4dd521cSBarry Smith /* ------------------------------------------------------------ */ 466ebe3b25bSBarry Smith /*MC 467ebe3b25bSBarry Smith TS_RK - ODE solver using the explicit Runge-Kutta methods 468ebe3b25bSBarry Smith 469ebe3b25bSBarry Smith Options Database: 470ebe3b25bSBarry Smith . -ts_rk_tol <tol> Tolerance for convergence 471ebe3b25bSBarry Smith 472ebe3b25bSBarry Smith Contributed by: Asbjorn Hoiland Aarrestad, asbjorn@aarrestad.com, http://asbjorn.aarrestad.com/ 473ebe3b25bSBarry Smith 474*d41222bbSBarry Smith Level: beginner 475*d41222bbSBarry Smith 476ebe3b25bSBarry Smith .seealso: TSCreate(), TS, TSSetType(), TS_EULER, TSRKSetTolerance() 477ebe3b25bSBarry Smith 478ebe3b25bSBarry Smith M*/ 479ebe3b25bSBarry Smith 480e4dd521cSBarry Smith EXTERN_C_BEGIN 481e4dd521cSBarry Smith #undef __FUNCT__ 482e4dd521cSBarry Smith #define __FUNCT__ "TSCreate_Rk" 483e4dd521cSBarry Smith int TSCreate_Rk(TS ts) 484e4dd521cSBarry Smith { 485e4dd521cSBarry Smith TS_Rk *rk; 486e4dd521cSBarry Smith int ierr; 487e4dd521cSBarry Smith 488e4dd521cSBarry Smith PetscFunctionBegin; 489e4dd521cSBarry Smith ts->ops->setup = TSSetUp_Rk; 490e4dd521cSBarry Smith ts->ops->step = TSStep_Rk; 491e4dd521cSBarry Smith ts->ops->destroy = TSDestroy_Rk; 492e4dd521cSBarry Smith ts->ops->setfromoptions = TSSetFromOptions_Rk; 493e4dd521cSBarry Smith ts->ops->view = TSView_Rk; 494e4dd521cSBarry Smith 495e4dd521cSBarry Smith ierr = PetscNew(TS_Rk,&rk);CHKERRQ(ierr); 496e4dd521cSBarry Smith PetscLogObjectMemory(ts,sizeof(TS_Rk)); 497e4dd521cSBarry Smith ts->data = (void*)rk; 498e4dd521cSBarry Smith 499262ff7bbSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRKSetTolerance_C","TSRKSetTolerance_RK", 500262ff7bbSBarry Smith TSRKSetTolerance_RK);CHKERRQ(ierr); 501262ff7bbSBarry Smith 502e4dd521cSBarry Smith PetscFunctionReturn(0); 503e4dd521cSBarry Smith } 504e4dd521cSBarry Smith EXTERN_C_END 505e4dd521cSBarry Smith 506e4dd521cSBarry Smith 507e4dd521cSBarry Smith 508e4dd521cSBarry Smith 509