Example #1
0
double RK4_adaptive_step(               // returns adapted time step
    Matrix<double,1>& x,                // solution vector
    double dt,                          // initial time step
    Matrix<double,1> flow(Matrix<double,1>&),  // derivative vector
    double accuracy)                    // desired accuracy
{
    // from Numerical Recipes
    const double SAFETY = 0.9, PGROW = -0.2, PSHRINK = -0.25,
                 ERRCON = 1.89E-4, TINY = 1.0E-30;
    int n = x.size();
    Matrix<double,1> scale = flow(x), x_half(n), Delta(n);
    for (int i = 0; i < n; i++)
        scale[i] = abs(x[i]) + abs(scale[i] * dt) + TINY;
    double error = 0;
    while (true) {
        dt /= 2;
        x_half = x;
        RK4_step(x_half, dt, flow);
        RK4_step(x_half, dt, flow);
        dt *= 2;
        Matrix<double,1> x_full = x;
        RK4_step(x_full, dt, flow);
        for (int i = 0; i < n; i++)
            Delta[i] = x_half[i] - x_full[i];
        error = 0;
        for (int i = 0; i < n; i++)
            error = max(abs(Delta[i] / scale[i]), error);
        error /= accuracy;
        if (error <= 1)
            break;
        double dt_temp = SAFETY * dt * pow(error, PSHRINK);
        if (dt >= 0)
            dt = max(dt_temp, 0.1 * dt);
        else
            dt = min(dt_temp, 0.1 * dt);
        if (abs(dt) == 0.0) {
            cerr << " step size underflow" << endl;
            exit(1);
        }
    }
    if (error > ERRCON)
        dt *= SAFETY * pow(error, PGROW);
    else
        dt *= 5.0;
    for (int i = 0; i < n; i++)
        x[i] = x_half[i] + Delta[i] / 15.0;
    return dt;
}
Example #2
0
int main(){
  double x_RK4, x_LF;
  double v_RK4, v_LF;
  double t;

  double T=1E5;
  double delta_t=1E-1;
  int n_step = (int)(T/delta_t);
  double x_step = 0.0;
  double v_step = 0.0;
  int i;

  t=0.0;
  x_RK4=1.0;
  v_RK4=0.0;
  x_LF=1.0;
  v_LF=0.0;
  
  for(i=0;i<n_step;i++){    
    printf("%f %.15e %.15e %.15e %.15e \n", t, x_RK4, v_RK4, x_LF, v_LF);
    RK4_step(delta_t, t, &x_RK4, &v_RK4);
    leapfrog_step(delta_t, t, &x_LF, &v_LF);
    t += delta_t;
  }

  return 0;
}
Example #3
0
File: rk4.c Project: mkmcc/flines
/* RK4 step with adaptive step size.  Adjusts the step size to reach
   an approximate error equal to `tolerance'. */
void RK4_qc_step(Real3Vect *xn, Real3Vect *xnp1,
                 double h_try, double *h_did, double *h_next,
                 double tolerance, int dir)
{
  double h, err;
  Real3Vect x_coarse;
  int i;

  h = h_try;
  i = 0;
  while (1==1){
    /* take two half-steps.  save in xnp1; use x_coarse as a scratch buffer */
    RK4_step(xn,        &x_coarse, 0.5*h, dir);
    RK4_step(&x_coarse, xnp1,      0.5*h, dir);

    /* take a full step.  save in x_coarse */
    RK4_step(xn, &x_coarse, h, dir);

    /* estimate the error */
    err = dist(&x_coarse, xnp1) / tolerance;
    err = MAX(fabs(err), TINY_NUMBER);

    /* if the error is small enough, increase the next time-step and exit... */
    if (err <= 1.0) {
      *h_did = h;
      *h_next = 0.9*exp(-0.20*log(err)) * h; /* err ~ h^5 */
      *h_next = MIN(*h_next, 4.0*h); /* limit growth to a factor of 4 */

      break;
    } else if (i > 15) {
      *h_did = h;
      *h_next = h_try;
      printf("hit %d iterations, h hit %f.  giving up.\n", i, h);

      break;
    }

    i+=1;

    /* ...otherwise, shrink time step and try again. */
    h = 0.9 * exp(-0.25*log(err)) * h; /* err ~ h^4 */
  }

  return;
}
Example #4
0
void Physics::RK4(real_t dt) {
    //reset states and derivatives
    for (size_t i = 0; i < num_spheres(); i++) {
        spheres[i]->state.dx = Vector3::Zero();
        spheres[i]->state.dv = Vector3::Zero();
        spheres[i]->state.dax = Vector3::Zero();
        spheres[i]->state.dav = Vector3::Zero();
    }

    RK4_step(dt, 0.5, 1.0/6.0);
    RK4_step(dt, 0.5, 1.0/3.0);
    RK4_step(dt, 1.0, 1.0/3.0);
    RK4_step(dt, 0.0, 1.0/6.0); //dummy value


    for (size_t i = 0; i < num_spheres(); i++) { 
        spheres[i]->position = 
            spheres[i]->initial_position + (spheres[i]->state.dx);
        spheres[i]->velocity = 
            spheres[i]->initial_velocity + (spheres[i]->state.dv);
        
        Vector3 dax = spheres[i]->state.dax;

        real_t x_radians = dax.x; //rotation around x axis
        real_t y_radians = dax.y; //rotation around y axis
        real_t z_radians = dax.z; //rotation around z axis

        Quaternion qx = Quaternion(Vector3::UnitX(), x_radians);
        Quaternion qy = Quaternion(Vector3::UnitY(), y_radians);
        Quaternion qz = Quaternion(Vector3::UnitZ(), z_radians);

        spheres[i]->orientation = 
            normalize(spheres[i]->initial_orientation * qz); //roll
        spheres[i]->orientation = 
            normalize(spheres[i]->orientation * qx); //pitch
        spheres[i]->orientation = 
            normalize(spheres[i]->orientation * qy); //yaw
        
        spheres[i]->angular_velocity = 
            spheres[i]->initial_angular_velocity + 
            (spheres[i]->state.dav);
    }

    }
