Utopia 2
Framework for studying models of complex & adaptive systems.
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Private Member Functions | Private Attributes | List of all members
Utopia::Models::PredatorPreyPlant::PredatorPreyPlant Class Reference

PredatorPreyPlant Model on grid cells. More...

#include <PredatorPreyPlant.hh>

Inheritance diagram for Utopia::Models::PredatorPreyPlant::PredatorPreyPlant:
Inheritance graph
[legend]
Collaboration diagram for Utopia::Models::PredatorPreyPlant::PredatorPreyPlant:
Collaboration graph
[legend]

Public Types

using Base = Model< PredatorPreyPlant, ModelTypes >
 The base model.
 
using DataSet = typename Base::DataSet
 Data type for a dataset.
 
using CellManager = Utopia::CellManager< CellTraits, PredatorPreyPlant >
 The type of the cell manager.
 
using Cell = typename CellManager::Cell
 The type of a cell.
 
using Rule = typename CellManager::RuleFunc
 Type of the update rules.
 
- Public Types inherited from Utopia::Model< PredatorPreyPlant, ModelTypes >
using Config = typename ModelTypes::Config
 Data type that holds the configuration.
 
using DataManager = DataIO::Default::DefaultDataManager< PredatorPreyPlant >
 The data manager to use, specialized with the derived model.
 
using DataGroup = typename ModelTypes::DataGroup
 Data type that is used for storing datasets.
 
using DataSet = typename ModelTypes::DataSet
 Data type that is used for storing data.
 
using RNG = typename ModelTypes::RNG
 Data type of the shared RNG.
 
using Space = typename ModelTypes::Space
 Data type of the space this model resides in.
 
using Time = typename ModelTypes::Time
 Data type for the model time.
 
using Monitor = typename ModelTypes::Monitor
 Data type for the monitor.
 
using MonitorManager = typename ModelTypes::MonitorManager
 Data type for the monitor manager.
 
using Level = typename ModelTypes::Level
 Data type for the hierarchical level.
 

Public Member Functions

template<class ParentModel >
 PredatorPreyPlant (const std::string &name, ParentModel &parent_model, const DataIO::Config &custom_cfg={})
 Construct the PredatorPreyPlant model.
 
void perform_step ()
 Perform an iteration step.
 
void monitor ()
 Monitor model information.
 
void write_data ()
 Write data.
 
- Public Member Functions inherited from Utopia::Model< PredatorPreyPlant, ModelTypes >
 Model (const std::string &name, const ParentModel &parent_model, const Config &custom_cfg={}, std::tuple< WriterArgs... > w_args={}, const DataIO::Default::DefaultDecidermap< PredatorPreyPlant > &w_deciders=DataIO::Default::default_deciders< PredatorPreyPlant >, const DataIO::Default::DefaultTriggermap< PredatorPreyPlant > &w_triggers=DataIO::Default::default_triggers< PredatorPreyPlant >)
 Constructs a Model instance.
 
const std::shared_ptr< Space > & get_space () const
 Return the space this model resides in.
 
Time get_time () const
 Return the current time of this model.
 
Time get_time_max () const
 Return the maximum time possible for this model.
 
Config get_cfg () const
 Return the config node of this model.
 
std::string get_name () const
 Return the name of this model instance.
 
std::string get_full_name () const
 Return the full name of this model within the model hierarchy.
 
std::shared_ptr< DataGroupget_hdfgrp () const
 Return a pointer to the HDF group this model stores data in.
 
Time get_write_start () const
 Return the parameter that controls when write_data is called first.
 
Time get_write_every () const
 Return the parameter that controls how often write_data is called.
 
DataManager get_datamanager () const
 return the datamanager
 
hsize_t get_remaining_num_writes () const
 Return the number of remaining write_data calls this model will make.
 
std::shared_ptr< RNGget_rng () const
 Return a pointer to the shared RNG.
 
std::shared_ptr< spdlog::logger > get_logger () const
 Return a pointer to the logger of this model.
 
Monitor get_monitor () const
 Return the monitor of this model.
 
std::shared_ptr< MonitorManagerget_monitor_manager () const
 Get the monitor manager of the root model.
 
