I have been trying for several days to attempt to have ODEINT's integrate_adaptive() function compile within a class. If I take the function outside of a class and have generic function names, then the program compiles and works as required. (out is just the output to a file and was previously defined)
void waterbodies::writeInfo(){
bulirsch_stoer_dense_out< state_type > stepper( 1E-9 , 1E-9 , 1.0 , 0.0 );
state_type x1 = { 0.0024 , 0.00001 , 0.0008,0.6,100,5,5,4,4,4,4,20000,0,10,10,100 }; // initial conditions
out.open( Name.c_str() );
out.precision(16);
double t = 0.0;
double max = 100;
double dt = 0.01;
boost::numeric::odeint::integrate_adaptive(
rhs,
x1 , t , max , dt, write_rhs);
out.close();
}
I have a function called rhs, and another called write_rhs
void waterbodies::write_rhs( const state_type &x , const double t )
{
out << t << '\t' << x[0] << '\t' << x[1] << '\t' << x[2] << '\t' << x[3] << '\t' << x[4] << '\t' << x[5] << '\t' << x[6] << '\t' << x[7] << '\t' << x[8] << '\t' << x[9] << '\t' << x[10] << '\t' << x[11] << '\t' << x[12] << '\t' << x[13] << '\t' << x[14] << '\t' << x[15] << std::endl;
}
void waterbodies::rhs( const state_type &x , state_type &dxdt , const double t )
{}
state_type is defined in header as follows
typedef boost::array< double , 16 > state_type;
The error output was:
..\src\waterbodies.cpp: In member function 'void waterbodies::writeInfo()':
..\src\waterbodies.cpp:84:32: error: no matching function for call to 'integrate_adaptive(<unresolved overloaded function type>, waterbodies::state_type&, double&, double&, double&, <unresolved overloaded function type>)'
x1 , t , max , dt, write_rhs);
^
..\src\waterbodies.cpp:84:32: note: candidates are:
In file included from C:\software\boost_1_59_0/boost/numeric/odeint/integrate/integrate.hpp:26:0,
from C:\software\boost_1_59_0/boost/numeric/odeint.hpp:67,
from ..\src\waterbodies.cpp:4:
C:\software\boost_1_59_0/boost/numeric/odeint/integrate/integrate_adaptive.hpp:36:8: note: template<class Stepper, class System, class State, class Time, class Observer> size_t boost::numeric::odeint::integrate_adaptive(Stepper, System, State&, Time, Time, Time, Observer)
size_t integrate_adaptive(
^
C:\software\boost_1_59_0/boost/numeric/odeint/integrate/integrate_adaptive.hpp:36:8: note: template argument deduction/substitution failed:
..\src\waterbodies.cpp:84:32: note: could not resolve address from overloaded function '((waterbodies*)this)->waterbodies::write_rhs'
x1 , t , max , dt, write_rhs);
^
In file included from C:\software\boost_1_59_0/boost/numeric/odeint/integrate/integrate.hpp:26:0,
from C:\software\boost_1_59_0/boost/numeric/odeint.hpp:67,
from ..\src\waterbodies.cpp:4:
C:\software\boost_1_59_0/boost/numeric/odeint/integrate/integrate_adaptive.hpp:60:8: note: template<class Stepper, class System, class State, class Time, class Observer> size_t boost::numeric::odeint::integrate_adaptive(Stepper, System, const State&, Time, Time, Time, Observer)
size_t integrate_adaptive(
^
C:\software\boost_1_59_0/boost/numeric/odeint/integrate/integrate_adaptive.hpp:60:8: note: template argument deduction/substitution failed:
..\src\waterbodies.cpp:84:32: note: could not resolve address from overloaded function '((waterbodies*)this)->waterbodies::write_rhs'
x1 , t , max , dt, write_rhs);
^
In file included from C:\software\boost_1_59_0/boost/numeric/odeint/integrate/integrate.hpp:26:0,
from C:\software\boost_1_59_0/boost/numeric/odeint.hpp:67,
from ..\src\waterbodies.cpp:4:
C:\software\boost_1_59_0/boost/numeric/odeint/integrate/integrate_adaptive.hpp:79:8: note: template<class Stepper, class System, class State, class Time> size_t boost::numeric::odeint::integrate_adaptive(Stepper, System, State&, Time, Time, Time)
size_t integrate_adaptive(
^
C:\software\boost_1_59_0/boost/numeric/odeint/integrate/integrate_adaptive.hpp:79:8: note: template argument deduction/substitution failed:
..\src\waterbodies.cpp:84:32: note: could not resolve address from overloaded function '((waterbodies*)this)->waterbodies::write_rhs'
x1 , t , max , dt, write_rhs);
^
In file included from C:\software\boost_1_59_0/boost/numeric/odeint/integrate/integrate.hpp:26:0,
from C:\software\boost_1_59_0/boost/numeric/odeint.hpp:67,
from ..\src\waterbodies.cpp:4:
C:\software\boost_1_59_0/boost/numeric/odeint/integrate/integrate_adaptive.hpp:91:8: note: template<class Stepper, class System, class State, class Time> size_t boost::numeric::odeint::integrate_adaptive(Stepper, System, const State&, Time, Time, Time)
size_t integrate_adaptive(
^
C:\software\boost_1_59_0/boost/numeric/odeint/integrate/integrate_adaptive.hpp:91:8: note: template argument deduction/substitution failed:
..\src\waterbodies.cpp:84:32: note: could not resolve address from overloaded function '((waterbodies*)this)->waterbodies::write_rhs'
x1 , t , max , dt, write_rhs);
If you need me to explain something, just let me know, and I will try to make what I am saying clearer.
Thanks
Simon
This question has already been answered several times:
Using boost::numeric::odeint inside the class
You need to bind the rhs
and write_rhs
to the current class:
// not tested
// the code also requires a C++14 compiler
auto rhs_wrapper = [this]( auto const& x , auto& dxdt , auto t ) {
this->rhs( x , dxdt , t ); };
auto obs = [this]( auto const& x , auto t ) {
this->write_rhs( x , t );
integrate_adaptive( stepper , rhs_wrapper , x , max , dt , obs );