1 #ifndef UTOPIA_MODELS_SANDPILE_HH
2 #define UTOPIA_MODELS_SANDPILE_HH
34 template<
typename RNG>
40 const auto initial_slope_lower_limit =
41 get_as<Slope>(
"initial_slope_lower_limit", cfg);
43 const auto initial_slope_upper_limit =
44 get_as<Slope>(
"initial_slope_upper_limit", cfg);
47 if (initial_slope_upper_limit <= initial_slope_lower_limit) {
48 throw std::invalid_argument(
"The `inital_slope_*_limit` "
49 "parameters need to specify a valid range, i.e. with `lower` "
50 "being strictly smaller than the `upper`!");
55 std::uniform_int_distribution<Slope>
56 dist(initial_slope_lower_limit, initial_slope_upper_limit);
85 public Model<SandPile, SandPileTypes>
158 template<
class ParentModel>
160 const std::string& name,
161 ParentModel& parent_model,
166 Base(name, parent_model, custom_cfg),
177 get_as<bool>(
"write_only_avalanche_size",
_cfg,
false)
190 throw std::invalid_argument(
191 "Other neighborhoods than vonNeumann are not supported!"
202 this->
_log->info(
"Adding first grain of sand and letting topple ...");
203 this->
_log->debug(
"Toppling size: {}", _topple_num_grains);
206 this->
_log->info(
"With {} cells, this may take a while ...",
212 this->
_log->info(
"{} all set up.", this->
_name);
226 [](
unsigned int sum,
const auto& cell){
227 if (cell->state.in_avalanche) {
239 auto& cell = _cm.
cells()[_cell_distr(*this->_rng)];
242 this->_log->trace(
"Adding grain of sand to cell {} ...", cell->id());
243 cell->state.slope += 1;
248 cell->state.in_avalanche =
true;
263 void topple(
const std::shared_ptr<Cell>& first_cell) {
264 this->_log->trace(
"Now toppling all supercritical cells ...");
267 std::queue<std::shared_ptr<Cell>> queue;
268 queue.push(first_cell);
270 while (not queue.empty()) {
273 const auto& cell = queue.front();
274 auto& state = cell->state;
279 if (state.slope > _critical_slope) {
280 state.slope -= _topple_num_grains;
281 state.in_avalanche =
true;
286 auto& nb_slope = nb->state.slope;
288 if (nb_slope > _critical_slope){
304 cell->state.in_avalanche =
false;
316 apply_rule<Update::async, Shuffle::off>(_reset, _cm.
cells());
320 topple(add_sand_grain());
329 this->_monitor.set_entry(
"avalanche_size", avalanche_size());
340 _dset_avalanche_size->write(avalanche_size());
342 if (_write_only_avalanche_size) {
347 _dset_slope->write(_cm.
cells().begin(), _cm.
cells().end(),
348 [](
const auto& cell) {
349 return cell->state.slope;
356 _dset_avalanche->write(_cm.
cells().begin(), _cm.
cells().end(),
357 [](
const auto& cell) {
358 return static_cast<char>(cell->state.in_avalanche);
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
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
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
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< spdlog::logger > _log
The (model) logger.
Definition: model.hh:164
The SandPile Model.
Definition: SandPile.hh:86
const std::shared_ptr< DataSet > _dset_avalanche_size
Dataset to store the avalanche size for each time step.
Definition: SandPile.hh:144
void write_data()
Write the cell slope and avalanche flag to the datasets.
Definition: SandPile.hh:338
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
std::vector< std::shared_ptr< Cell > > CellContainer
Cell container type.
Definition: SandPile.hh:98
const std::shared_ptr< DataSet > _dset_avalanche
Dataset to store the avalanche state of all cells for all time steps.
Definition: SandPile.hh:141
typename Base::DataSet DataSet
Data type for a dataset.
Definition: SandPile.hh:104
CellManager _cm
The grid manager.
Definition: SandPile.hh:116
typename std::uniform_int_distribution< std::size_t > UniformIntDist
The uniform integer distribution type to use.
Definition: SandPile.hh:107
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
typename CellManager::RuleFunc RuleFunc
Supply a type for rule functions that are applied to cells.
Definition: SandPile.hh:101
typename CellManager::Cell Cell
Cell type.
Definition: SandPile.hh:95
unsigned int avalanche_size() const
Calculate the avalanche size.
Definition: SandPile.hh:222
SandPile(const std::string &name, ParentModel &parent_model, const DataIO::Config &custom_cfg={})
Construct the SandPile model.
Definition: SandPile.hh:159
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
UniformIntDist _cell_distr
A distribution to select a random cell.
Definition: SandPile.hh:133
void perform_step()
Perform an iteration step.
Definition: SandPile.hh:314
const std::shared_ptr< DataSet > _dset_slope
Dataset to store the slopes of all cells for all time steps.
Definition: SandPile.hh:138
void monitor()
Supply monitor information to the frontend.
Definition: SandPile.hh:327
@ vonNeumann
The vonNeumann neighborhood, i.e. only nearest neighbors.
YAML::Node Config
Type of a variadic dictionary-like data structure used throughout Utopia.
Definition: types.hh:71
std::mt19937 rng
– Type definitions ----------------------------------------------------—
Definition: test_revision.cc:17
unsigned int Slope
Type of the slope.
Definition: SandPile.hh:20
The entity traits struct gathers types to be used for specializing an entity.
Definition: entity.hh:49
Wrapper struct for defining model class data types.
Definition: model.hh:92
Cell State for the SandPile model.
Definition: SandPile.hh:23
Slope slope
The current value of the slope.
Definition: SandPile.hh:25
bool in_avalanche
Whether the cell was touched by an avalanche; useful for updating.
Definition: SandPile.hh:28
State()=delete
Default constructor.
State(const DataIO::Config &cfg, const std::shared_ptr< RNG > &rng)
Configuration based constructor.
Definition: SandPile.hh:35