Level get_level () const
 Return the hierarchical level within the model hierarchy.
 
virtual void prolog ()
 A function that is called before starting model iteration.
 
virtual void epilog ()
 A function that is called after the last iteration of a model.
 
void iterate ()
 Iterate one (time) step of this model.
 
void run ()
 Run the model from the current time to the maximum time.
 
std::shared_ptr< DataSetcreate_dset (const std::string name, const std::shared_ptr< DataGroup > &hdfgrp, std::vector< hsize_t > add_write_shape, const std::size_t compression_level=1, const std::vector< hsize_t > chunksize={})
 Create a new dataset within the given group.
 
std::shared_ptr< DataSetcreate_dset (const std::string name, const std::vector< hsize_t > add_write_shape, const std::size_t compression_level=1, const std::vector< hsize_t > chunksize={})
 Create a new dataset within the model's base data group.
 
std::shared_ptr< DataSetcreate_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.
 
std::shared_ptr< DataSetcreate_am_dset (const std::string name, const AgentManager &am, const std::size_t compression_level=1, const std::vector< hsize_t > chunksize={})
 Create a dataset storing data from a AgentManager.
 

Private Member Functions

std::shared_ptr< Cellget_random_neighbor (const CellContainer< Cell > &nbs) const
 Returns a random neighbor.
 
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.
 
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.
 
auto move_prey (std::shared_ptr< Cell > cell)
 Move the prey looking for resources.
 
auto move_predator (std::shared_ptr< Cell > cell)
 Move the predator looking for preys.
 
void move_entities (std::shared_ptr< Cell > cell)
 Define the movement rule of an individual.
 
void setup_cell_states_from_file (const Config &cs_cfg)
 Sets predator, prey, and plant positions from loaded HDF5 data.
 

Private Attributes

CellManager _cm
 The cell manager.
 
SpeciesParams _params
 All species-specific parameters.
 
std::size_t _num_moves
 How many cells the movement rule should be applied to each time step.
 
CellContainer< Cell_prey_cell
 A container to temporarily accumulate the prey neighbour cells.
 
CellContainer< Cell_empty_cell
 A container to temporarily accumulate empty neighbour cells.
 
CellContainer< Cell_repro_cell
 A container to temporarily accumulate neighbour cells for reproduction.
 
CellContainer< Cell_resource_cell
 A container to temporarily accumulate neighbour cells with mature plants.
 
std::uniform_real_distribution< double_prob_distr
 Uniform real distribution [0, 1) for evaluating probabilities.
 
std::uniform_int_distribution _cm_dist
 Distribution for randomly selecting a cell in your cellmanager.
 
const std::shared_ptr< DataSet_dset_prey
 Dataset of Prey locations on the grid.
 
const std::shared_ptr< DataSet_dset_predator
 Dataset of Predator locations on the grid.
 
const std::shared_ptr< DataSet_dset_resource_prey
 Dataset of Prey resources on the grid.
 
const std::shared_ptr< DataSet_dset_resource_predator
 Dataset of Predator resources on the grid.
 
const std::shared_ptr< DataSet_dset_plant
 Dataset of Plant resources.
 
Rule _cost_of_living
 Cost of Living.
 
Rule _flee_prey
 If a prey is on the cell, determine whether it may flee and where to.
 
Rule _eat
 Define the eating rule.
 
Rule _reproduce
 Define the reproduction rule.
 

Additional Inherited Members

- Protected Member Functions inherited from Utopia::Model< PredatorPreyPlant, ModelTypes >
void __perform_step ()
 Perform the computation of a step.
 
void __monitor ()
 Monitor information in the terminal.
 
void __write_data ()
 Write data; calls the implementation's write_data method.
 
void __write_initial_state ()
 Write the initial state.
 
void increment_time (const Time dt=1)
 Increment time.
 
void __prolog ()
 The default prolog of a model.
 
void __epilog ()
 The default epilog of a model.
 
PredatorPreyPlant & impl ()
 cast to the derived class
 
const PredatorPreyPlant & impl () const
 const cast to the derived interface
 
