libpspm
species.tpp
Go to the documentation of this file.
1 #include <cassert>
2 #include <algorithm>
3 #include <numeric>
4 
5 // *************** Species_Base ***************
6 
7 template<class T>
9  (dynamic_cast<Species<T>>(*this)).addCohort(bc);
10 }
11 
12 
13 // *************** Species<Model> ******************
14 
15 
16 
17 template<class Model>
19  J = _J;
20  cohorts.resize(J, boundaryCohort); // when resizing, always insert copies of boundary cohort
21 }
22 
23 
24 template<class Model>
25 double Species<Model>::get_maxSize(){ // TODO ALERT: make sure this sees the latest state
26  if (!X.empty()) return *x.rbegin(); // for FMU, get this from X
27  else if (cohorts.empty()) return 0;
28  else { // else get from state vector
29  return cohorts[0].x; // cohorts are sorted descending
30  }
31 }
32 
33 
34 // FIXME: this constructor should be corrected or removed.
35 template<class Model>
36 Species<Model>::Species(std::vector<double> breaks){
37  J = breaks.size(); // changes with
38  cohorts.resize(J, boundaryCohort);
39  for (int i=0; i<J; ++i) cohorts[i].x = breaks[i];
40 }
41 
42 
43 template<class Model>
45  boundaryCohort = savedCohort = Cohort<Model>(M);
46 }
47 
48 
49 template <class Model>
51  std::cout << "~~~~~ Species ~~~~~\n";
52  //auto iset = get_iterators(sv);
53  //std::cout << "start index = " << start_index <<"\n";
54  //std::cout << "Model = " << mod << "\n";
55  std::cout << "xb = " << boundaryCohort.x << " / " << xb << "\n";
56  std::cout << "xsize = " << J << "\n";
57  std::cout << "Extra state variables: " << n_extra_statevars << "\n";
58  std::cout << "Input birth flux = " << birth_flux_in << "\n";
59  //if (!X.empty()){
60  // iset.push_back("_X", X.begin(),1);
61  // iset.push_back("_h", h.begin(),1);
62  std::cout << "x (" << x.size() << "): ";
63  for (auto xx : x) std::cout << xx << " ";
64  std::cout << "\n";
65  //}
66 
67  std::cout << "Cohorts: (" << cohorts.size() << ")\n";
68  std::cout << "t0" << "\tx" << "\t" << "u" << "\t";
69  if (!cohorts.empty()){
70  for (auto s : cohorts[0].varnames) std::cout << s << "\t";
71  }
72  std::cout << "\n";
73  for (auto& c : cohorts) {
74  //c.print_xu(); //std::cout << c.x << "\t" << c.u << "\t";
75  c.print();
76  std::cout << "\n";
77  }
78  std::cout << "- - - - - - - - - - - - - - - - - - - - - - - \n";
79  //boundaryCohort.print_xu(); //std::cout << c.x << "\t" << c.u << "\t";
80  boundaryCohort.print();
81  std::cout << "\n";
82  std::cout << "Max size = " << get_maxSize() << "\n";
83  //std::cout << "State (" << size() << "):\n";
84  //iset.print();
85 
86  //std::cout << "Rates (" << size() << "):\n";
87  //auto irates = get_iterators(rv);
88  //irates.print();
89  std::cout << "-------\n\n"; std::cout.flush();
90 
91 }
92 
93 template <class Model>
95  if (i == -1) return boundaryCohort;
96  else return cohorts[i];
97 }
98 
99 template <class Model>
100 double Species<Model>::getX(int i){
101  if (i == -1) return boundaryCohort.x;
102  else return cohorts[i].x;
103 }
104 
105 
106 template <class Model>
107 double Species<Model>::getU(int i){
108  return cohorts[i].u;
109 }
110 
111 
112 template <class Model>
114  return boundaryCohort.u;
115 }
116 
117 
118 template <class Model>
119 void Species<Model>::set_xb(double _xb){
120  xb = _xb;
121  boundaryCohort.x = _xb;
122  boundaryCohort.set_size(_xb);
123 }
124 
125 
126 template <class Model>
127 void Species<Model>::set_ub(double _ub){
128  boundaryCohort.u = _ub;
129 }
130 
131 
132 template <class Model>
133 void Species<Model>::set_birthTime(int i, double t0){
134  cohorts[i].birth_time = t0;
135 }
136 
137 
138 template <class Model>
139 void Species<Model>::setX(int i, double _x){
140  cohorts[i].x = _x;
141  cohorts[i].set_size(_x);
142 }
143 
144 
145 template <class Model>
146 void Species<Model>::setU(int i, double _u){
147  cohorts[i].u = _u;
148 }
149 
150 
151 template <class Model>
152 void Species<Model>::initAndCopyExtraState(double t, void * env, std::vector<double>::iterator &it){
153  // init boundary cohort (no copy required)
154  boundaryCohort.init_state(t, env);
155  // init internal cohorts and copy to state vector
156  for (auto& c : cohorts){
157  c.init_state(t, env); // init state
158  auto it_prev = it;
159  it = c.get_state(it); // copy the initialized state into state vector
160  assert(distance(it_prev, it) == n_extra_statevars);
161  }
162 }
163 
164 
165 template <class Model>
166 void Species<Model>::initBoundaryCohort(double t, void * env){
167  boundaryCohort.birth_time = t;
168  boundaryCohort.init_state(t, env);
169 }
170 
171 
172 template <class Model>
173 double Species<Model>::init_density(int i, double _x, void * _env){
174  return cohorts[i].init_density(_x, _env, birth_flux_in);
175 }
176 
177 // TODO: check increment here itself
178 template <class Model>
179 void Species<Model>::copyExtraStateToCohorts(std::vector<double>::iterator &it){
180  for (auto& c : cohorts) c.set_state(it);
181 }
182 
183 
184 template <class Model>
185 void Species<Model>::copyCohortsExtraToState(std::vector<double>::iterator &it){
186  for (auto& c : cohorts) c.get_state(it);
187 }
188 
189 
190 template <class Model>
192  for (auto& c : cohorts) c.need_precompute = true;
193  boundaryCohort.need_precompute = true;
194 }
195 
196 
197 template <class Model>
198 double Species<Model>::establishmentProbability(double t, void * env){
199  return boundaryCohort.establishmentProbability(t, env);
200 }
201 
202 
203 // FIXME: Should be renamed as "calc_boundary_u"
204 template <class Model>
205 double Species<Model>::calc_boundary_u(double gb, double pe){
206  std::cout << "calc_boundary_u\n";
207  if (bfin_is_u0in){
208  boundaryCohort.u = birth_flux_in;
209  }
210  else {
211  boundaryCohort.u = (gb>0)? birth_flux_in * pe/gb : 0;
212  }
213  return boundaryCohort.u;
214 }
215 
216 
217 template <class Model>
218 double Species<Model>::growthRate(int i, double x, double t, void * env){
219  Cohort<Model> &c = (i<0)? boundaryCohort : cohorts[i];
220  return c.growthRate(c.x,t,env);
221 }
222 
223 
224 template <class Model>
225 double Species<Model>::growthRateOffset(int i, double x, double t, void * env){
226  Cohort<Model> coff = (i<0)? boundaryCohort : cohorts[i];
227  coff.set_size(x);
228  //coff.preCompute(coff.x,t,env);
229 
230  return coff.growthRate(coff.x,t,env);
231 }
232 
233 
234 template <class Model>
235 std::vector<double> Species<Model>::growthRateGradient(int i, double x, double t, void * env, double grad_dx){
236  Cohort<Model> &c = (i<0)? boundaryCohort : cohorts[i];
237 
238  Cohort<Model> cplus = c;
239  cplus.set_size(c.x + grad_dx);
240  //cplus.preCompute(cplus.x,t,env);
241 
242  double g = c.growthRate(c.x,t,env);
243  double gplus = cplus.growthRate(cplus.x, t, env);
244 
245  return {g, (gplus-g)/grad_dx};
246 }
247 
248 
249 template <class Model>
250 std::vector<double> Species<Model>::growthRateGradientCentered(int i, double xplus, double xminus, double t, void * env){
251  assert(i>=0);
252 
253  Cohort<Model> cplus = cohorts[i];
254  cplus.set_size(xplus);
255  //cplus.preCompute(cplus.x,t,env);
256 
257  Cohort<Model> cminus = cohorts[i];
258  cminus.set_size(xminus);
259  //cminus.preCompute(cminus.x,t,env);
260 
261  double gplus = cplus.growthRate(cplus.x, t, env);
262  double gminus = cminus.growthRate(cminus.x, t, env);
263 
264  return {gplus, gminus};
265 }
266 
267 
268 template <class Model>
269 double Species<Model>::mortalityRate(int i, double x, double t, void * env){
270  assert(i>=0);
271  Cohort<Model> &c = cohorts[i];
272  return c.mortalityRate(c.x,t,env);
273 }
274 
275 
276 template <class Model>
277 std::vector<double> Species<Model>::mortalityRateGradient(int i, double x, double t, void * env, double grad_dx){
278  Cohort<Model> &c = (i<0)? boundaryCohort : cohorts[i];
279 
280  Cohort<Model> cplus = c;
281  cplus.set_size(x + grad_dx);
282  //cplus.preCompute(cplus.x,t,env);
283 
284  double g = c.mortalityRate(c.x,t,env);
285  double gplus = cplus.mortalityRate(cplus.x, t, env);
286 
287  return {g, (gplus-g)/grad_dx};
288 }
289 
290 
291 template <class Model>
292 double Species<Model>::birthRate(int i, double x, double t, void * env){
293  Cohort<Model> &c = (i<0)? boundaryCohort : cohorts[i];
294  return c.birthRate(c.x,t,env);
295 }
296 
297 
298 template <class Model>
299 void Species<Model>::getExtraRates(std::vector<double>::iterator &it){
300  for (auto& c : cohorts) c.get_rates(it);
301 }
302 
303 
304 template <class Model>
306  cohorts.push_back(boundaryCohort);
307  ++J;
308 }
309 
310 
311 
312 // This function allows a user to add a custom cohort to the species any time.
313 // However, Solver->resizeStateFromSpecies() must be called after calling this function.
314 template <class Model>
316  cohorts.push_back(bc);
317  ++J;
318  // FIXME: add option to sort cohorts here.
319 }
320 
321 
322 template <class Model>
324  if (cohorts.size() < 3) return; // do nothing if there are 2 or fewer cohorts
325  int i_min = 1;
326  double dx_min = cohorts[0].x - cohorts[2].x;
327  for (int i=1; i<J-1; ++i){ // skip first and last cohorts
328  double dx = cohorts[i-1].x - cohorts[i+1].x;
329  if (dx < dx_min){
330  dx_min = dx;
331  i_min = i;
332  }
333  }
334 
335  cohorts.erase(cohorts.begin()+i_min);
336  --J;
337 }
338 
339 
340 template <class Model>
342  // mark cohorts to remove; skip 1st and last cohort
343  for (int i=1; i<J-1; i+=2){
344  double dx_lo = cohorts[i-1].x-cohorts[i].x;
345  double dx_hi = cohorts[i].x-cohorts[i+1].x;
346 
347  if (dx_lo < dxcut || dx_hi < dxcut) cohorts[i].remove = true;
348  }
349 
350  // remove marked cohorts
351  auto it_end = std::remove_if(cohorts.begin(), cohorts.end(), [](Cohort<Model> &c){return c.remove;});
352  cohorts.erase(it_end, cohorts.end());
353 
354  // reset size
355  J = cohorts.size();
356 }
357 
358 
359 template <class Model>
361  // mark cohorts to remove; skip pi0-cohort (index J-1)
362  for (int i=0; i<J-1; ++i){
363  if (cohorts[i].u < ucut) cohorts[i].remove = true;
364  }
365 
366  // remove marked cohorts
367  auto it_end = std::remove_if(cohorts.begin(), cohorts.end(), [](Cohort<Model> &c){return c.remove;});
368  cohorts.erase(it_end, cohorts.end());
369 
370  // reset size
371  J = cohorts.size();
372 }
373 
374 
375 //template <class Model>
376 //void Species<Model>::backupCohort(int j){
377 // savedCohort = cohorts[j];
378 //}
379 
380 //template <class Model>
381 //void Species<Model>::restoreCohort(int j){
382 // cohorts[j] = savedCohort;
383 //}
384 
385 //template <class Model>
386 //void Species<Model>::copyBoundaryCohortTo(int j){
387 // cohorts[j] = boundaryCohort;
388 //}
389 
390 //template <class Model>
391 //void Species<Model>::backupBoundaryCohort(){
392  //boundaryCohort_backup = boundaryCohort;
393 //}
394 
395 //template <class Model>
396 //void Species<Model>::restoreBoundaryCohort(){
397  //boundaryCohort = boundaryCohort_backup;
398 //}
399 
400 
std::vector< double > mortalityRateGradient(int i, double x, double t, void *env, double grad_dx)
Definition: species.tpp:277
double growthRateOffset(int i, double x, double t, void *env)
Definition: species.tpp:225
virtual double get_maxSize()=0
double getU(int i)
Definition: species.tpp:107
void removeDeadCohorts(double ucut)
Definition: species.tpp:360
bool bfin_is_u0in
Definition: species.h:37
double get_boundary_u()
Definition: species.tpp:113
void getExtraRates(std::vector< double >::iterator &it)
Definition: species.tpp:299
void print()
Definition: species.tpp:50
void set_xb(double _xb)
Definition: species.tpp:119
double x
Definition: cohort.h:11
void set_size(double _x)
Definition: cohort.h:38
std::vector< double > growthRateGradient(int i, double x, double t, void *env, double grad_dx)
Definition: species.tpp:235
void copyCohortsExtraToState(std::vector< double >::iterator &it)
Definition: species.tpp:185
virtual void addCohort()=0
double calc_boundary_u(double gb, double pe)
Definition: species.tpp:205
int n_extra_statevars
Definition: species.h:21
void removeDensestCohort()
Definition: species.tpp:323
void removeDenseCohorts(double dxcut)
Definition: species.tpp:341
double growthRate(int i, double x, double t, void *env)
Definition: species.tpp:218
double birthRate(int i, double x, double t, void *env)
Definition: species.tpp:292
void addCohort()
Definition: species.tpp:305
double establishmentProbability(double t, void *env)
Definition: species.tpp:198
void setU(int i, double _u)
Definition: species.tpp:146
std::vector< double > x
Definition: species.h:29
std::vector< double > growthRateGradientCentered(int i, double xplus, double xminus, double t, void *env)
Definition: species.tpp:250
double mortalityRate(int i, double x, double t, void *env)
Definition: species.tpp:269
double birthRate(double x, double t, void *_env)
Definition: cohort.h:68
double get_maxSize()
Definition: species.tpp:25
double growthRate(double x, double t, void *_env)
Definition: cohort.h:54
double init_density(int i, double x, void *env)
Definition: species.tpp:173
Cohort< Model > & getCohort(int i)
Definition: species.tpp:94
double birth_flux_in
Definition: species.h:34
double xb
Definition: species.h:41
void initAndCopyExtraState(double t, void *env, std::vector< double >::iterator &it)
Definition: species.tpp:152
void triggerPreCompute()
Definition: species.tpp:191
void copyExtraStateToCohorts(std::vector< double >::iterator &it)
Definition: species.tpp:179
void setX(int i, double _x)
Definition: species.tpp:139
void resize(int _J)
Definition: species.tpp:18
double mortalityRate(double x, double t, void *_env)
Definition: cohort.h:61
void set_birthTime(int i, double t0)
Definition: species.tpp:133
void initBoundaryCohort(double t, void *env)
Definition: species.tpp:166
std::vector< double > X
Definition: species.h:28
Species(std::vector< double > breaks=std::vector< double >())
Definition: species.tpp:36
void set_ub(double _ub)
Definition: species.tpp:127
double getX(int i)
Definition: species.tpp:100