Example #5
0
int main(){
  double x_RK4, x_LF, x3_RK4,x3_LF;
  double v_RK4, v_LF, v3_RK4,v3_LF;
  double t;
  double x3_CI;
  
  double T=2800;
  double delta_t=6E-3;
  int n_step = (int)(T/delta_t);
  double x_step = 0.0, e=1;
  double v_step = 0.0;
  int i,j;

  file1 = fopen("salida3LF.dat", "w");
  file2 = fopen("salida3RK4.dat", "w"); 

 
  t=0.0;
  x_RK4=0.425;
  v_RK4=0.0;
  x3_RK4=0.0;
  v3_RK4=0.0;
  x3_LF=0.0;
  v_LF=0.0;
  x_LF=0.46;
  v3_LF=0.0;
  x3_CI=-0.2;
  for(j=0;j<100;j++){
    x3_LF=x3_CI;
    v_LF=0.0;
    x_LF=0.46;
    v3_LF=0.0;
    x3_RK4=x3_CI;
    v_RK4=0.0;
    x_RK4=0.425;
    v3_RK4=0.0;
    for(i=0;i<n_step;i++){ 
      if(fabs(v_LF)<0.0005)   
          fprintf(file1,"%f %.15e %.15e %.15e %.15e \n", t, x_LF, v_LF, x3_LF, v3_LF);
      if(fabs(v_RK4)<0.0005)   
          fprintf(file2,"%f %.15e %.15e %.15e %.15e \n", t, x_LF, v_LF, x3_RK4, v3_RK4);
      RK4_step(delta_t,e, t, &x_RK4, &v_RK4, &x3_RK4, &v3_RK4);
      leapfrog_step(delta_t,e, t, &x_LF, &v_LF,&x3_LF,&v3_LF);
      t += delta_t;
    }
    x3_CI+=0.03;
  }
  fclose(file1);
  fclose(file2);
  return 0;
}
Example #6
0
double RK4_integrate(                   // returns adapted time step
    Matrix<double,1>& x,                // solution vector
    double dt,                          // initial time step
    Matrix<double,1> flow(Matrix<double,1>&),  // derivative vector
    double Delta_t,                     // finite step in time x[0]
    double accuracy)                    // desired accuracy
{
    if (dt * Delta_t <= 0) {
        cerr << "dt * Delta_t <= 0" << endl;
        exit(1);
    }
    if (abs(dt) > abs(Delta_t))
        dt = Delta_t / 5.0;
    double t0 = x[0];
    while (abs(x[0] - t0) < abs(Delta_t))
        dt = RK4_adaptive_step(x, dt, flow, accuracy);
    RK4_step(x, t0 + Delta_t - x[0], flow);
    return dt;
}
Example #7
0
int main(void)
{
    double y_RK2;
    double y_RK4;
    double t;
    int i;

    double T=2.0;
    double step=1E-2;
    int n_step = (int)(T/step);

    t=0.0;
    y_RK2=1.0;
    y_RK4=1.0;
    for(i=0; i<n_step; i++) {
        printf("%f %.15e %.15e %.15e\n", t, exact_sol_y(t), y_RK2, y_RK4);
        y_RK2 += RK2_step(step, t, y_RK2, func_y);
        y_RK4 += RK4_step(step, t, y_RK4, func_y);
        t += step;
    }

    return 0;
}