- Protected Attributes inherited from Utopia::Model< PredatorPreyPlant, ModelTypes >
const std::string _name
 Name of the model instance.
 
const std::string _full_name
 The full name within the model hierarchy.
 
const Level _level
 The level within the model hierarchy.
 
const Config _cfg
 Config node belonging to this model instance.
 
const std::shared_ptr< RNG_rng
 The RNG shared between models.
 
const std::shared_ptr< spdlog::logger > _log
 The (model) logger.
 
std::shared_ptr< Space_space
 The space this model resides in.
 
Time _time
 Model-internal current time stamp.
 
const Time _time_max
 Model-internal maximum time stamp.
 
const std::shared_ptr< DataGroup_hdfgrp
 The HDF group this model instance should write its data to.
 
const Time _write_start
 First time at which write_data is called.
 
const Time _write_every
 How often to call write_data from iterate.
 
Monitor _monitor
 The monitor.
 
DataManager _datamanager
 Manager object for handling data output; see DataManager.
 
- Static Protected Attributes inherited from Utopia::Model< PredatorPreyPlant, ModelTypes >
static constexpr WriteMode _write_mode
 Which data-writing mode the base model should use.
 

Detailed Description

PredatorPreyPlant Model on grid cells.

Predators and prey correspond to the Population state of each cell, either empty, prey, predator or both. Cells are updated based on the following interactions: 1) resource levels are reduced by a cost_of_living for both species and individuals are removed if resource <= 0 2) predators move to neighbouring cells if there is a no prey on their own cell. Prey flees with a certain probability, if there is a predator on the same cell. Prey looks for resources if there are none on its cell. 3) predators eat prey if on the same cell, else if there is only a prey it takes up resources, when this are present 4) both predators and prey reproduce if resources are sufficient and if there is a cell in their neighbourhood not already occupied by the same species. The plant grows if it is set in mode other than 0.

Member Typedef Documentation

◆ Base

The base model.

◆ Cell

The type of a cell.

◆ CellManager

The type of the cell manager.

◆ DataSet

Data type for a dataset.

◆ Rule

Type of the update rules.

Constructor & Destructor Documentation

◆ PredatorPreyPlant()

template<class ParentModel >
Utopia::Models::PredatorPreyPlant::PredatorPreyPlant::PredatorPreyPlant ( const std::string &  name,
ParentModel parent_model,
const DataIO::Config custom_cfg = {} 
)
inline

Construct the PredatorPreyPlant model.

Parameters
nameName of this model instance; is used to extract the configuration from the parent model and set up a HDFGroup for this instance
parent_modelThe parent model this model instance resides in
custom_cfgA custom configuration to use instead of the one extracted from the parent model using the instance name
549 {}
550 )
551 :
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 }
auto nb_size() const
Return the (maximum) size of the currently selected neighborhood.
Definition cell_manager.hh:450
const CellContainer< Cell > & cells() const
Return const reference to the managed CA cells.
Definition cell_manager.hh:219
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
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
const std::shared_ptr< spdlog::logger > _log
The (model) logger.
Definition model.hh:164
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
const std::shared_ptr< DataSet > _dset_predator
Dataset of Predator locations on the grid.
Definition PredatorPreyPlant.hh:190
CellManager _cm
The cell manager.
Definition PredatorPreyPlant.hh:155
std::uniform_int_distribution _cm_dist
Distribution for randomly selecting a cell in your cellmanager.
Definition PredatorPreyPlant.hh:182
const std::shared_ptr< DataSet > _dset_prey
Dataset of Prey locations on the grid.
Definition PredatorPreyPlant.hh:187
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
std::size_t _num_moves
How many cells the movement rule should be applied to each time step.
Definition PredatorPreyPlant.hh:162
const std::shared_ptr< DataSet > _dset_resource_predator
Dataset of Predator resources on the grid.
Definition PredatorPreyPlant.hh:196
SpeciesParams _params
All species-specific parameters.
Definition PredatorPreyPlant.hh:159
CellContainer< Cell > _empty_cell
A container to temporarily accumulate empty neighbour cells.
Definition PredatorPreyPlant.hh:169
Container select_entities(const Manager &mngr, const DataIO::Config &sel_cfg)
Select entities according to parameters specified in a configuration.
Definition select.hh:213

