libpspm
solver.tpp
Go to the documentation of this file.
1 template<typename AfterStepFunc>
15 void Solver::step_to(double tstop, AfterStepFunc &afterStep_user){
16  // do nothing if tstop is <= current_time
17  if (tstop <= current_time) return;
18 
19  auto after_step = [this, afterStep_user](double t, std::vector<double>::iterator S){
20  std::cout << "After step: t = " << t << "\n";
22  afterStep_user(t);
23  };
24 
25 
26  if (method == SOLVER_FMU){
27  auto derivs = [this](double t, std::vector<double>::iterator S, std::vector<double>::iterator dSdt, void* params){
29  updateEnv(t, S, dSdt);
30  calcRates_FMU(t, S, dSdt);
31  };
32 
33  // integrate
34  odeStepper.step_to(tstop, current_time, state, derivs, after_step); // rk4_stepsize is only used if method is "rk4"
35  }
36 
37 
38  if (method == SOLVER_IFMU){
39  while (current_time < tstop){
40  double dt = std::min(control.ode_ifmu_stepsize, tstop-current_time);
41 
42  //copyStateToCohorts(state.begin()); // not needed here because it is called by the odestepper below
43  updateEnv(current_time, state.begin(), rates.begin());
44  std::vector<double> rates_prev(rates.begin(), rates.begin()+n_statevars_system); // save system variable rates
45 
46  // use implicit stepper to advance u
48  // current_time += dt; // not needed here, as current time is advanced by the ODE stepper below.
49 
50  if (n_statevars_system > 0){
51  copyStateToCohorts(state.begin()); // copy updated u to cohorts
52  updateEnv(current_time, state.begin(), rates.begin()); // recompute env with updated u
53  // FIXME: use fully implicit stepper here?
54  for (int i=0; i<n_statevars_system; ++i){
55  state[i] += (rates_prev[i]+rates[i])/2*dt; // use average of old and updated rates for stepping system vars
56  }
57  }
58 
59  // use the ODE-stepper for other state variables
60  // this stepper is called even if there are no extra state variables, so copyStateToCohorts is accomplished here
61  auto derivs = [this](double t, std::vector<double>::iterator S, std::vector<double>::iterator dSdt, void* params){
63  // precompute and env computation is not needed here, because it depends on x and u, which are not updated by the solver.
64  calcRates_iFMU(t,S,dSdt);
65  };
66  // this step below will do afterstep. FIXME: But what if there are no extra state variables?
67  odeStepper.step_to(current_time+dt, current_time, state, derivs, after_step); // rk4_stepsize is only used if method is "rk4"
68 
69  }
70 
71  }
72 
73  if (method == SOLVER_EBT){
74  auto derivs = [this](double t, std::vector<double>::iterator S, std::vector<double>::iterator dSdt, void* params){
76  updateEnv(t, S, dSdt);
77  calcRates_EBT(t, S, dSdt);
78  };
79 
80  // integrate
81  odeStepper.step_to(tstop, current_time, state, derivs, after_step); // rk4_stepsize is only used if method is "rk4"
82 
83  // update cohorts
85  addCohort_EBT(); // Add new cohort if N0 > 0. Add after removing dead ones otherwise this will also be removed.
86  }
87 
88 
89  if (method == SOLVER_CM){
90  auto derivs = [this](double t, std::vector<double>::iterator S, std::vector<double>::iterator dSdt, void* params){
91  std::cout << "derivs()\n";
92  copyStateToCohorts(S); // this triggers precompute
93  updateEnv(t, S, dSdt);
94  calcRates_CM(t, S, dSdt);
95  };
96 
97  // integrate
98  odeStepper.step_to(tstop, current_time, state, derivs, after_step); // rk4_stepsize is only used if method is "rk4"
99 
100  // update cohorts
101  if (control.update_cohorts){
102  addCohort_CM(); // add before so that it becomes boundary cohort and first internal cohort can be (potentially) removed
103  removeCohort_CM();
104  }
105  //env->computeEnv(current_time, this); // is required here IF rescaleEnv is used in derivs
106  }
107 }
108 
void calcRates_FMU(double t, std::vector< double >::iterator S, std::vector< double >::iterator dSdt)
Definition: fmu.cpp:11
void removeCohort_CM()
Definition: cm.cpp:85
std::vector< double > state
Definition: solver.h:28
void removeDeadCohorts_EBT()
Definition: ebt.cpp:99
void stepU_iFMU(double t, std::vector< double > &S, std::vector< double > &dSdt, double dt)
Definition: ifmu.cpp:25
double current_time
Definition: solver.h:27
int n_statevars_system
Definition: solver.h:20
void copyStateToCohorts(std::vector< double >::iterator state_begin)
Definition: solver.cpp:256
void calcRates_iFMU(double t, std::vector< double >::iterator S, std::vector< double >::iterator dSdt)
Definition: ifmu.cpp:5
std::vector< double > rates
Definition: solver.h:29
OdeSolver odeStepper
Definition: solver.h:23
PSPM_SolverType method
Definition: solver.h:17
void updateEnv(double t, std::vector< double >::iterator S, std::vector< double >::iterator dSdt)
Definition: solver.cpp:344
void calcRates_EBT(double t, std::vector< double >::iterator S, std::vector< double >::iterator dSdt)
Definition: ebt.cpp:8
void addCohort_EBT()
Definition: ebt.cpp:70
void step_to(double t_stop, double &t, std::vector< double > &y, Functor &derivs, AfterStep &after_step)
Definition: ode_solver.h:60
void step_to(double tstop, AfterStepFunc &afterStep_user)
Definition: solver.tpp:15
void calcRates_CM(double t, std::vector< double >::iterator S, std::vector< double >::iterator dSdt)
Definition: cm.cpp:9
struct Solver::@1 control
void addCohort_CM()
Definition: cm.cpp:58