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::SandPile::SandPile Class Reference

The SandPile Model. More...

#include <SandPile.hh>

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

Public Types

using Base = Model< SandPile, SandPileTypes >
 The base model's type.
 
using CellManager = Utopia::CellManager< CellTraits, SandPile >
 The type of the cell manager.
 
using Cell = typename CellManager::Cell
 Cell type.
 
using CellContainer = std::vector< std::shared_ptr< Cell > >
 Cell container type.
 
using RuleFunc = typename CellManager::RuleFunc
 Supply a type for rule functions that are applied to cells.
 
using DataSet = typename Base::DataSet
 Data type for a dataset.
 
using UniformIntDist = typename std::uniform_int_distribution< std::size_t >
 The uniform integer distribution type to use.
 
- Public Types inherited from Utopia::Model< SandPile, SandPileTypes >
using Config = typename ModelTypes::Config
 Data type that holds the configuration.
 
using DataManager = DataIO::Default::DefaultDataManager< SandPile >
 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 >
 SandPile (const std::string &name, ParentModel &parent_model, const DataIO::Config &custom_cfg={})
 Construct the SandPile model.
 
void perform_step ()
 Perform an iteration step.
 
void monitor ()
 Supply monitor information to the frontend.
 
void write_data ()
 Write the cell slope and avalanche flag to the datasets.
 
- Public Member Functions inherited from Utopia::Model< SandPile, SandPileTypes >
 Model (const std::string &name, const ParentModel &parent_model, const Config &custom_cfg={}, std::tuple< WriterArgs... > w_args={}, const DataIO::Default::DefaultDecidermap< SandPile > &w_deciders=DataIO::Default::default_deciders< SandPile >, const DataIO::Default::DefaultTriggermap< SandPile > &w_triggers=DataIO::Default::default_triggers< SandPile >)
 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

unsigned int avalanche_size () const
 Calculate the avalanche size.
 
const std::shared_ptr< Cell > & add_sand_grain ()
 Select a random cell, add a grain of sand to it, and return it.
 
void topple (const std::shared_ptr< Cell > &first_cell)
 Topple cells if the critical slope is exceeded.
 

Private Attributes

CellManager _cm
 The grid manager.
 
const Slope _critical_slope
 The critical slope of the cells.
 
const unsigned int _topple_num_grains
 The number of grains that topple; depends on the neighborhood size.
 
const bool _write_only_avalanche_size
 If true, will only store the avalanche size, not the spatial data.
 
UniformIntDist _cell_distr
 A distribution to select a random cell.
 
const std::shared_ptr< DataSet_dset_slope
 Dataset to store the slopes of all cells for all time steps.
 
const std::shared_ptr< DataSet_dset_avalanche
 Dataset to store the avalanche state of all cells for all time steps.
 
const std::shared_ptr< DataSet_dset_avalanche_size
 Dataset to store the avalanche size for each time step.
 
RuleFunc _reset
 Resets cells for the next iteration.
 

Additional Inherited Members

- Protected Member Functions inherited from Utopia::Model< SandPile, SandPileTypes >
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.
 
SandPile & impl ()
 cast to the derived class
 
const SandPile & impl () const
 const cast to the derived interface
 
- Protected Attributes inherited from Utopia::Model< SandPile, SandPileTypes >
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< SandPile, SandPileTypes >
static constexpr WriteMode _write_mode
 Which data-writing mode the base model should use.
 

Detailed Description

The SandPile Model.

The SandPile model simulates a sand pile under the influence of new grains of sand that get added every iteration. The sand reaches a critical state _critical_slope, after which it collapses, passing sand on to the neighboring cells

Member Typedef Documentation

◆ Base

The base model's type.

◆ Cell

Cell type.

◆ CellContainer

Cell container type.

◆ CellManager

The type of the cell manager.

◆ DataSet

Data type for a dataset.

◆ RuleFunc

Supply a type for rule functions that are applied to cells.

◆ UniformIntDist

using Utopia::Models::SandPile::SandPile::UniformIntDist = typename std::uniform_int_distribution<std::size_t>

The uniform integer distribution type to use.

Constructor & Destructor Documentation

◆ SandPile()

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