Member Function Documentation

◆ get_random_neighbor()

std::shared_ptr< Cell > Utopia::Models::PredatorPreyPlant::PredatorPreyPlant::get_random_neighbor ( const CellContainer< Cell > &  nbs) const
inlineprivate

Returns a random neighbor.

This method chooses uniform randomly a cell from the neighborhood of the given cell.

242 {
243 return nbs[std::uniform_int_distribution<std::size_t>(0, nbs.size() - 1)(*this->_rng)];
244 }
const std::shared_ptr< RNG > _rng
The RNG shared between models.
Definition model.hh:161

◆ monitor()

void Utopia::Models::PredatorPreyPlant::PredatorPreyPlant::monitor ( )
inline

Monitor model information.

734 {
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 }
Monitor _monitor
The monitor.
Definition model.hh:188

◆ move_entities()

void Utopia::Models::PredatorPreyPlant::PredatorPreyPlant::move_entities ( std::shared_ptr< Cell cell)
inlineprivate

Define the movement rule of an individual.

370 {
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 {
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)
386 }
387 };
auto move_prey(std::shared_ptr< Cell > cell)
Move the prey looking for resources.
Definition PredatorPreyPlant.hh:287
auto move_predator(std::shared_ptr< Cell > cell)
Move the predator looking for preys.
Definition PredatorPreyPlant.hh:326
unsigned int move_limit
Movement limit.
Definition species.hh:75
PreyParams prey
Prey parameters.
Definition species.hh:145
PredatorParams predator
Predator parameters.
Definition species.hh:148

◆ move_predator()

auto Utopia::Models::PredatorPreyPlant::PredatorPreyPlant::move_predator ( std::shared_ptr< Cell cell)
inlineprivate

Move the predator looking for preys.

Predators looks for prey in the neighborhood. If there are multiple cells with prey on them randomly choose one cell to move to. If there is no cell with prey just do a movement towards a randomly selected neighboring cell. A predator can never move to a cell with another predator on it.

326 {
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
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
354 return nb_cell;
355 }
356 }
357 return cell;
358 };
CellContainer< Cell > neighbors_of(const Cell &cell) const
Retrieve the given cell's neighbors.
Definition cell_manager.hh:458
std::shared_ptr< Cell > get_random_neighbor(const CellContainer< Cell > &nbs) const
Returns a random neighbor.
Definition PredatorPreyPlant.hh:241
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

◆ move_predator_to_nb_cell()

void Utopia::Models::PredatorPreyPlant::PredatorPreyPlant::move_predator_to_nb_cell ( const std::shared_ptr< Cell > &  cell,
const std::shared_ptr< Cell > &  nb_cell 
)
inlineprivate

Move a predator to a neighboring cell.

This function resets the states predator state and updates the neighboring predator state.

251 {
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 }

◆ move_prey()

auto Utopia::Models::PredatorPreyPlant::PredatorPreyPlant::move_prey ( std::shared_ptr< Cell cell)
inlineprivate

Move the prey looking for resources.

If plants are enabled, prey might need to look for available resources in the form of plants in the neighboring cells. If there is a plant on a neighboring cell and no predator, the prey will move there. If there are multiple cells with plants on them, one is selected at random. If there are no free cells just take your chance and randomly select a cell, if there is a predator on it nevertheless move to it.

287 {
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)];
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) {
312 return nb_cell;
313 }
314 return cell;
315 }
316 };
CellContainer< Cell > _resource_cell
A container to temporarily accumulate neighbour cells with mature plants.
Definition PredatorPreyPlant.hh:175
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

◆ move_prey_to_nb_cell()

void Utopia::Models::PredatorPreyPlant::PredatorPreyPlant::move_prey_to_nb_cell ( const std::shared_ptr< Cell > &  cell,
const std::shared_ptr< Cell > &  nb_cell 
)
inlineprivate

Move a prey to a neighboring cell.

This function resets the states prey state and updates the neighboring prey state.

267 {
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 }

◆ perform_step()

