headmyshoulder / odeint-v2

odeint - solving ordinary differential equations in c++ v2
http://headmyshoulder.github.com/odeint-v2/
Other
341 stars 101 forks source link

Querying system values at a particular time with dense output #82

Closed dtamayo closed 11 years ago

dtamayo commented 11 years ago

Hi,

I'm trying to use dense output to output the system values at times when one of the variables is equal to 0. I gather from trying to call calc_state that it makes numerous calls to my observer functor that does the output (the one I pass to integrate_adaptive), but I can't tell how to choose the times at which it does the interpolations. In particular, I would like to query the stepper with calc_state to give me the system values for a given time (in order to find where one of the variables equals 0). I'm not sure whether this is easy, hard, or impossible with the current implementation.

This thread seems related:

https://github.com/headmyshoulder/odeint-v2/issues/61

I was wondering whether anyone would be able to share cshelton's modified code with me. I might be able to figure out how to do this from that.

Thank you very much for all the fantastic work with odeint!

Dan

mariomulansky commented 11 years ago

Hi,

I think for your problem you should not use integrate routines, but rather go deeper and use the dense_output_stepper's do_step method to iterate along the solution. Then you can check after every step if a zero is to be expected within this step interval by checking if your variable of question changes sign. If so, you can do a bisection using calc_state to get the intermediate values to find the point of zero. You would miss situation with 2 zeros in the interval by that approach, but I think it is a good starting point.

dtamayo commented 11 years ago

Thanks for the quick response!

Your approach seems good as with my system I don't think I have to worry about variables passing through zero more than once between timesteps. Pardon the ignorant question, but when I call calc_state(t,x), is the interpolated state at time t put into x?

Also, do I take it you think it would be a bad idea to modify the stepper's try_step to do the bisection whenever a step is accepted? With my system I get a big performance boost from using adaptive time steps.

Thanks again!

Dan

mariomulansky commented 11 years ago

Yes, calc_state writes the interpolated state at time t into the variable x.

If you use a dense_output stepper, stepsize control is automatically performed when you iterate through the solution with the do_step method.

you might find the sections on dense output steppers in the odeint docs helpful: http://headmyshoulder.github.io/odeint-v2/doc/boost_numeric_odeint/odeint_in_detail/steppers.html#boost_numeric_odeint.odeint_in_detail.steppers.dense_output_steppers http://headmyshoulder.github.io/odeint-v2/doc/boost_numeric_odeint/concepts/dense_output_stepper.html

dtamayo commented 11 years ago

Thank you!