How to use ode advancers

Suppose that you have:

template<class ScalarType>
struct BasicSteppableClass{
public:
  void operator()(std::vector<ScalarType> & state,
                  const ScalarType time,
                  const ScalarType dt,
                  const pressio::ode::step_count_type step) const
  {
    // for simplicity, let's say that taking one step
    // corresponds to adding 1 to the state
    state[0] += dt;
    state[1] += dt;
    state[2] += dt;
  };
};

template<class ScalarType>
struct SteppableClassThatNeedsSomethingElse{
public:

  template<class SomethingElse>
  void operator()(std::vector<ScalarType> & state,
                  const ScalarType time,
                  const ScalarType dt,
                  const pressio::ode::step_count_type step,
          SomethingElse & my_auxiliary_object) const
  {
    // just for demonstration, we might need auxiliary object
    // to do something, but we don't know the type in advance
    state[0] += 1;
    state[1] += 1;
    state[2] += 1;

    my_auxiliary_object.aComplicatedMethod(state);
  };
};

struct Foo
{
  template<class ScalarType>
  void aComplicatedMethod(std::vector<ScalarType> & state){
    // do something
  }
};

advance_n_times

{
  /*
    time-step is fixed
   */
  namespace pode = pressio::ode;
  using scalar_type = double;

  BasicSteppableClass<scalar_type> stepper;
  std::vector<scalar_type> state = {1,2,3};
  const scalar_type dt = 0.1;
  const scalar_type start_time = 0.0;
  const pode::step_count_type num_steps = 10;
  pode::advance_n_steps(stepper, state, start_time, dt, num_steps);
  std::cout << "Final state: ["
        << state[0] << " " << state[1] << " " << state[2] << "] "
        << std::endl;
}
{
  /*
    time-step is fixed, and stepper needs an auxiliary object
   */
  namespace pode = pressio::ode;
  using scalar_type = double;

  SteppableClassThatNeedsSomethingElse<scalar_type> stepper;
  std::vector<scalar_type> state = {1,2,3};
  const scalar_type dt = 0.1;
  const scalar_type start_time = 0.0;
  const pode::step_count_type num_steps = 10;

  Foo aux;
  pode::advance_n_steps(stepper, state, start_time, dt, num_steps, aux);
  std::cout << "Final state: ["
        << state[0] << " " << state[1] << " " << state[2] << "] "
        << std::endl;
}
{
  /*
    time-step is specified by the user with a functor
   */
  namespace pode = pressio::ode;
  using scalar_type = double;

  BasicSteppableClass<scalar_type> stepper;
  std::vector<scalar_type> state = {1,2,3};
  const scalar_type dt = 0.1;
  const scalar_type start_time = 0.0;
  const pode::step_count_type num_steps = 10;

  auto dt_setter = [](const pode::step_count_type step,
              const scalar_type & time,
              scalar_type & dt)
  {
    // step starts at 1 for the first step

    // set the time step size you want at each step, time
    dt = (scalar_type) step;
  };

  pode::advance_n_steps(stepper, state, start_time, dt_setter, num_steps);
  std::cout << "Final state: ["
        << state[0] << " " << state[1] << " " << state[2] << "] "
        << std::endl;
}

advance_n_times_and_observe

{
  /*
    time-step is fixed, user passes an observer to monitor state
   */
  namespace pode = pressio::ode;
  using scalar_type = double;

  BasicSteppableClass<scalar_type> stepper;
  std::vector<scalar_type> state = {1,2,3};
  const scalar_type dt = 0.1;
  const scalar_type start_time = 0.0;
  const pode::step_count_type num_steps = 10;

  MyObserver monitor;
  pode::advance_n_steps_and_observe(stepper, state, start_time, dt, num_steps, monitor);
}

Similarly works for the other cases accepting the time step setter, etc.

advance_to_target_time

This always needs a functor to set the time step.

{
  /*
    time-step is provided
   */
  namespace pode = pressio::ode;
  using scalar_type = double;

  BasicSteppableClass<scalar_type> stepper;
  std::vector<scalar_type> state = {1,2,3};
  const scalar_type dt = 0.1;
  const scalar_type start_time = 0.0;
  const scalar_type final_time = 2.8;
  const pode::step_count_type num_steps = 10;

  auto dt_setter = [](const pode::step_count_type step,
              const scalar_type & time,
              scalar_type & dt)
  {
    // step starts at 1 for the first step

    // set the time step size you want at each step, time
    dt = (scalar_type) step + (scalar_type) 0.5;
    std::cout << " step = " << step << " dt = " << dt << '\n';
  };

  pode::advance_to_target_time(stepper, state, start_time, final_time, dt_setter);
}

advance_to_target_time_and_observe

This is like above, but you also need to pass an obsever.