void Utopia::Models::PredatorPreyPlant::PredatorPreyPlant::perform_step ( )
inline

Perform an iteration step.

An iteration step consists of:

  1. Subtracting costs of living
  2. Let predator and prey move
  3. Lunch time: Prey eats grass and predator eats prey if on the same cell
  4. Reproduction: Create offspring and grow plant
718 {
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 }
727 *this->_rng);
730 *this->_rng);
731 }
Rule _flee_prey
If a prey is on the cell, determine whether it may flee and where to.
Definition PredatorPreyPlant.hh:397
void move_entities(std::shared_ptr< Cell > cell)
Define the movement rule of an individual.
Definition PredatorPreyPlant.hh:370
Rule _reproduce
Define the reproduction rule.
Definition PredatorPreyPlant.hh:470
Rule _cost_of_living
Cost of Living.
Definition PredatorPreyPlant.hh:209
Rule _eat
Define the eating rule.
Definition PredatorPreyPlant.hh:431

◆ setup_cell_states_from_file()

void Utopia::Models::PredatorPreyPlant::PredatorPreyPlant::setup_cell_states_from_file ( const Config cs_cfg)
inlineprivate

Sets predator, prey, and plant positions from loaded HDF5 data.

603 {
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"]);
624 get_as<int>("min_init_resources",
627 get_as<int>("max_init_resources",
629 std::uniform_int_distribution<>
633 );
634 cell->state.predator.resources =
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"]);
664 get_as<int>("min_init_resources", prey_cfg);
666 get_as<int>("max_init_resources", prey_cfg);
667 std::uniform_int_distribution<>
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 }
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

◆ write_data()

void Utopia::Models::PredatorPreyPlant::PredatorPreyPlant::write_data ( )
inline

Write data.

When invoked, stores cell positions and resources of both prey and predators.

Note
Positions are cast to char and therefore stored as such. This is because C has no native boolean type, and the HDF5 library thus cannot store it directly. With 8 bit width, char is the smallest data type available; short int is already 16 bit.
768 {
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 }

Member Data Documentation

◆ _cm

CellManager Utopia::Models::PredatorPreyPlant::PredatorPreyPlant::_cm
private

The cell manager.

◆ _cm_dist

std::uniform_int_distribution Utopia::Models::PredatorPreyPlant::PredatorPreyPlant::_cm_dist
private

Distribution for randomly selecting a cell in your cellmanager.

◆ _cost_of_living

Rule Utopia::Models::PredatorPreyPlant::PredatorPreyPlant::_cost_of_living
private
Initial value:
= [this](const auto& cell) {
auto& state = cell->state;
state.predator.resources =
std::clamp( state.predator.resources
state.prey.resources =
std::clamp( state.prey.resources
if (state.predator.on_cell and state.predator.resources <= 0.)
state.predator.on_cell = false;
if (state.prey.on_cell and state.prey.resources <= 0.)
state.prey.on_cell = false;
return state;
}
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

Cost of Living.

subtract the cost of living from the resources of an individual and map the values below zero back to zero, then remove all individuals that do not have sufficient resources. This function applies only to predator and prey, but not to plants.

209 {
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 };

◆ _dset_plant

const std::shared_ptr<DataSet> Utopia::Models::PredatorPreyPlant::PredatorPreyPlant::_dset_plant
private

Dataset of Plant resources.

◆ _dset_predator

const std::shared_ptr<DataSet> Utopia::Models::PredatorPreyPlant::PredatorPreyPlant::_dset_predator
private

Dataset of Predator locations on the grid.

◆ _dset_prey

const std::shared_ptr<DataSet> Utopia::Models::PredatorPreyPlant::PredatorPreyPlant::_dset_prey
private

Dataset of Prey locations on the grid.

◆ _dset_resource_predator

const std::shared_ptr<DataSet> Utopia::Models::PredatorPreyPlant::PredatorPreyPlant::_dset_resource_predator
private

Dataset of Predator resources on the grid.

◆ _dset_resource_prey

const std::shared_ptr<DataSet> Utopia::Models::PredatorPreyPlant::PredatorPreyPlant::_dset_resource_prey
private

Dataset of Prey resources on the grid.

◆ _eat

Rule Utopia::Models::PredatorPreyPlant::PredatorPreyPlant::_eat
private

Define the eating rule.

Update procedure is as follows:

  • prey is consumed by a predator if they are on the same cell. The predator increases its resources.
  • prey eats plants which increases its resources; if the plant growth model is not none the plant is removed from the cell.
431 {
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 };
@ none
Plant level is ignored; prey are always able to eat.
double resource_intake
Resource intake from eating.
Definition species.hh:33
const GrowthModel growth_model
The growth model of the plant.
Definition species.hh:41
PlantParams plant
Plant parameters.
Definition species.hh:151

◆ _empty_cell

CellContainer<Cell> Utopia::Models::PredatorPreyPlant::PredatorPreyPlant::_empty_cell
private

A container to temporarily accumulate empty neighbour cells.

◆ _flee_prey

Rule Utopia::Models::PredatorPreyPlant::PredatorPreyPlant::_flee_prey
private
Initial value:
= [this](const auto& cell) {
auto& state = cell->state;
if (state.prey.on_cell and state.predator.on_cell and
_empty_cell.clear();
for (const auto& nb : this->_cm.neighbors_of(cell)) {
if ( not nb->state.prey.on_cell
and not nb->state.predator.on_cell)
_empty_cell.push_back(nb);
}
if (_empty_cell.size() > 0) {
std::uniform_int_distribution<>
dist(0, _empty_cell.size() - 1);
auto nb_cell = _empty_cell[dist(*this->_rng)];
}
}
return state;
}
double p_flee
Probability to flee from a predator if on the same cell.
Definition species.hh:116

If a prey is on the cell, determine whether it may flee and where to.

A prey should only flee if there is a predator on the cell, too. First empty neighboring cells are collected to which a prey can potentially flee. Choose a random cell out of the selection to flee to. If there is no empty cell nothing happens.

397 {
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)];
417 }
418 }
419 return state;
420 };

