Search code examples
c++boostodeint

Destructor calls during integration with boost odeint


If I integrate a system with boosts odeint module, using a class to define the derivative, the destructor of this class is called very often.

  1. Is this behavior intended?
  2. Why is it the case?
  3. What should I do if I want to allocate arrays dynamically in this class?

For example, this code:

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

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

class foo
{
public:
    virtual ~foo() {
        std::cout << "destructor called" << std::endl;
    }

    void operator()(const double &x, double &dxdt, double t) const    {
        dxdt = 1;
    }
};

int main( int argc , char **argv )
{
    double x = 0;
    const double dt = 0.1;
    typedef runge_kutta4< double > stepper_type;

    integrate_const( stepper_type() , foo(), x , 0.0 , 10.0 , dt);

    return 0;
}

calls the destructor around 400 times. (I'am a beginner in c++)


Solution

  • The destructor is only called once at the end of the program if

    1. there is an instantiation of foo in main and
    2. if std::ref() is used in the call to integrate_const()

    Like this:

    #include <iostream>
    #include <boost/numeric/odeint.hpp>
    #include <functional>
    
    using namespace boost::numeric::odeint;
    
    class foo
    {
    public:
        virtual ~foo() {
            std::cout << "destructor called" << std::endl;
        }
    
        void operator()(const double &x, double &dxdt, double t) const   {
            dxdt = 1;
        }
    };
    
    int main( int argc , char **argv )
    {
        double x = 0;
        const double dt = 0.1;
        typedef runge_kutta4< double > stepper_type;
        foo myfoo;
        integrate_const( stepper_type() , std::ref( myfoo ), x , 0.0 , 10.0 , dt);
        return 0;
    }
    

    You can allocate any kind of data dynamically in the foo class, for instance by adding a simple setter function .setData() that could be called from main with

    myfoo.setData(myArray);
    

    prior to the call to integrate_const().