libpspm
ode_solver.h
Go to the documentation of this file.
1 #ifndef PSPM_ODE_SOLVER_H_
2 #define PSPM_ODE_SOLVER_H_
3 
4 #include "rkck45.h"
5 #include "lsoda.h"
6 
7 #include <string>
8 #include <vector>
9 #include <iostream>
10 #include <exception>
11 
13 
14 class OdeSolver{
15  private:
17  void * solver = nullptr;
18  int nfe_cumm = 0;
19 
20  public:
21  struct{
22  double abs_tol = 1e-8;
23  double rel_tol = 1e-8;
24  } control;
25 
26  public:
27  OdeSolver(std::string method, double t_start, double rtol, double atol){
28  if (method == "rk45ck") type = ODE_RKCK45;
29  else if (method == "lsoda") type = ODE_LSODA;
30  else {
31  throw std::runtime_error("Fatal: Unknown ODE method " + method); //exit(1);
32  }
33  reset(t_start, rtol, atol);
34  }
35 
37  if (type == ODE_RKCK45) delete static_cast<RKCK45*>(solver);
38  else if (type == ODE_LSODA) delete static_cast<LSODA*>(solver);
39  }
40 
41 
42  void reset(double t_start, double rtol, double atol){
43  nfe_cumm = 0;
44  control.abs_tol = atol;
45  control.rel_tol = rtol;
46  if (type == ODE_RKCK45){
47  RKCK45* sol = static_cast<RKCK45*>(solver);
48  delete sol; sol = nullptr;
49  solver = new RKCK45(t_start, rtol, 1e-8);
50  }
51  else if (type == ODE_LSODA){
52  LSODA* sol = static_cast<LSODA*>(solver);
53  delete sol; sol = nullptr;
54  solver = new LSODA();
55  }
56  }
57 
58 
59  template <class Functor, class AfterStep>
60  void step_to(double t_stop, double &t, std::vector<double>&y, Functor &derivs, AfterStep &after_step){
61  if (t_stop == t || y.size() == 0) return;
62 
63  if (type == ODE_RKCK45){
64  RKCK45 * sol = static_cast<RKCK45*>(solver);
65  sol->Step_to(t_stop, t, y, derivs, after_step);
66  }
67  else if (type == ODE_LSODA ){
68  LSODA* sol = static_cast<LSODA*>(solver);
69  sol->set_istate(1); // forces re-initialization
70  sol->lsoda_update(derivs, after_step, y.size(), y, &t, t_stop, nullptr, control.rel_tol, control.abs_tol);
71  if(sol->get_istate() <= 0) {
72  std::cerr << "LSODA Error: istate = " << sol->get_istate() << std::endl;
73  return;
74  }
75  nfe_cumm += sol->get_fncalls();
76  }
77 
78  //else if (type == ODE_LSODA ){
81  //LSODA * sol = new LSODA();
82  //sol->lsoda_update(derivs, y.size(), y, &t, t_stop, nullptr, control.rel_tol, control.abs_tol);
83  //if(sol->get_istate() <= 0) {
84  //std::cerr << "LSODA Error: istate = " << sol->get_istate() << std::endl;
85  //return;
86  //}
87  //nfe_cumm += sol->get_fncalls();
88  //delete sol;
89  //}
90  }
91 
92  int get_fn_evals(){
93  if (type == ODE_RKCK45) return static_cast<RKCK45*>(solver)->get_fn_evals();
94  else if (type == ODE_LSODA) return nfe_cumm;
95  else return -1;
96  }
97 
98 };
99 
100 
101 
102 #endif
103 
int get_fn_evals()
Definition: ode_solver.h:92
~OdeSolver()
Definition: ode_solver.h:36
SolverType
Definition: ode_solver.h:12
void reset(double t_start, double rtol, double atol)
Definition: ode_solver.h:42
int get_fncalls()
Definition: lsoda.cpp:848
void lsoda_update(Functor &derivs, AfterStep &after_step, const size_t neq, std::vector< double > &y, double *t, const double tout, void *const _data, double rtol=1e-6, double atol=1e-6)
Definition: lsoda.tpp:1257
struct OdeSolver::@0 control
void Step_to(double t_stop, double &x, container &y, functor &derivs, AfterStep &after_step)
Definition: rkck45.tpp:149
double abs_tol
Definition: ode_solver.h:22
SolverType type
Definition: ode_solver.h:16
void * solver
Definition: ode_solver.h:17
Definition: rkck45.h:47
Definition: lsoda.h:38
int nfe_cumm
Definition: ode_solver.h:18
OdeSolver(std::string method, double t_start, double rtol, double atol)
Definition: ode_solver.h:27
void step_to(double t_stop, double &t, std::vector< double > &y, Functor &derivs, AfterStep &after_step)
Definition: ode_solver.h:60
double rel_tol
Definition: ode_solver.h:23
void set_istate(int n)
Definition: lsoda.cpp:857
int get_istate() const
Definition: lsoda.cpp:853