Construct the SandPile 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
162 {}
163 )
164 :
165 // Initialize first via base model
167
168 // Initialize the cell manager, binding it to this model
169 _cm(*this),
170
171 // Initialize other class members
172 _critical_slope(get_as<Slope>("critical_slope", _cfg)),
173 _topple_num_grains(_cm.nb_size()),
174
175 // Writing-related parameters
177 get_as<bool>("write_only_avalanche_size", _cfg, false)
178 ),
179
180 // Initialize the distribution such that a random cell can be selected
181 _cell_distr(0, _cm.cells().size() - 1),
182
183 // create datasets
185 _dset_avalanche(this->create_cm_dset("avalanche", _cm)),
186 _dset_avalanche_size(this->create_dset("avalanche_size", {}))
187 {
188 // Check neighborhood mode; currently does not work with Moore
189 if (_cm.nb_mode() != NBMode::vonNeumann) {
190 throw std::invalid_argument(
191 "Other neighborhoods than vonNeumann are not supported!"
192 );
193 }
194
195 // Add a dimension label for the avalanche size dataset and store the
196 // size of the grid as attribute, allowing to compute the avalanche
197 // size area fraction without the need for spatial data
198 _dset_avalanche_size->add_attribute("dim_names", "time");
199 _dset_avalanche_size->add_attribute("num_cells", _cm.cells().size());
200
201 // Perform initial step
202 this->_log->info("Adding first grain of sand and letting topple ...");
203 this->_log->debug("Toppling size: {}", _topple_num_grains);
204
205 if (_cm.cells().size() > 4000) {
206 this->_log->info("With {} cells, this may take a while ...",
207 _cm.cells().size());
208 }
210
211 // Done.
212 this->_log->info("{} all set up.", this->_name);
213 }
const CellContainer< Cell > & cells() const
Return const reference to the managed CA cells.
Definition cell_manager.hh:219
const NBMode & nb_mode() const
Return the currently selected neighborhood mode.
Definition cell_manager.hh:443
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
std::shared_ptr< DataSet > create_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.
Definition model.hh:752
const std::shared_ptr< DataSet > _dset_avalanche_size
Dataset to store the avalanche size for each time step.
Definition SandPile.hh:144
void topple(const std::shared_ptr< Cell > &first_cell)
Topple cells if the critical slope is exceeded.
Definition SandPile.hh:263
const unsigned int _topple_num_grains
The number of grains that topple; depends on the neighborhood size.
Definition SandPile.hh:123
const std::shared_ptr< DataSet > _dset_avalanche
Dataset to store the avalanche state of all cells for all time steps.
Definition SandPile.hh:141
CellManager _cm
The grid manager.
Definition SandPile.hh:116
const Slope _critical_slope
The critical slope of the cells.
Definition SandPile.hh:120
Model< SandPile, SandPileTypes > Base
The base model's type.
Definition SandPile.hh:89
const bool _write_only_avalanche_size
If true, will only store the avalanche size, not the spatial data.
Definition SandPile.hh:128
const std::shared_ptr< Cell > & add_sand_grain()
Select a random cell, add a grain of sand to it, and return it.
Definition SandPile.hh:237
UniformIntDist _cell_distr
A distribution to select a random cell.
Definition SandPile.hh:133
const std::shared_ptr< DataSet > _dset_slope
Dataset to store the slopes of all cells for all time steps.
Definition SandPile.hh:138
@ vonNeumann
The vonNeumann neighborhood, i.e. only nearest neighbors.
ReturnType get_as(const std::string &key, const DataIO::Config &node)
This function is a wrapper around the yaml-cpp YAML::Node::as function.
Definition cfg_utils.hh:158
Container select_entities(const Manager &mngr, const DataIO::Config &sel_cfg)
Select entities according to parameters specified in a configuration.
Definition select.hh:213
unsigned int Slope
Type of the slope.
Definition SandPile.hh:20

Member Function Documentation

◆ add_sand_grain()

const std::shared_ptr< Cell > & Utopia::Models::SandPile::SandPile::add_sand_grain ( )
inlineprivate

Select a random cell, add a grain of sand to it, and return it.

237 {
238 // Select a random cell to be modified
239 auto& cell = _cm.cells()[_cell_distr(*this->_rng)];
240
241 // Adjust that cell's state: add a grain of sand
242 this->_log->trace("Adding grain of sand to cell {} ...", cell->id());
243 cell->state.slope += 1;
244
245 // As the slope of this grain changed, it is regarded as "in avalanche"
246 // NOTE This does NOT mean that it is supercritical and that it will
247 // lead to toppling in the topple method.
248 cell->state.in_avalanche = true;
249
250 // Return the cell reference such that the topple method can use that
251 // information to do its thing
252 return cell;
253 };
const std::shared_ptr< RNG > _rng
The RNG shared between models.
Definition model.hh:161

◆ avalanche_size()

unsigned int Utopia::Models::SandPile::SandPile::avalanche_size ( ) const
inlineprivate

Calculate the avalanche size.

Counts all cells that are marked as in_avalanche.

222 {
223 return
224 std::accumulate(_cm.cells().begin(), _cm.cells().end(),
225 0,
226 [](unsigned int sum, const auto& cell){
227 if (cell->state.in_avalanche) {
228 return sum + 1;
229 }
230 return sum;
231 }
232 );
233 }

◆ monitor()

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

Supply monitor information to the frontend.