◆ _num_moves

std::size_t Utopia::Models::PredatorPreyPlant::PredatorPreyPlant::_num_moves
private

How many cells the movement rule should be applied to each time step.

◆ _params

SpeciesParams Utopia::Models::PredatorPreyPlant::PredatorPreyPlant::_params
private

All species-specific parameters.

◆ _prey_cell

CellContainer<Cell> Utopia::Models::PredatorPreyPlant::PredatorPreyPlant::_prey_cell
private

A container to temporarily accumulate the prey neighbour cells.

◆ _prob_distr

std::uniform_real_distribution<double> Utopia::Models::PredatorPreyPlant::PredatorPreyPlant::_prob_distr
private

Uniform real distribution [0, 1) for evaluating probabilities.

◆ _repro_cell

CellContainer<Cell> Utopia::Models::PredatorPreyPlant::PredatorPreyPlant::_repro_cell
private

A container to temporarily accumulate neighbour cells for reproduction.

◆ _reproduce

Rule Utopia::Models::PredatorPreyPlant::PredatorPreyPlant::_reproduce
private

Define the reproduction rule.

If a neighboring cell if not already occupied by an individual of the same species, individuals reproduce with reproduction probabilities of predator and prey respectively. Plants reproduce according to their GrowthMode.

470 {
471 auto& state = cell->state;
472
473 // Reproduction of predators
474 if ( state.predator.on_cell
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 };
@ stochastic
Once eaten, a plant regrows with probability regen_prob
@ deterministic
Once eaten, a plant requires regen_time time to regenerate.
double repro_cost
Cost of reproduction.
Definition species.hh:43
double repro_resource_requ
Minimal reproduction resources requirements.
Definition species.hh:36
double repro_prob
Reproduction probability.
Definition species.hh:46
const unsigned int regen_time
The deterministic regeneration time.
Definition species.hh:44
const double regen_prob
The regeneration probability, evaluated each time step.
Definition species.hh:47

◆ _resource_cell

CellContainer<Cell> Utopia::Models::PredatorPreyPlant::PredatorPreyPlant::_resource_cell
private

A container to temporarily accumulate neighbour cells with mature plants.


The documentation for this class was generated from the following file: