Utopia  2
Framework for studying models of complex & adaptive systems.
PredatorPreyPlant.hh
Go to the documentation of this file.
1 #ifndef UTOPIA_MODELS_PREDATORPREYPLANT_HH
2 #define UTOPIA_MODELS_PREDATORPREYPLANT_HH
3 
4 #include <algorithm>
5 #include <random>
6 
7 #include <utopia/core/apply.hh>
8 #include <utopia/core/model.hh>
10 
12 
13 #include "species.hh"
14 
15 
16 namespace Utopia {
17 namespace Models {
18 namespace PredatorPreyPlant {
19 
20 // ++ Type definitions ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
21 
23 struct State {
26 
29 
32 
34  template<class RNGType>
35  State(const DataIO::Config& cfg, const std::shared_ptr<RNGType>& rng)
36  :
37  predator{},
38  prey{},
39  plant{}
40  {
41  std::uniform_real_distribution<double> dist(0., 1.);
42 
43  // Get the threshold probability value
44  const auto p_plant = get_as<double>("p_plant", cfg);
45  const auto p_prey = get_as<double>("p_prey", cfg);
46  const auto p_predator = get_as<double>("p_predator", cfg);
47 
48  auto cfg_prey = get_as<DataIO::Config>("prey", cfg);
49  auto cfg_predator = get_as<DataIO::Config>("predator", cfg);
50 
51  // Check if the max resource limit is actually higher than the lower
52  // limit.
53  const auto min_init_resources_prey = get_as<int>("min_init_resources",
54  cfg_prey);
55  const auto max_init_resources_prey = get_as<int>("max_init_resources",
56  cfg_prey);
57  const auto min_init_resources_predator =
58  get_as<int>("min_init_resources", cfg_predator);
59  const auto max_init_resources_predator =
60  get_as<int>("max_init_resources", cfg_predator);
61  if(max_init_resources_predator <
62  min_init_resources_predator){
63  throw::std::invalid_argument("The upper limit for the initial "
64  "predator resources needs to be higher than the lower limit.");
65  }
66  if(max_init_resources_prey <
67  min_init_resources_prey){
68  throw::std::invalid_argument("The upper limit for the initial "
69  "prey resources needs to be higher than the lower limit.");
70  }
71  // Set a plant on this cell with a given probability
72  plant.on_cell = (dist(*rng) < p_plant);
73 
74  // Set a predator on a cell with the given probability and the
75  // resources in the given range.
76  if (dist(*rng) < p_predator) {
77  predator.on_cell = true;
78  std::uniform_int_distribution<> init_res_dist_pred(
79  min_init_resources_predator,
80  max_init_resources_predator
81  );
82  predator.resources = init_res_dist_pred(*rng);
83  }
84 
85  // Set a prey on this cell with the desired probability; also set the
86  // initial resource amount from an integer distribution.
87  if (dist(*rng) < p_prey) {
88  prey.on_cell = true;
89  std::uniform_int_distribution<> init_res_dist_prey(
90  min_init_resources_prey,
91  max_init_resources_prey
92  );
93 
94  prey.resources = init_res_dist_prey(*rng);
95  }
96 
97 
98  }
99 };
100 
101 
103 
108 
111 
112 // ++ Model definition ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
113 
115 
130  : public Model<PredatorPreyPlant, ModelTypes>
131 {
132 public:
135 
137  using DataSet = typename Base::DataSet;
138 
141 
143  using Cell = typename CellManager::Cell;
144 
146  using Rule = typename CellManager::RuleFunc;
147 
148 
149 private:
150  // Base members: _time, _name, _cfg, _hdfgrp, _rng, _monitor, _log, _space
151  // ... but you should definitely check out the documentation ;)
152 
153  // -- Members -------------------------------------------------------------
156 
157  // .. Model parameters ....................................................
160 
162  std::size_t _num_moves;
163 
164  // .. Temporary objects ...................................................
167 
170 
173 
176 
177 
179  std::uniform_real_distribution<double> _prob_distr;
180 
182  std::uniform_int_distribution<> _cm_dist;
183 
184 
185  // .. Datasets ............................................................
187  const std::shared_ptr<DataSet> _dset_prey;
188 
190  const std::shared_ptr<DataSet> _dset_predator;
191 
193  const std::shared_ptr<DataSet> _dset_resource_prey;
194 
196  const std::shared_ptr<DataSet> _dset_resource_predator;
197 
199  const std::shared_ptr<DataSet> _dset_plant;
200 
201 
202  // .. Rule functions and helper methods ...................................
204 
209  Rule _cost_of_living = [this](const auto& cell) {
210  // Get the state of the cell
211  auto& state = cell->state;
212 
213  // Subtract the cost of living and clamp the resources to the limits:
214  // If the resources exceed the maximal resources they are equal to
215  // the maximal resources and if they go below 0 they are mapped to 0.
216  state.predator.resources =
217  std::clamp( state.predator.resources
220  state.prey.resources =
221  std::clamp( state.prey.resources
224 
225  // Remove predators that have no resources.
226  if (state.predator.on_cell and state.predator.resources <= 0.)
227  state.predator.on_cell = false;
228 
229  // Remove prey that have no resources.
230  if (state.prey.on_cell and state.prey.resources <= 0.)
231  state.prey.on_cell = false;
232 
233  return state;
234  };
235 
237 
240  std::shared_ptr<Cell>
242  {
243  return nbs[std::uniform_int_distribution<std::size_t>(0, nbs.size() - 1)(*this->_rng)];
244  }
245 
247 
250  void move_predator_to_nb_cell(const std::shared_ptr<Cell>& cell,
251  const std::shared_ptr<Cell>& nb_cell) {
252  auto& state = cell->state;
253  auto& nb_state = nb_cell->state;
254 
255  nb_state.predator.on_cell = true;
256  nb_state.predator.resources = state.predator.resources;
257 
258  state.predator.on_cell = false;
259  state.predator.resources = 0.;
260  }
261 
263 
266  void move_prey_to_nb_cell(const std::shared_ptr<Cell>& cell,
267  const std::shared_ptr<Cell>& nb_cell) {
268  auto& state = cell->state;
269  auto& nb_state = nb_cell->state;
270 
271  nb_state.prey.on_cell = true;
272  nb_state.prey.resources = state.prey.resources;
273 
274  state.prey.on_cell = false;
275  state.prey.resources = 0.;
276  }
277 
278 
280 
287  auto move_prey(std::shared_ptr<Cell> cell) {
288  _resource_cell.clear();
289 
290  // Collect empty neighboring cells with available resources, where the
291  // prey could move
292  for (const auto& nb : this->_cm.neighbors_of(cell)) {
293  if (nb->state.plant.on_cell
294  and not nb->state.prey.on_cell
295  and not nb->state.predator.on_cell)
296  _resource_cell.push_back(nb);
297  }
298 
299  // Choose a random cell with resources.
300  if (_resource_cell.size() > 0) {
301  std::uniform_int_distribution<> dist(0, _resource_cell.size() - 1);
302  const auto nb_cell = _resource_cell[dist(*this->_rng)];
303  move_prey_to_nb_cell(cell, nb_cell);
304  return nb_cell;
305  }
306  // if there isn't one, then try a random walk
307  else {
308  const std::shared_ptr<Cell> nb_cell = get_random_neighbor(_cm.neighbors_of(cell));
309  // The will move even if there is a predator.
310  if (not nb_cell->state.prey.on_cell) {
311  move_prey_to_nb_cell(cell, nb_cell);
312  return nb_cell;
313  }
314  return cell;
315  }
316  };
317 
318 
320 
326  auto move_predator(std::shared_ptr<Cell> cell) {
327  // clear the container for cells that contain prey or empty cells
328  // in the neighbourhood
329  _prey_cell.clear();
330 
331  // Collect neighboring cells with preys and without predator
332  for (const auto& nb : this->_cm.neighbors_of(cell)) {
333  if ( nb->state.prey.on_cell
334  and not nb->state.predator.on_cell)
335  _prey_cell.push_back(nb);
336  }
337 
338  // now update the cell state and the respective neighbor
339  if (_prey_cell.size() > 0) {
340  // distribution to choose a random cell for the movement
341  std::uniform_int_distribution<> dist_prey(0 ,_prey_cell.size() - 1);
342  auto nb_cell = _prey_cell[dist_prey(*this->_rng)];
343  // move the predator to the given cell
344  move_predator_to_nb_cell(cell, nb_cell);
345 
346  return nb_cell;
347  }
348  else {
349  // If no prey in the neighborhoods try a random step if possible
350  const std::shared_ptr<Cell> nb_cell = get_random_neighbor(_cm.neighbors_of(cell));
351  if (not nb_cell->state.predator.on_cell){
352  // move the predator to the given cell
353  move_predator_to_nb_cell(cell, nb_cell);
354  return nb_cell;
355  }
356  }
357  return cell;
358  };
359 
360 
362  /*+ Go through all cells. If there are both predator and prey on the cell,
363  * then the prey attempts to flee with a given probability.
364  * If there is only a predator on the cell then it moves until it reaches
365  * the movement limit or reaches a prey.
366  * If there is only a prey on the cell and there are no plant resources,
367  * then the prey moves until it reaches the movement limit or it finds a
368  * cell with plant resource on it.
369  */
370  void move_entities(std::shared_ptr<Cell> cell) {
371  auto& state = cell->state;
372 
373  // Marker used to compute how many steps the prey or predator has taken
374  unsigned int step = 0;
375 
376  if (state.predator.on_cell) {
377  while ( step++ < _params.predator.move_limit
378  and not cell->state.prey.on_cell)
379  {
380  cell = move_predator(cell);
381  }
382  }
383  else if (state.prey.on_cell and not cell->state.plant.on_cell){
384  while(step++ < _params.prey.move_limit and not cell->state.plant.on_cell)
385  cell = move_prey(cell);
386  }
387  };
388 
389 
390 
392 
397  Rule _flee_prey = [this](const auto& cell) {
398  auto& state = cell->state;
399 
400  if (state.prey.on_cell and state.predator.on_cell and
401  (_prob_distr(*this->_rng) < _params.prey.p_flee)) {
402  // Collect empty neighboring cells to which the prey could flee
403  _empty_cell.clear();
404  for (const auto& nb : this->_cm.neighbors_of(cell)) {
405  if ( not nb->state.prey.on_cell
406  and not nb->state.predator.on_cell)
407  _empty_cell.push_back(nb);
408  }
409 
410  // If there is an empty cell, move there
411  if (_empty_cell.size() > 0) {
412  // Choose a random cell to move to
413  std::uniform_int_distribution<>
414  dist(0, _empty_cell.size() - 1);
415  auto nb_cell = _empty_cell[dist(*this->_rng)];
416  move_prey_to_nb_cell(cell, nb_cell);
417  }
418  }
419  return state;
420  };
421 
422 
423 
425 
431  Rule _eat = [this](const auto& cell) {
432  auto& state = cell->state;
433 
434  // Predator eats prey
435  if (state.predator.on_cell and state.prey.on_cell) {
436  // Increment resources and clamp to [0, resource_max]
437  state.predator.resources =
438  std::clamp( state.predator.resources
441 
442  // Remove the prey from the cell
443  state.prey.on_cell = false;
444  state.prey.resources = 0.;
445  }
446 
447  // Prey eats plants
448  else if (state.prey.on_cell and state.plant.on_cell) {
449  // Increment resources and clamp to [0, resource_max]
450  state.prey.resources =
451  std::clamp( state.prey.resources
454 
456  state.plant.on_cell = false;
457  state.plant.regeneration_counter = 0;
458  }
459  }
460  return state;
461  };
462 
463 
465 
470  Rule _reproduce = [this](const auto& cell) {
471  auto& state = cell->state;
472 
473  // Reproduction of predators
474  if ( state.predator.on_cell
475  and (this->_prob_distr(*this->_rng) < _params.predator.repro_prob)
476  and ( state.predator.resources
478  {
479  const std::shared_ptr<Cell> nb_cell = get_random_neighbor(_cm.neighbors_of(cell));
480  if (not nb_cell->state.predator.on_cell) {
481  nb_cell->state.predator.on_cell = true;
482 
483  // transfer resources from parent to offspring
484  nb_cell->state.predator.resources = _params.predator.repro_cost;
485  state.predator.resources -= _params.predator.repro_cost;
486  }
487  }
488 
489  // Reproduction of preys
490  if ( state.prey.on_cell
491  and this->_prob_distr(*this->_rng) < _params.prey.repro_prob
492  and state.prey.resources >= _params.prey.repro_resource_requ)
493  {
494  const std::shared_ptr<Cell> nb_cell = get_random_neighbor(_cm.neighbors_of(cell));
495  if (not nb_cell->state.prey.on_cell) {
496  nb_cell->state.prey.on_cell = true;
497 
498  // transfer resources from parent to offspring
499  nb_cell->state.prey.resources = _params.prey.repro_cost;
500  state.prey.resources -= _params.prey.repro_cost;
501  }
502  }
503 
504  // If there is no plant, there _may_ be plant growth, depending on the
505  // plant growth model
506  if (not state.plant.on_cell) {
507  // TODO Ideally, the model is decided once in the beginning, and
508  // not for each cell anew.
510  // If the regeneration counter if not high enough, increment it
511  if ( state.plant.regeneration_counter
513  {
514  // Grow a plant :)
515  state.plant.on_cell = true;
516  }
517  else {
518  state.plant.regeneration_counter++;
519  }
520  }
522  // Regrow with a certain probability
523  if (_prob_distr(*this->_rng) < _params.plant.regen_prob) {
524  state.plant.on_cell = true;
525  }
526  }
527  // else: no regrowth
528  }
529 
530  return state;
531  };
532 
533 
534 public:
535  // -- Model setup ---------------------------------------------------------
537 
545  template <class ParentModel>
547  const std::string& name,
548  ParentModel& parent_model,
549  const DataIO::Config& custom_cfg = {}
550  )
551  :
552  Base(name, parent_model, custom_cfg),
553 
554  // Initialize the cell manager, binding it to this model
555  _cm(*this),
556 
557  // Extract model parameters
558  _params(this->_cfg),
559  _num_moves([&](){
560  const auto f = get_as<double>("num_moves_fraction", this->_cfg);
561  return f * this->_cm.cells().size();
562  }()),
563 
564  // Temporary cell containers
565  _prey_cell(),
566  _empty_cell(),
567  _repro_cell(),
568 
569  // create random distributions
570  _prob_distr(0., 1.),
571  _cm_dist(0, _cm.cells().size() - 1),
572 
573  // create datasets
574  _dset_prey(this->create_cm_dset("prey", _cm)),
575  _dset_predator(this->create_cm_dset("predator", _cm)),
576  _dset_resource_prey(this->create_cm_dset("resource_prey", _cm)),
577  _dset_resource_predator(this->create_cm_dset("resource_predator", _cm)),
578  _dset_plant(this->create_cm_dset("plant", _cm))
579  {
580  // Inform about number of movements per iteration step:
581  this->_log->info("The movement rule will be applied {} times each "
582  "time step.", _num_moves);
583 
584  // Load the cell state from a file, overwriting the current state
585  if (this->_cfg["cell_states_from_file"]) {
586  setup_cell_states_from_file(this->_cfg["cell_states_from_file"]);
587  }
588 
589  // Reserve memory in the size of the neighborhood for the temp. vectors
590  const auto nb_size = _cm.nb_size();
591  _prey_cell.reserve(nb_size);
592  _empty_cell.reserve(nb_size);
593  _repro_cell.reserve(nb_size);
594 
595  // Initialization finished
596  this->_log->info("{} model fully set up.", this->_name);
597  }
598 
599 private:
600  // .. Setup functions .....................................................
601 
603  void setup_cell_states_from_file(const Config& cs_cfg) {
604  const auto hdf5_file = get_as<std::string>("hdf5_file", cs_cfg);
605 
606  if (get_as<bool>("load_predator", cs_cfg)) {
607  this->_log->info("Loading predator positions from file ...");
608 
609  // Use the CellManager to set the cell state from the data
610  // given by the `predator` dataset. Load as int to be able to
611  // detect that a user supplied invalid values (better than
612  // failing silently, which would happen with booleans).
613  _cm.set_cell_states<int>(hdf5_file, "predator",
614  [this](auto& cell, const int on_cell){
615  if (on_cell == 0 or on_cell == 1) {
616  // Place predator state on cell.
617  cell->state.predator.on_cell = on_cell;
618  // Take care of species resources.
619  if(on_cell){
620  const auto& predator_cfg =
621  get_as<Config>("predator",
622  _cfg["cell_manager"]["cell_params"]);
623  int min_init_resources_predator =
624  get_as<int>("min_init_resources",
625  predator_cfg);
626  int max_init_resources_predator =
627  get_as<int>("max_init_resources",
628  predator_cfg);
629  std::uniform_int_distribution<>
630  init_res_dist_predator(
631  min_init_resources_predator,
632  max_init_resources_predator
633  );
634  cell->state.predator.resources =
635  init_res_dist_predator(*this->_rng);
636  }
637  else{
638  cell->state.predator.resources = 0;
639  }
640  return;
641  }
642  throw std::invalid_argument("While setting predator "
643  "positions, encountered an invalid value: "
644  + std::to_string(on_cell) + ". Allowed: 0 or 1.");
645  }
646  );
647  this->_log->info("Predator positions loaded.");
648  }
649 
650  if (get_as<bool>("load_prey", cs_cfg)) {
651  this->_log->info("Loading prey positions from file ...");
652 
653  _cm.set_cell_states<int>(hdf5_file, "prey",
654  [this](auto& cell, const int on_cell){
655  if (on_cell == 0 or on_cell == 1) {
656  // Place prey state on cell.
657  cell->state.prey.on_cell = on_cell;
658  // Take care of species resources.
659  if(on_cell){
660  const auto& prey_cfg =
661  get_as<Config>("prey",
662  _cfg["cell_manager"]["cell_params"]);
663  int min_init_resources_prey =
664  get_as<int>("min_init_resources", prey_cfg);
665  int max_init_resources_prey =
666  get_as<int>("max_init_resources", prey_cfg);
667  std::uniform_int_distribution<>
668  init_res_dist_prey(
669  min_init_resources_prey,
670  max_init_resources_prey
671  );
672  cell->state.prey.resources =
673  init_res_dist_prey(*this->_rng);
674  }
675  else{
676  cell->state.prey.resources = 0;
677  }
678  return;
679  }
680  throw std::invalid_argument("While setting prey "
681  "positions, encountered an invalid value: "
682  + std::to_string(on_cell) + ". Allowed: 0 or 1.");
683  }
684  );
685  this->_log->info("Prey positions loaded.");
686  }
687 
688  if (get_as<bool>("load_plant", cs_cfg)) {
689  this->_log->info("Loading plant positions from file ...");
690 
691  _cm.set_cell_states<int>(hdf5_file, "plant",
692  [](auto& cell, const int on_cell){
693  if (on_cell == 0 or on_cell == 1) {
694  cell->state.plant.on_cell = on_cell;
695  return;
696  }
697  throw std::invalid_argument("While setting plant "
698  "positions, encountered an invalid value: "
699  + std::to_string(on_cell) + ". Allowed: 0 or 1.");
700  }
701  );
702  this->_log->info("Plant positions loaded.");
703  }
704  }
705 
706 public:
707  // -- Public Interface ----------------------------------------------------
708  // .. Simulation Control ..................................................
709 
711 
718  void perform_step() {
719  apply_rule<Update::async, Shuffle::off>(_cost_of_living, _cm.cells());
720 
721  // Choose _num_moves cells randomly and apply the movement rule to them
722  // NOTE Be aware that cells can be selected multiple times.
723  for (std::size_t i = 0; i < _num_moves; ++i) {
724  move_entities(_cm.cells()[_cm_dist(*this->_rng)]);
725  }
726  apply_rule<Update::async, Shuffle::on>(_flee_prey, _cm.cells(),
727  *this->_rng);
728  apply_rule<Update::async, Shuffle::off>(_eat, _cm.cells());
729  apply_rule<Update::async, Shuffle::on>(_reproduce, _cm.cells(),
730  *this->_rng);
731  }
732 
734  void monitor () {
735  // Calculate the densities for all species
736  auto [pred_density, prey_density, plant_density] = [this](){
737  double predator_sum = 0.;
738  double prey_sum = 0.;
739  double plant_sum = 0.;
740  double num_cells = this->_cm.cells().size();
741 
742  for (const auto& cell : this->_cm.cells()) {
743  auto state = cell->state;
744 
745  if (state.prey.on_cell) prey_sum++;
746  if (state.predator.on_cell) predator_sum++;
747  if (state.plant.on_cell) plant_sum++;
748  }
749  return std::tuple{predator_sum / num_cells,
750  prey_sum / num_cells,
751  plant_sum / num_cells};
752  }();
753 
754  this->_monitor.set_entry("predator_density", pred_density);
755  this->_monitor.set_entry("prey_density", prey_density);
756  this->_monitor.set_entry("plant_density", plant_density);
757  }
758 
760 
768  void write_data() {
769  // Predator
770  _dset_predator->write(_cm.cells().begin(), _cm.cells().end(),
771  [](const auto& cell) {
772  return static_cast<char>(cell->state.predator.on_cell);
773  }
774  );
775 
776  // Prey
777  _dset_prey->write(_cm.cells().begin(), _cm.cells().end(),
778  [](const auto& cell) {
779  return static_cast<char>(cell->state.prey.on_cell);
780  }
781  );
782 
783  // Plant
784  _dset_plant->write(_cm.cells().begin(), _cm.cells().end(),
785  [](const auto& cell) {
786  return static_cast<char>(cell->state.plant.on_cell);
787  }
788  );
789 
790  // resource of predator
791  _dset_resource_predator->write(_cm.cells().begin(), _cm.cells().end(),
792  [](const auto& cell) {
793  return cell->state.predator.resources;
794  }
795  );
796 
797  // resource of prey
798  _dset_resource_prey->write(_cm.cells().begin(), _cm.cells().end(),
799  [](const auto& cell) {
800  return cell->state.prey.resources;
801  }
802  );
803  }
804 };
805 
806 } // namespace PredatorPreyPlant
807 } // namespace Models
808 } // namespace Utopia
809 
810 #endif // UTOPIA_MODELS_PREDATORPREYPLANT_HH
void set_cell_states(const std::string &hdf5_file, const std::string &dset_path, const SetterFunc &setter_func)
Set all cell states using information from a HDF5 file.
Definition: cell_manager.hh:388
const CellContainer< Cell > & cells() const
Return const reference to the managed CA cells.
Definition: cell_manager.hh:219
typename std::function< CellState(const std::shared_ptr< Cell > &)> RuleFunc
The type of a rule function acting on cells of this cell manager.
Definition: cell_manager.hh:84
auto nb_size() const
Return the (maximum) size of the currently selected neighborhood.
Definition: cell_manager.hh:450
CellContainer< Cell > neighbors_of(const Cell &cell) const
Retrieve the given cell's neighbors.
Definition: cell_manager.hh:458
Utopia::Cell< CellTraits > Cell
Type of the managed cells.
Definition: cell_manager.hh:47
Base class interface for Models using the CRT Pattern.
Definition: model.hh:112
Monitor _monitor
The monitor.
Definition: model.hh:188
std::shared_ptr< DataSet > create_cm_dset(const std::string name, const CellManager &cm, const std::size_t compression_level=1, const std::vector< hsize_t > chunksize={})
Create a dataset storing data from a CellManager.
Definition: model.hh:849
typename ModelTypes::DataSet DataSet
Data type that is used for storing data.
Definition: model.hh:125
const Config _cfg
Config node belonging to this model instance.
Definition: model.hh:158
const std::string _name
Name of the model instance.
Definition: model.hh:149
typename ModelTypes::Config Config
Data type that holds the configuration.
Definition: model.hh:116
const std::shared_ptr< spdlog::logger > _log
The (model) logger.
Definition: model.hh:164
const std::shared_ptr< RNG > _rng
The RNG shared between models.
Definition: model.hh:161
PredatorPreyPlant Model on grid cells.
Definition: PredatorPreyPlant.hh:131
CellContainer< Cell > _repro_cell
A container to temporarily accumulate neighbour cells for reproduction.
Definition: PredatorPreyPlant.hh:172
std::uniform_real_distribution< double > _prob_distr
Uniform real distribution [0, 1) for evaluating probabilities.
Definition: PredatorPreyPlant.hh:179
const std::shared_ptr< DataSet > _dset_plant
Dataset of Plant resources.
Definition: PredatorPreyPlant.hh:199
const std::shared_ptr< DataSet > _dset_resource_prey
Dataset of Prey resources on the grid.
Definition: PredatorPreyPlant.hh:193
Rule _flee_prey
If a prey is on the cell, determine whether it may flee and where to.
Definition: PredatorPreyPlant.hh:397
const std::shared_ptr< DataSet > _dset_predator
Dataset of Predator locations on the grid.
Definition: PredatorPreyPlant.hh:190
void move_predator_to_nb_cell(const std::shared_ptr< Cell > &cell, const std::shared_ptr< Cell > &nb_cell)
Move a predator to a neighboring cell.
Definition: PredatorPreyPlant.hh:250
auto move_prey(std::shared_ptr< Cell > cell)
Move the prey looking for resources.
Definition: PredatorPreyPlant.hh:287
void perform_step()
Perform an iteration step.
Definition: PredatorPreyPlant.hh:718
typename Base::DataSet DataSet
Data type for a dataset.
Definition: PredatorPreyPlant.hh:137
CellManager _cm
The cell manager.
Definition: PredatorPreyPlant.hh:155
CellContainer< Cell > _resource_cell
A container to temporarily accumulate neighbour cells with mature plants.
Definition: PredatorPreyPlant.hh:175
PredatorPreyPlant(const std::string &name, ParentModel &parent_model, const DataIO::Config &custom_cfg={})
Construct the PredatorPreyPlant model.
Definition: PredatorPreyPlant.hh:546
std::uniform_int_distribution _cm_dist
Distribution for randomly selecting a cell in your cellmanager.
Definition: PredatorPreyPlant.hh:182
void monitor()
Monitor model information.
Definition: PredatorPreyPlant.hh:734
const std::shared_ptr< DataSet > _dset_prey
Dataset of Prey locations on the grid.
Definition: PredatorPreyPlant.hh:187
typename CellManager::RuleFunc Rule
Type of the update rules.
Definition: PredatorPreyPlant.hh:146
Model< PredatorPreyPlant, ModelTypes > Base
The base model.
Definition: PredatorPreyPlant.hh:134
void setup_cell_states_from_file(const Config &cs_cfg)
Sets predator, prey, and plant positions from loaded HDF5 data.
Definition: PredatorPreyPlant.hh:603
CellContainer< Cell > _prey_cell
A container to temporarily accumulate the prey neighbour cells.
Definition: PredatorPreyPlant.hh:166
auto move_predator(std::shared_ptr< Cell > cell)
Move the predator looking for preys.
Definition: PredatorPreyPlant.hh:326
void move_prey_to_nb_cell(const std::shared_ptr< Cell > &cell, const std::shared_ptr< Cell > &nb_cell)
Move a prey to a neighboring cell.
Definition: PredatorPreyPlant.hh:266
void move_entities(std::shared_ptr< Cell > cell)
Define the movement rule of an individual.
Definition: PredatorPreyPlant.hh:370
std::size_t _num_moves
How many cells the movement rule should be applied to each time step.
Definition: PredatorPreyPlant.hh:162
Rule _reproduce
Define the reproduction rule.
Definition: PredatorPreyPlant.hh:470
const std::shared_ptr< DataSet > _dset_resource_predator
Dataset of Predator resources on the grid.
Definition: PredatorPreyPlant.hh:196
void write_data()
Write data.
Definition: PredatorPreyPlant.hh:768
Rule _cost_of_living
Cost of Living.
Definition: PredatorPreyPlant.hh:209
SpeciesParams _params
All species-specific parameters.
Definition: PredatorPreyPlant.hh:159
typename CellManager::Cell Cell
The type of a cell.
Definition: PredatorPreyPlant.hh:143
Rule _eat
Define the eating rule.
Definition: PredatorPreyPlant.hh:431
std::shared_ptr< Cell > get_random_neighbor(const CellContainer< Cell > &nbs) const
Returns a random neighbor.
Definition: PredatorPreyPlant.hh:241
CellContainer< Cell > _empty_cell
A container to temporarily accumulate empty neighbour cells.
Definition: PredatorPreyPlant.hh:169
YAML::Node Config
Type of a variadic dictionary-like data structure used throughout Utopia.
Definition: types.hh:71
std::string to_string(const Config &node)
Given a config node, returns a string representation of it.
Definition: cfg_utils.hh:110
std::mt19937 rng
– Type definitions ----------------------------------------------------—
Definition: test_revision.cc:17
ModelTypes<> ModelTypes
Typehelper to define data types of PredatorPreyPlant model.
Definition: PredatorPreyPlant.hh:110
@ none
Plant level is ignored; prey are always able to eat.
@ stochastic
Once eaten, a plant regrows with probability regen_prob
@ deterministic
Once eaten, a plant requires regen_time time to regenerate.
Definition: agent.hh:11
EntityContainer< CellType > CellContainer
Type of the variably sized container for cells.
Definition: types.hh:26
The entity traits struct gathers types to be used for specializing an entity.
Definition: entity.hh:49
double resource_intake
Resource intake from eating.
Definition: species.hh:33
double repro_cost
Cost of reproduction.
Definition: species.hh:43
double resource_max
Maximal resource level.
Definition: species.hh:39
double cost_of_living
Cost of living that is taken each time step.
Definition: species.hh:30
double repro_resource_requ
Minimal reproduction resources requirements.
Definition: species.hh:36
double repro_prob
Reproduction probability.
Definition: species.hh:46
Struct that holds all species states.
Definition: species.hh:11
double resources
The internal resources reservoir.
Definition: species.hh:16
bool on_cell
Whether the species is on the cell.
Definition: species.hh:13
const unsigned int regen_time
The deterministic regeneration time.
Definition: species.hh:44
const GrowthModel growth_model
The growth model of the plant.
Definition: species.hh:41
const double regen_prob
The regeneration probability, evaluated each time step.
Definition: species.hh:47
Struct that holds all plant characterising states.
Definition: species.hh:12
bool on_cell
Whether a plant is on the cell.
Definition: species.hh:14
double p_flee
Probability to flee from a predator if on the same cell.
Definition: species.hh:116
unsigned int move_limit
Movement limit.
Definition: species.hh:75
The parameter of all species.
Definition: species.hh:143
PreyParams prey
Prey parameters.
Definition: species.hh:145
PlantParams plant
Plant parameters.
Definition: species.hh:151
PredatorParams predator
Predator parameters.
Definition: species.hh:148
Cell state, combining states for predator, prey and plant species.
Definition: PredatorPreyPlant.hh:23
PredatorPrey::SpeciesState prey
The state a prey on this cell has.
Definition: PredatorPreyPlant.hh:28
PlantState plant
The state a plant on this cell has.
Definition: PredatorPreyPlant.hh:31
State(const DataIO::Config &cfg, const std::shared_ptr< RNGType > &rng)
Construct a cell state with the use of a RNG.
Definition: PredatorPreyPlant.hh:35
PredatorPrey::SpeciesState predator
The state a predator on this cell has.
Definition: PredatorPreyPlant.hh:25