Provides 'avalanche_size' at the current time step

327 {
328 // Supply the last avalanche size to the monitor
329 this->_monitor.set_entry("avalanche_size", avalanche_size());
330 // NOTE As the monitor is called very infrequently, it is not a large
331 // overhead to re-calculate the avalanche size here; cheaper and
332 // simpler than storing it and implementing logic of whether to
333 // re-calculate it or not.
334 }
Monitor _monitor
The monitor.
Definition model.hh:188
unsigned int avalanche_size() const
Calculate the avalanche size.
Definition SandPile.hh:222

◆ perform_step()

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

Perform an iteration step.

314 {
315 // Reset cells: All cells are not touched by an avalanche
317
318 // Add a grain of sand and, starting from the cell the grain fell on,
319 // let all supercritical cells topple until a relaxed state is reached
321 }
RuleFunc _reset
Resets cells for the next iteration.
Definition SandPile.hh:303

◆ topple()

void Utopia::Models::SandPile::SandPile::topple ( const std::shared_ptr< Cell > &  first_cell)
inlineprivate

Topple cells if the critical slope is exceeded.

Starting from the first_cell, every time a cell topples the neighbors are also checked whether they need to topple. This is implemented by adding them into a queue and toppling until the queue is empty.

Parameters
first_cellThe first cell from which the topple avalanche starts
263 {
264 this->_log->trace("Now toppling all supercritical cells ...");
265
266 // Create a queue that stores all the cells that need to topple
267 std::queue<std::shared_ptr<Cell>> queue;
268 queue.push(first_cell);
269
270 while (not queue.empty()) {
271 // Get the first element from the queue, extract its state and
272 // remove it from the queue.
273 const auto& cell = queue.front();
274 auto& state = cell->state;
275 queue.pop();
276
277 // A cell will topple only if its slope is greater than the
278 // critical slope.
279 if (state.slope > _critical_slope) {
280 state.slope -= _topple_num_grains;
281 state.in_avalanche = true;
282
283 // Add grains (=slopes) to the neighbors
284 // and add only neighbors with supercritical slope to the queue
285 for (const auto& nb : _cm.neighbors_of(cell)){
286 auto& nb_slope = nb->state.slope;
287 nb_slope += 1;
289 queue.push(nb);
290 }
291 }
292 }
293 }
294 }

◆ write_data()

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

Write the cell slope and avalanche flag to the datasets.

338 {
339 // Calculate and write the avalanche size; may stop after that
341
343 return;
344 }
345
346 // Write the slope of all cells
347 _dset_slope->write(_cm.cells().begin(), _cm.cells().end(),
348 [](const auto& cell) {
349 return cell->state.slope;
350 }
351 );
352
353 // Write a mask of whether a cell was touched by an avalanche. Most
354 // feasible data type for that is char, which is the only C-native
355 // 8-bit data type and thus the only type supported by HDF5
356 _dset_avalanche->write(_cm.cells().begin(), _cm.cells().end(),
357 [](const auto& cell) {
358 return static_cast<char>(cell->state.in_avalanche);
359 }
360 );
361 }

Member Data Documentation

◆ _cell_distr

UniformIntDist Utopia::Models::SandPile::SandPile::_cell_distr
private

A distribution to select a random cell.

◆ _cm

CellManager Utopia::Models::SandPile::SandPile::_cm
private

The grid manager.

◆ _critical_slope

const Slope Utopia::Models::SandPile::SandPile::_critical_slope
private

The critical slope of the cells.

◆ _dset_avalanche

const std::shared_ptr<DataSet> Utopia::Models::SandPile::SandPile::_dset_avalanche
private

Dataset to store the avalanche state of all cells for all time steps.

◆ _dset_avalanche_size

const std::shared_ptr<DataSet> Utopia::Models::SandPile::SandPile::_dset_avalanche_size
private

Dataset to store the avalanche size for each time step.

◆ _dset_slope

const std::shared_ptr<DataSet> Utopia::Models::SandPile::SandPile::_dset_slope
private

Dataset to store the slopes of all cells for all time steps.

◆ _reset

RuleFunc Utopia::Models::SandPile::SandPile::_reset
private
Initial value:
= [](const auto& cell){
cell->state.in_avalanche = false;
return cell->state;
}

Resets cells for the next iteration.

Marks cell as untouched by the avalanche and updates the slope to the cached future slope

303 {
304 cell->state.in_avalanche = false;
305
306 return cell->state;
307 };

◆ _topple_num_grains

const unsigned int Utopia::Models::SandPile::SandPile::_topple_num_grains
private

The number of grains that topple; depends on the neighborhood size.

◆ _write_only_avalanche_size

const bool Utopia::Models::SandPile::SandPile::_write_only_avalanche_size
private

If true, will only store the avalanche size, not the spatial data.


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