15 inline std::vector <double>
seq(
double from,
double to,
int len){
16 std::vector<double> x(len);
17 for (
size_t i=0; i<len; ++i) x[i] = from + i*(to-from)/(len-1);
21 inline std::vector <double>
logseq(
double from,
double to,
int len){
22 std::vector<double> x(len);
23 for (
size_t i=0; i<len; ++i) x[i] = exp(log(from) + i*(log(to)-log(from))/(len-1));
27 inline std::vector <double>
diff(vector <double> breaks){
28 std::vector<double> mids(breaks.size()-1);
29 for (
size_t i=0; i<mids.size(); ++i) mids[i] = (breaks[i]+breaks[i+1])/2;
47 std::sort(xbreaks.begin(), xbreaks.end(), std::less<double>());
48 s->
xb = *xbreaks.begin();
51 std::sort(xbreaks.begin(), xbreaks.end(), std::greater<double>());
52 s->
xb = *xbreaks.rbegin();
61 else throw std::runtime_error(
"Unsupported method");
80 for (
size_t i=0; i<s->
J; ++i) s->
X[i] = (s->
x[i]+s->
x[i+1])/2.0;
83 for (
size_t i=0; i<s->
J; ++i) s->
h[i] = s->
x[i+1] - s->
x[i];
90 if (
control.ifmu_centered_grids){
91 for (
size_t i=0; i<s->
J; ++i) s->
X[i] = (s->
x[i]+s->
x[i+1])/2.0;
92 for (
size_t i=0; i<s->
J; ++i) s->
h[i] = s->
x[i+1] - s->
x[i];
97 for (
size_t i=0; i<s->
J; ++i) s->
X[i] = s->
x[i];
98 for (
size_t i=0; i<s->
J; ++i) s->
h[i] = s->
x[i+1] - s->
x[i];
107 int n_extra_vars,
double input_birth_flux){
108 vector<double> xbreaks;
109 if (log_breaks) xbreaks =
logseq(_xb, _xm, _J+1);
110 else xbreaks =
seq(_xb, _xm, _J+1);
112 addSpecies(xbreaks, s, n_extra_vars, input_birth_flux);
138 state.resize(state_size_new, -999);
139 rates.resize(state_size_new, -999);
160 for (
auto spp :
species_vec) maxsize = std::max(maxsize, spp->get_maxSize());
168 std::cout <<
">> SOLVER \n";
169 string types[] = {
"FMU",
"MMU",
"CM",
"EBT",
"Implicit FMU"};
170 std::cout <<
"+ Type: " << types[
method] << std::endl;
172 std::cout <<
"+ State size = " <<
state.size() <<
"\n";
173 std::cout <<
"+ Rates size = " <<
rates.size() <<
"\n";
174 std::cout <<
"+ Species:\n";
177 std::cout <<
"Sp (" << i <<
"):\n";
210 for (
size_t i=0; i<s->
J; ++i){
219 for (
size_t i=0; i<s->
J; ++i){
230 for (
size_t i=0; i<s->
J-1; ++i){
231 double X = (s->
x[i]+s->
x[i+1])/2.0;
239 *it++ = 0; *it++ = 0;
257 std::cout <<
"state ---> cohorts\n";
265 for (
size_t i=0; i<s->
J; ++i){
270 for (
size_t i=0; i<s->
J; ++i){
280 for (
size_t i=0; i<s->
J; ++i){
298 std::cout <<
"state <--- cohorts\n";
305 for (
size_t i=0; i<s->
J; ++i){
310 for (
size_t i=0; i<s->
J; ++i){
311 double X = s->
getX(i);
312 double U = s->
getU(i);
320 for (
size_t i=0; i<s->
J; ++i){
321 double X = s->
getX(i);
322 double U = s->
getU(i);
339 auto func = [](
double t){};
344 void Solver::updateEnv(
double t, std::vector<double>::iterator S, std::vector<double>::iterator dSdt){
345 std::cout <<
"update Env...\n";
346 for (
auto spp :
species_vec) spp->triggerPreCompute();
353 std::cout <<
"calc birthFlux...\n";
355 auto newborns_production = [
this, spp](
int i,
double _t){
356 double b1 = spp->birthRate(i, spp->getX(i), _t,
env);
359 double birthFlux =
integrate_x(newborns_production, t, k);
371 vector<double> b_out;
385 b_out.push_back(birthFlux);
392 vector <double> u0out;
434 double xm = spp->getX(0)+1e-6;
436 vector<point> points(breaks.size()-1);
440 int current_interval = breaks.size()-2;
441 for (
int i=0; i<spp->J; ++i){
442 double x = spp->getX(i);
443 double N = spp->getU(i);
444 if (i == spp->J-1) x = spp->xb + x/(N+1e-12);
446 while(breaks[current_interval]>x) --current_interval;
449 points[current_interval].abund += N;
450 points[current_interval].count += 1;
451 points[current_interval].xmean += N*x;
456 for (
int i=0; i<points.size(); ++i)
if (points[i].count>0) points[i].xmean /= points[i].abund;
459 auto pred = [
this](
const point& p) ->
bool {
463 auto pend = std::remove_if(points.begin(), points.end(), pred);
464 points.erase(pend, points.end());
470 if (points.size() > 2){
471 vector<double> h(points.size());
472 h[0] = (points[1].xmean+points[0].xmean)/2 - spp->xb;
473 for (
int i=1; i<h.size()-1; ++i) h[i] = (points[i+1].xmean - points[i-1].xmean)/2;
474 h[h.size()-1] = xm - (points[h.size()-1].xmean+points[h.size()-2].xmean)/2;
476 vector <double> xx, uu;
477 xx.reserve(points.size());
478 uu.reserve(points.size());
479 for (
int i=0; i<points.size(); ++i){
480 xx.push_back(points[i].xmean);
481 uu.push_back(points[i].abund / h[i]);
489 vector <double> dens;
490 dens.reserve(points.size());
491 for (
int i=0; i<breaks.size(); ++i){
492 dens.push_back(spl.
eval(breaks[i]));
497 else return vector<double>(breaks.size(), 0);
500 throw std::runtime_error(
"This function can only be called for the EBT solver");
std::vector< double > logseq(double from, double to, int len)
virtual double init_density(int i, double x, void *env)=0
virtual void resize(int _J)=0
std::vector< double > state
virtual double getU(int i)=0
void reset(double t_start, double rtol, double atol)
virtual void set_ub(double _ub)=0
virtual double getX(int i)=0
virtual void set_xb(double _xb)=0
void set_inputBirthFlux(double b)
virtual void computeEnv(double t, Solver *sol, std::vector< double >::iterator S, std::vector< double >::iterator dSdt)=0
virtual void initAndCopyExtraState(double t, void *env, std::vector< double >::iterator &it)=0
void copyStateToCohorts(std::vector< double >::iterator state_begin)
void set_points(const Container &x, const Container &y)
std::vector< double > diff(vector< double > breaks)
std::vector< double > newborns_out(double t)
double integrate_x(wFunc w, double t, int species_id)
Computes the integral for the specified species. For details, see integrate_wudx_above.
std::vector< double > rates
void addSpecies(int _J, double _xb, double _xm, bool log_breaks, Species_Base *_mod, int n_extra_vars, double input_birth_flux=-1)
void setEnvironment(EnvironmentBase *_env)
Float eval(Float x) const
virtual void copyCohortsExtraToState(std::vector< double >::iterator &it)=0
virtual void set_birthTime(int i, double t0)=0
void copyCohortsToState()
void updateEnv(double t, std::vector< double >::iterator S, std::vector< double >::iterator dSdt)
void resizeStateFromSpecies()
virtual void setU(int i, double _u)=0
void resetState(double t0=0)
std::vector< double > seq(double from, double to, int len)
std::vector< Species_Base * > species_vec
Solver(PSPM_SolverType _method, std::string ode_method="rk45ck")
std::vector< double > getDensitySpecies_EBT(int k, std::vector< double > breaks)
virtual void copyExtraStateToCohorts(std::vector< double >::iterator &it)=0
virtual void setX(int i, double _x)=0
void step_to(double tstop, AfterStepFunc &afterStep_user)
void addSystemVariables(int _s)
struct Solver::@1 control
double calcSpeciesBirthFlux(int k, double t)
std::vector< double > u0_out(double t)