0

I would like to know whether the step size in odeint is fixed or not. In stepper

The basic stepper concept. A basic stepper following this Stepper concept is able to perform a single step of the solution x(t) of an ODE to obtain x(t+dt) using a given step size dt.

In my following code,

#include <iostream>
#include <boost/numeric/odeint.hpp>

using namespace std;
using namespace boost::numeric::odeint;

/* The type of container used to hold the state vector */
typedef std::vector< double > state_type;

const double gam = 0.15;


void sys( const state_type &x , state_type &dx ,  double t )
{
    dx[0] =  x[1];
    dx[1] = -x[0] - gam*x[1];

    static int count(0);

    cout << "count in sys: " << count << endl;

    ++count;
}

int main(int argc, char **argv)
{
    const double dt = 0.1;

    runge_kutta_dopri5<state_type> stepper;
    state_type x(2);
    // initial values
    x[0] = 1.0;
    x[1] = 0.0;



   int count(0);
   double t = 0.0;

   for ( size_t i(0); i < 100; ++i, t+=dt ){

       stepper.do_step(sys , x , t, dt );
       cout << "count in main: " << count << endl;
       ++count;
   }

    return 0;
}

In the above code, I have two counters, one inside the sys function which is passed to do_step for solving the ode and another counter inside the main function. The output is shown as follows

count in sys: 598 
count in sys: 599 
count in sys: 600 
count in main: 99 
Press any key to continue . . .

Does this mean that the step size is not fixed because the sys is being called more than the once in the main?

CroCo
  • 5,531
  • 9
  • 56
  • 88

1 Answers1

2

The step size is fixed for your stepper. For each step is calls the system function 6 times. In detail, it performs 6 Euler steps each with a different step sizes and does some kind of averaging to increase the accuracy of the solution.

headmyshoulder
  • 6,240
  • 2
  • 20
  • 27
  • inside `sys` function, I would like to read data from `txt`. Is there any safe approach to retrieve data with each step size inside `sys`? So far, I'm using global variables for this problem. – CroCo May 18 '15 at 05:59
  • You can pass a class with an approriate `operator()` and with all informations you need to open and read the txt file. But be aware, that sys is called several times during each step and that the time is not simply `t` for each intermediate step. Maybe you need to interpolate the data from the txt, just to get the time correct. Otherwise you could also use the adams bashforth moulton stepper. It calls the sys function exactly once during each step. – headmyshoulder May 18 '15 at 07:22
  • When I use `adams_bashforth_moulton<1,state_type> stepper;`, the `sys` is called twice. any suggestions how to force it to be called exactly once? – CroCo May 18 '15 at 07:40
  • In the very first iterations it is called several times because it needs to create a buffer with the history of the ode. But after a few steps it should only call sys once each step. Could you check this? – headmyshoulder May 18 '15 at 08:43
  • Could you please elaborate about how can I check that? – CroCo May 19 '15 at 01:46
  • I think using `%` might solve the problem in my case. I've used `tempCount%6 == 0` to control how many times the counter should increase and it seems that it did the trick. The result is `count in sys: 99 count in main: 99` – CroCo May 19 '15 at 02:54
  • Ahh, do you want to iterate exactly N times? Then you can use integrate_n_steps. – headmyshoulder May 19 '15 at 07:51
  • I have ode of second order. I've used Euler method but it is not that accurate, therefore I thought why not to use other methods. – CroCo May 19 '15 at 07:55