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

SEIRD model on a grid. More...

#include <SEIRD.hh>

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

Public Types

using Base = Model< SEIRD, CDTypes >
 The base model type.
 
using DataGroup = typename Base::DataGroup
 Data type for a data group.
 
using DataSet = typename Base::DataSet
 Data type for a dataset.
 
using CellManager = Utopia::CellManager< CDCellTraits, SEIRD >
 Type of the CellManager to use.
 
using Cell = typename CellManager::Cell
 Type of a cell.
 
using CellContainer = Utopia::CellContainer< Cell >
 Type of a container of shared pointers to cells.
 
using RuleFunc = typename CellManager::RuleFunc
 Rule function type.
 
- Public Types inherited from Utopia::Model< SEIRD, CDTypes >
using Config = typename ModelTypes::Config
 Data type that holds the configuration.
 
using DataManager = DataIO::Default::DefaultDataManager< SEIRD >
 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 >
 SEIRD (const std::string &name, ParentModel &parent_model, const DataIO::Config &custom_cfg={})
 Construct the SEIRD model.
 
void perform_step ()
 Iterate a single time step.
 
void monitor ()
 Monitor model information.
 
void write_data ()
 Write data.
 
- Public Member Functions inherited from Utopia::Model< SEIRD, CDTypes >
 Model (const std::string &name, const ParentModel &parent_model, const Config &custom_cfg={}, std::tuple< WriterArgs... > w_args={}, const DataIO::Default::DefaultDecidermap< SEIRD > &w_deciders=DataIO::Default::default_deciders< SEIRD >, const DataIO::Default::DefaultTriggermap< SEIRD > &w_triggers=DataIO::Default::default_triggers< SEIRD >)
 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.
 

Protected Member Functions

void update_densities ()
 Update the densities array.
 
void identify_clusters ()
 Identify clusters.
 
void exposure_control ()
 Apply exposure control.
 
void immunity_control ()
 Apply immunity control.
 
void transmission_control ()
 Apply transmission control.
 
- Protected Member Functions inherited from Utopia::Model< SEIRD, CDTypes >
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.
 
SEIRD & impl ()
 cast to the derived class
 
const SEIRD & impl () const
 const cast to the derived interface
 

Protected Attributes

RuleFunc _update
 Define the update rule.
 
RuleFunc _identify_cluster
 Identify each cluster of susceptibles.
 
RuleFunc _move_away_from_infected
 Move the agent on the cell away from an infected neighboring cell.
 
RuleFunc _move_randomly
 Move randomly to a neighboring cell if that cell is empty.
 
- Protected Attributes inherited from Utopia::Model< SEIRD, CDTypes >
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.
 

Private Attributes

CellManager _cm
 The cell manager.
 
const Params _params
 Model parameters.
 
std::uniform_real_distribution< double_prob_distr
 The range [0, 1] distribution to use for probability checks.
 
unsigned int _cluster_id_cnt
 The incremental cluster tag.
 
std::vector< std::shared_ptr< CellManager::Cell > > _cluster_members
 A temporary container for use in cluster identification.
 
std::array< double, static_cast< char >(Kind::COUNT)> _densities
 Densities for all states.
 
Counters< std::size_t > _counts
 Cumulative counters for state transitions and other events
 
const int _compression
 The compression level used for all datasets.
 
bool _write_ca_data
 If false, writes only the non-spatial densities and counts data.
 
std::shared_ptr< DataSet_dset_densities
 2D dataset (densities array and time) of density values
 
std::shared_ptr< DataSet_dset_counts
 2D dataset (counts array and time) of cumulative state counters
 
std::shared_ptr< DataSet_dset_kind
 2D dataset (cell ID and time) of cell kinds
 
std::shared_ptr< DataSet_dset_immune
 2D dataset (cell ID and time) of cell's immunity
 
std::shared_ptr< DataSet_dset_num_recoveries
 2D dataset (cell ID and time) of cell's number of recoveries
 
std::shared_ptr< DataSet_dset_age
 2D dataset (cell ID and time) of cell's age
 
std::shared_ptr< DataSet_dset_cluster_id
 The dataset for storing the cluster ID associated with each cell.
 

Additional Inherited Members

- Static Protected Attributes inherited from Utopia::Model< SEIRD, CDTypes >
static constexpr WriteMode _write_mode
 Which data-writing mode the base model should use.
 

Detailed Description

SEIRD model on a grid.

In this model, we model the spread of a disease using a SEIRD (susceptible-exposed-infected-recovered-deceased) model on a 2D grid.

Member Typedef Documentation

◆ Base

The base model type.

◆ Cell

Type of a cell.

◆ CellContainer

Type of a container of shared pointers to cells.

◆ CellManager

Type of the CellManager to use.

◆ DataGroup

Data type for a data group.

◆ DataSet

Data type for a dataset.

◆ RuleFunc

Rule function type.

Constructor & Destructor Documentation

◆ SEIRD()

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

Construct the SEIRD 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
138 {})
139 :
140 // Initialize first via base model
142
143 // Initialize the cell manager, binding it to this model
144 _cm(*this),
145
146 // Carry over Parameters
147 _params(this->_cfg),
148
149 // Initialize remaining members
150 _prob_distr(0., 1.),
153 _densities{}, // undefined here, will be set in constructor body
154 _counts{},
155
156 // Data output . . . . . . . . . . . . . . . . . . . . . . . . . . . .
157 // Get output-related parameters
158 _compression(get_as<int>("compression", this->_cfg)),
159 _write_ca_data(get_as<bool>("write_ca_data", this->_cfg)),
160
161 // Create the dataset for the densities and counts; shape is known
163 this->create_dset("densities", {static_cast<char>(Kind::COUNT)},
165 ),
167 this->create_dset("counts", {_counts.size}, _compression)
168 ),
169
170 // Create CellManager-based datasets
172 this->create_cm_dset("kind", _cm, _compression)),
174 this->create_cm_dset("immune", _cm, _compression)),
176 this->create_cm_dset("num_recoveries", _cm, _compression)),
177 _dset_age(
178 this->create_cm_dset("age", _cm, _compression)),
180 this->create_cm_dset("cluster_id", _cm, _compression))
181 {
182 // Make sure the densities are not undefined
183 _densities.fill(std::numeric_limits<double>::quiet_NaN());
184
185 // Cells are already set up by the CellManager.
186 // Remaining initialization steps regard only macroscopic quantities,
187 // e.g. the setup of heterogeneities: Inert cells and infection source.
188
189 // Inert
190 if (_cfg["inert_cells"] and
191 get_as<bool>("enabled", _cfg["inert_cells"]))
192 {
193 this->_log->info("Setting cells to be inert ...");
194
195 // Get the container
196 auto make_inert = _cm.select_cells(_cfg["inert_cells"]);
197
198 // Apply a rule to all cells of that container: turn to an inert cell
200 [](const auto& cell) {
201 auto& state = cell->state;
202 state.kind = Kind::inert;
203 return state;
204 },
205 make_inert);
206
207 this->_log->info("Set {} cells to be inert using selection mode "
208 "'{}'.",
209 make_inert.size(),
210 get_as<std::string>("mode", _cfg["inert_cells"]));
211 }
212
213 // Ignite some cells permanently: infection sources
214 if (_cfg["infection_source"] and
215 get_as<bool>("enabled", _cfg["infection_source"]))
216 {
217 this->_log->info("Setting cells to be infection sources ...");
218 auto source_cells = _cm.select_cells(_cfg["infection_source"]);
219
221 [](const auto& cell) {
222 auto& state = cell->state;
223 state.kind = Kind::source;
224 return state;
225 },
227
228 this->_log->info(
229 "Set {} cells to be infection sources using "
230 "selection mode '{}'.",
231 source_cells.size(),
232 get_as<std::string>("mode", _cfg["infection_source"]));
233 }
234
235 // Store the kind names (see state.hh) in the dataset attributes.
236 _dset_kind->add_attribute("kind_names", kind_names);
237 this->_log->debug("Stored metadata in 'kind' dataset.");
238
239 // Add coordinate attributes to density and counts datasets
240 _dset_densities->add_attribute("dim_name__1", "kind");
241 _dset_densities->add_attribute("coords_mode__kind", "values");
242 _dset_densities->add_attribute("coords__kind", kind_names);
243
244 _dset_counts->add_attribute("dim_name__1", "label");
245 _dset_counts->add_attribute("coords_mode__label", "values");
246 _dset_counts->add_attribute("coords__label", _counts.labels());
247
248 this->_log->debug("Added coordinate labels to 'densities' and "
249 "'counts' datasets.");
250
251 // Initialization should be finished here. Provide some info
252 this->_log->info("{} model fully set up.", this->_name);
253 this->_log->info(" Writing CA data? {}",
254 _write_ca_data ? "Yes" : "No");
255 this->_log->info(" Compression level: {}", _compression);
256 }
CellContainer< Cell > select_cells(Args &&... args) const
Select cells using the Utopia::select_entities interface.
Definition cell_manager.hh:342
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 Params _params
Model parameters.
Definition SEIRD.hh:73
std::shared_ptr< DataSet > _dset_kind
2D dataset (cell ID and time) of cell kinds
Definition SEIRD.hh:110
unsigned int _cluster_id_cnt
The incremental cluster tag.
Definition SEIRD.hh:79
std::array< double, static_cast< char >(Kind::COUNT)> _densities
Densities for all states.
Definition SEIRD.hh:90
std::shared_ptr< DataSet > _dset_age
2D dataset (cell ID and time) of cell's age
Definition SEIRD.hh:119
std::vector< std::shared_ptr< CellManager::Cell > > _cluster_members
A temporary container for use in cluster identification.
Definition SEIRD.hh:82
std::shared_ptr< DataSet > _dset_num_recoveries
2D dataset (cell ID and time) of cell's number of recoveries
Definition SEIRD.hh:116
Counters< std::size_t > _counts
Cumulative counters for state transitions and other events
Definition SEIRD.hh:93
std::shared_ptr< DataSet > _dset_immune
2D dataset (cell ID and time) of cell's immunity
Definition SEIRD.hh:113
CellManager _cm
The cell manager.
Definition SEIRD.hh:70
std::uniform_real_distribution< double > _prob_distr
The range [0, 1] distribution to use for probability checks.
Definition SEIRD.hh:76
bool _write_ca_data
If false, writes only the non-spatial densities and counts data.
Definition SEIRD.hh:101
std::shared_ptr< DataSet > _dset_densities
2D dataset (densities array and time) of density values
Definition SEIRD.hh:104
const int _compression
The compression level used for all datasets.
Definition SEIRD.hh:98
std::shared_ptr< DataSet > _dset_counts
2D dataset (counts array and time) of cumulative state counters
Definition SEIRD.hh:107
std::shared_ptr< DataSet > _dset_cluster_id
The dataset for storing the cluster ID associated with each cell.
Definition SEIRD.hh:122
Model< SEIRD, CDTypes > Base
The base model type.
Definition SEIRD.hh:44
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
const std::array< std::string, static_cast< char >(Kind::COUNT)> kind_names
The associated string names of each Kind enum entry.
Definition state.hh:76
@ source
Cell is an infection source: constantly infected, spreading infection.
@ inert
Cell does not partake in the dynamics.
@ COUNT
The number of kinds (COUNT)
const auto & labels()
The labels cooresponding to each entry of the counts array.
Definition counters.hh:58
static constexpr std::size_t size
Number of counters.
Definition counters.hh:25

Member Function Documentation

◆ exposure_control()

void Utopia::Models::SEIRD::SEIRD::exposure_control ( )
inlineprotected

Apply exposure control.

Add exposures if the iteration step matches the ones specified in the configuration. There are two available modes of exposure control that are applied, if provided, in this order:

  1. At specified times (parameter: at_times) a number of additional exposures is added (parameter: num_additional_exposures)
  2. The parameter p_exposed is changed to a new value at given times. This can happen multiple times. Parameter: change_p_exposed
312 {
313 // Check that time matches the first element of the sorted queue of
314 // time steps at which to apply the given number of exposures.
315 if (not _params.exposure_control.at_times.empty()) {
316 // Check whether time has come for exposures
317 if (this->_time == _params.exposure_control.at_times.front()) {
318 // Select cells that are susceptibles
319 // (not empty, inert, infected, or source)
320 const auto cells_pool =
322 [&](const auto& cell) {
323 return (cell->state.kind == Kind::susceptible);
324 });
325
326 // Sample cells from the pool and ...
328 std::sample(cells_pool.begin(),
329 cells_pool.end(),
330 std::back_inserter(sample),
332 *this->_rng);
333
334 // ... and expose the sampled cells
335 for (const auto& cell : sample) {
336 cell->state.kind = Kind::exposed;
338 }
339
340 // Done. Can now remove first element of the queue.
342 }
343 }
344
345 // Change p_exposed if the iteration step matches the ones
346 // specified in the configuration. This leads to constant time lookup.
348 const auto change_p_exposed =
350
351 if (this->_time == change_p_exposed.first) {
352 _params.p_exposed = change_p_exposed.second;
353
354 // Done. Can now remove the element from the queue.
356 }
357 }
358 }
Time _time
Model-internal current time stamp.
Definition model.hh:170
Utopia::CellContainer< Cell > CellContainer
Type of a container of shared pointers to cells.
Definition SEIRD.hh:59
@ condition
Select if a condition is fulfilled.
@ sample
Select a random sample of entities with a known sample size.
@ exposed
Cell is exposed to the dease but not yet infected.
@ susceptible
Cell represents a susceptible.
void increment_susceptible_to_exposed_controlled()
Increment counter for transitions from susceptible to exposed (control)
Definition counters.hh:83
TimesQueue at_times
Add additional exposures at these time steps.
Definition params.hh:32
const std::size_t num_additional_exposures
The number of exposures added to the default p_expose.
Definition params.hh:29
TimesValuesQueue change_p_exposed
Change p_expose to new value at given times.
Definition params.hh:39
double p_exposed
Definition params.hh:274
const ExposureContParams exposure_control
Exposure control parameters.
Definition params.hh:302

◆ identify_clusters()

void Utopia::Models::SEIRD::SEIRD::identify_clusters ( )
inlineprotected

Identify clusters.

This function identifies clusters and updates the cell specific cluster_id as well as the member variable cluster_id_cnt that counts the number of ids

294 {
295 // reset cluster counter
296 _cluster_id_cnt = 0;
298 }
const CellContainer< Cell > & cells() const
Return const reference to the managed CA cells.
Definition cell_manager.hh:219
RuleFunc _identify_cluster
Identify each cluster of susceptibles.
Definition SEIRD.hh:658

◆ immunity_control()

void Utopia::Models::SEIRD::SEIRD::immunity_control ( )
inlineprotected

Apply immunity control.

Add cell immunities if the iteration step matches the ones specified in the configuration. There are two available modes of immunity control that are applied, if provided, in this order:

  1. At specified times (parameter: at_times) a number of additional immmunities is added (parameter: num_additional_immmunities)
  2. The parameter immune is changed to a new value at given times. This can happen multiple times. Parameter: change_immune
372 {
373 // Check that time matches the first element of the sorted queue of
374 // time steps at which to apply the given number of immmunities.
375 if (not _params.immunity_control.at_times.empty()) {
376 // Check whether time has come for immmunities
377 if (this->_time == _params.immunity_control.at_times.front()) {
378 // Select cells that are susceptibles
379 // (not empty, exposed, infected, inert, infected, or source)
380 const auto cells_pool =
382 [&](const auto& cell) {
383 return (cell->state.kind == Kind::susceptible);
384 });
385
386 // Sample cells from the pool and ...
388 std::sample(cells_pool.begin(),
389 cells_pool.end(),
390 std::back_inserter(sample),
392 *this->_rng);
393
394 // ... and add immunity to the sampled cells
395 for (const auto& cell : sample) {
396 cell->state.immune = true;
397 }
398
399 // Done. Can now remove first element of the queue.
401 }
402 }
403
404 // Change immune if the iteration step matches the ones
405 // specified in the configuration. This leads to constant time lookup.
407 const auto change_p_immune =
409
410 if (this->_time == change_p_immune.first) {
411 _params.p_immune = change_p_immune.second;
412
413 // Done. Can now remove the element from the queue.
415 }
416 }
417 }
const std::size_t num_additional_immunities
The number of immunities added to the default p_expose.
Definition params.hh:114
TimesValuesQueue change_p_immune
Change p_immune to new value at given times.
Definition params.hh:124
TimesQueue at_times
Add additional immunities at these time steps.
Definition params.hh:117
const ImmunityContParams immunity_control
Immunity control parameters.
Definition params.hh:305
double p_immune
Probability per transition to susceptible via p_susceptible to be immune.
Definition params.hh:266

◆ monitor()

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

Monitor model information.

Supplies the densities and counts arrays to the monitor.

818 {
820 this->_monitor.set_entry("densities", _densities);
821 this->_monitor.set_entry("counts", _counts.counts());
822 }
Monitor _monitor
The monitor.
Definition model.hh:188
void update_densities()
Update the densities array.
Definition SEIRD.hh:268
auto counts()
Return a copy of the current value of all counts.
Definition counters.hh:53

◆ perform_step()

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

Iterate a single time step.

This updates all cells (synchronously) according to the _update rule. For specifics, see there.

If exposure control is activated, the cells are first modified according to the specific exposure control parameters.

780 {
781 // Apply exposure control if enabled
784 }
785
786 // Apply immunity control if enabled
789 }
790
791 // Apply transmit control if enabled
794 }
795
796 // Apply the update rule to all cells.
798 // NOTE The cell state is updated synchronously, i.e.: only after
799 // all cells have been visited and know their state for the next step
800
801 // Move cells randomly with probability p_move_randomly
803 _cm.cells(),
804 *this->_rng);
805
806 // Move the agents living on cells randomly
809 _cm.cells(),
810 *this->_rng);
811 }
812 }
void immunity_control()
Apply immunity control.
Definition SEIRD.hh:371
void transmission_control()
Apply transmission control.
Definition SEIRD.hh:427
RuleFunc _move_randomly
Move randomly to a neighboring cell if that cell is empty.
Definition SEIRD.hh:736
RuleFunc _move_away_from_infected
Move the agent on the cell away from an infected neighboring cell.
Definition SEIRD.hh:700
void exposure_control()
Apply exposure control.
Definition SEIRD.hh:311
RuleFunc _update
Define the update rule.
Definition SEIRD.hh:480
const bool enabled
Whether exposure control is enabled.
Definition params.hh:26
const bool enabled
Whether immunity control is enabled.
Definition params.hh:111
bool move_away_from_infected
Whether to globally allow moving away from infected neighboring cells.
Definition params.hh:296
const TransmitContParams transmission_control
Transmit control parameters.
Definition params.hh:308
const bool enabled
Whether immunity control is enabled.
Definition params.hh:197

◆ transmission_control()

void Utopia::Models::SEIRD::SEIRD::transmission_control ( )
inlineprotected

Apply transmission control.

Change the transmitting probability p_transmit for a subset of cells of a specified kind if the iteration step matches the ones specified in the configuration. The parameter p_transmit is changed to a new value at given times for a number of randomly chosen cells of specified kins. This can happen multiple times. Parameter: change_p_transmit

428 {
429 // Change p_transmit if the iteration step matches the ones
430 // specified in the configuration. This leads to constant time
431 // lookup.
433 // Extract parameters
434 const auto change_p_transmit =
436
437 const auto iteration_step = std::get<0>(change_p_transmit);
438 const auto num_cells = std::get<1>(change_p_transmit);
439 const auto cell_kind = std::get<2>(change_p_transmit);
440 const auto p_transmit = std::get<3>(change_p_transmit);
441
442 if (this->_time == iteration_step) {
443 // Select cells that are of desired kind
444 const auto cells_pool =
446 [&](const auto& cell) {
447 return (cell->state.kind == cell_kind);
448 });
449
450 // Sample cells from the pool and ...
452 std::sample(cells_pool.begin(),
453 cells_pool.end(),
454 std::back_inserter(sample),
455 num_cells,
456 *this->_rng);
457
458 // ... and change p_transmit for the sampled cells
459 for (const auto& cell : sample) {
460 cell->state.p_transmit = p_transmit;
461 }
462
463 // Done. Can now remove the element from the queue.
465 }
466 }
467 }
TimesValuesQueue change_p_transmit
Change p_transmit to new value at given times.
Definition params.hh:205

◆ update_densities()

void Utopia::Models::SEIRD::SEIRD::update_densities ( )
inlineprotected

Update the densities array.

Each density is calculated by counting the number of state occurrences and afterwards dividing by the total number of cells.

Attention
It is possible that rounding errors occur due to the division, thus, it is not guaranteed that the densities exactly add up to 1. The errors should be negligible.
269 {
270 // Temporarily overwrite every entry in the densities with zeroes
271 _densities.fill(0);
272
273 // Count the occurrence of each possible state. Use the _densities
274 // member for that in order to not create a new array.
275 for (const auto& cell : this->_cm.cells()) {
276 // Cast enum to integer to arrive at the corresponding index
277 ++_densities[static_cast<char>(cell->state.kind)];
278 }
279 // The _densities array now contains the counts.
280
281 // Calculate the actual densities by dividing the counts by the total
282 // number of cells.
283 for (auto&& d : _densities) {
284 d /= static_cast<double>(this->_cm.cells().size());
285 }
286 };

◆ write_data()

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

Write data.

826 {
827 // Update densities and write them
830
831 // Store the counts
832 _dset_counts->write(_counts.counts());
833
834 // If CA data is not to be written, can return here
835 if (not _write_ca_data) {
836 return;
837 }
838
839 // Write the cell state
840 _dset_kind->write(_cm.cells().begin(),
841 _cm.cells().end(),
842 [](const auto& cell) {
843 return static_cast<char>(cell->state.kind);
844 });
845
846 // Write the immune state
847 _dset_immune->write(_cm.cells().begin(),
848 _cm.cells().end(),
849 [](const auto& cell) {
850 return static_cast<char>(cell->state.immune);
851 });
852
853 // Write the number of recoveries state
854 _dset_num_recoveries->write(_cm.cells().begin(),
855 _cm.cells().end(),
856 [](const auto& cell) {
857 return static_cast<unsigned short>(
858 cell->state.num_recoveries);
859 });
860
861 // Write the susceptible ages
862 _dset_age->write(_cm.cells().begin(),
863 _cm.cells().end(),
864 [](const auto& cell) {
865 return cell->state.age;
866 });
867
868 // Identify clusters and write them out
870 _dset_cluster_id->write(_cm.cells().begin(),
871 _cm.cells().end(),
872 [](const auto& cell) {
873 return cell->state.cluster_id;
874 });
875 }
void identify_clusters()
Identify clusters.
Definition SEIRD.hh:293

Member Data Documentation

◆ _cluster_id_cnt

unsigned int Utopia::Models::SEIRD::SEIRD::_cluster_id_cnt
private

The incremental cluster tag.

◆ _cluster_members

std::vector<std::shared_ptr<CellManager::Cell> > Utopia::Models::SEIRD::SEIRD::_cluster_members
private

A temporary container for use in cluster identification.

◆ _cm

CellManager Utopia::Models::SEIRD::SEIRD::_cm
private

The cell manager.

◆ _compression

const int Utopia::Models::SEIRD::SEIRD::_compression
private

The compression level used for all datasets.

◆ _counts

Counters<std::size_t> Utopia::Models::SEIRD::SEIRD::_counts
private

Cumulative counters for state transitions and other events

◆ _densities

std::array<double, static_cast<char>(Kind::COUNT)> Utopia::Models::SEIRD::SEIRD::_densities
private

Densities for all states.

Array indices are linked to Utopia::Models::SEIRD::Kind

Warning
This array is used for temporary storage; it is not automatically updated but only upon write operations.

◆ _dset_age

std::shared_ptr<DataSet> Utopia::Models::SEIRD::SEIRD::_dset_age
private

2D dataset (cell ID and time) of cell's age

◆ _dset_cluster_id

std::shared_ptr<DataSet> Utopia::Models::SEIRD::SEIRD::_dset_cluster_id
private

The dataset for storing the cluster ID associated with each cell.

◆ _dset_counts

std::shared_ptr<DataSet> Utopia::Models::SEIRD::SEIRD::_dset_counts
private

2D dataset (counts array and time) of cumulative state counters

◆ _dset_densities

std::shared_ptr<DataSet> Utopia::Models::SEIRD::SEIRD::_dset_densities
private

2D dataset (densities array and time) of density values

◆ _dset_immune

std::shared_ptr<DataSet> Utopia::Models::SEIRD::SEIRD::_dset_immune
private

2D dataset (cell ID and time) of cell's immunity

◆ _dset_kind

std::shared_ptr<DataSet> Utopia::Models::SEIRD::SEIRD::_dset_kind
private

2D dataset (cell ID and time) of cell kinds

◆ _dset_num_recoveries

std::shared_ptr<DataSet> Utopia::Models::SEIRD::SEIRD::_dset_num_recoveries
private

2D dataset (cell ID and time) of cell's number of recoveries

◆ _identify_cluster

RuleFunc Utopia::Models::SEIRD::SEIRD::_identify_cluster
protected

Identify each cluster of susceptibles.

658 {
659 if (cell->state.cluster_id != 0 or
660 cell->state.kind != Kind::susceptible)
661 {
662 // already labelled, nothing to do. Return current state
663 return cell->state;
664 }
665 // else: need to label this cell
666
667 // Increment the cluster ID counter and label the given cell
669 cell->state.cluster_id = _cluster_id_cnt;
670
671 // Use existing cluster member container, clear it, add current cell
673 cluster.clear();
674 cluster.push_back(cell);
675
676 // Perform the percolation
677 for (unsigned int i = 0; i < cluster.size(); ++i) {
678 // Iterate over all potential cluster members nb, i.e. all
679 // neighbors of cell cluster[i] that is already in the cluster
680 for (const auto& nb : this->_cm.neighbors_of(cluster[i])) {
681 // If it is susceptible and not yet in the cluster, add it.
682 if (nb->state.cluster_id == 0 and
683 nb->state.kind == Kind::susceptible)
684 {
685 nb->state.cluster_id = _cluster_id_cnt;
686 cluster.push_back(nb);
687 // This extends the outer for-loop...
688 }
689 }
690 }
691
692 return cell->state;
693 };

◆ _move_away_from_infected

RuleFunc Utopia::Models::SEIRD::SEIRD::_move_away_from_infected
protected
Initial value:
= [this](const auto& cell) {
auto& state = cell->state;
for (const auto& nb : neighbors) {
if (nb->state.kind == Kind::infected) {
std::shuffle(neighbors.begin(), neighbors.end(), *this->_rng);
for (const auto& _nb : neighbors) {
if (_nb->state.kind == Kind::empty) {
std::swap(state, _nb->state);
break;
}
}
break;
}
}
return state;
}
CellContainer< Cell > neighbors_of(const Cell &cell) const
Retrieve the given cell's neighbors.
Definition cell_manager.hh:458
@ neighbors
Iterate over neighbors (adjacent_vertices).
@ infected
Cell is infected.
void increment_move_away_from_infected()
Increment counter for movement events away from an infected agent.
Definition counters.hh:113

Move the agent on the cell away from an infected neighboring cell.

Check whether there is an infected cell in the neighborhood. If there is an empty cell in the neighborhood, move to it. If there is no empty spot in the neighborhood do nothing.

700 {
701 // Get the reference to the state because it is directly manipulated
702 auto& state = cell->state;
703
705
706 for (const auto& nb : neighbors) {
707 if (nb->state.kind == Kind::infected) {
708 // Shuffle the neighbors container ...
709 std::shuffle(neighbors.begin(), neighbors.end(), *this->_rng);
710 // ... go through it, and move to the first appearing empty
711 // cell
712 for (const auto& _nb : neighbors) {
713 if (_nb->state.kind == Kind::empty) {
714 // Swap the states and leave the loop
715 std::swap(state, _nb->state);
717 break;
718 }
719 }
720 // NOTE It is important to leave the outer loop because the
721 // neighbors container over which it is iterated was
722 // shuffled. This could result in undefined behavior and
723 // breaking code
724 break;
725 }
726 }
727
728 return state;
729 };

◆ _move_randomly

RuleFunc Utopia::Models::SEIRD::SEIRD::_move_randomly
protected

Move randomly to a neighboring cell if that cell is empty.

If the cell is not empty, an inert cell, or a source: move to neighboring empty location with probability p_move_randomly. If no neighboring cell is empty, do nothing.

736 {
737 // Get the state reference to directly manipulate the state
738 auto& state = cell->state;
739
740 // Directly return the state if the cell is of kind empty, source,
741 // or inert.
742 if ((state.kind == Kind::empty) or
743 (state.kind == Kind::source) or
744 (state.kind == Kind::inert))
745 {
746 return state;
747 }
748
749 if (_prob_distr(*this->_rng) < _params.p_move_randomly) {
751
752 // Shuffle the neighbors container ...
753 std::shuffle(neighbors.begin(), neighbors.end(), *this->_rng);
754 // ... go through it, and move to the first appearing empty cell
755 for (const auto& _nb : neighbors) {
756 if (_nb->state.kind == Kind::empty) {
757 // Swap the states and leave the loop
758 std::swap(state, _nb->state);
760 break;
761 }
762 }
763 }
764
765 return state;
766 };
const std::shared_ptr< RNG > _rng
The RNG shared between models.
Definition model.hh:161
void increment_move_randomly()
Increment counter for random movement events.
Definition counters.hh:108
double p_move_randomly
Probability to move randomly if the neighboring cell is empty.
Definition params.hh:299

◆ _params

const Params Utopia::Models::SEIRD::SEIRD::_params
private

Model parameters.

◆ _prob_distr

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

The range [0, 1] distribution to use for probability checks.

◆ _update

RuleFunc Utopia::Models::SEIRD::SEIRD::_update
protected

Define the update rule.

Update the given cell according to the following rules:

  • Empty cells grow susceptible cells with probability p_susceptible.
  • Cells in neighborhood of an infected cell do not get exposed with the probability p_random_immunity.
  • Exposed cells become infected cells after a certain incubation period.
  • Infected cells die with probability p_deceased and become an empty cell or they become recovered cells with 1-p_deceased.
480 {
481 // Get the current state of the cell and reset its cluster ID
482 auto state = cell->state;
483 state.cluster_id = 0;
484
485 // With probability p_empty transition any kind of cell to be empty
486 // Note that this allows for empty cells to become susceptible directly
487 // in the same update step. Having it at the end would, however, create
488 // a similar issue with just appearing agents.
489 // Be explicit in the kinds to assure that inert and sources do not
490 // convert to empty cells
491 // Note that this could probably be made more efficient through
492 // sampling if more performance is needed.
493 if ((state.kind == Kind::susceptible) or
494 (state.kind == Kind::exposed) or
495 (state.kind == Kind::infected) or
496 (state.kind == Kind::recovered))
497 {
498 if (_prob_distr(*this->_rng) < _params.p_empty) {
499 state.kind = Kind::empty;
500 state.num_recoveries = 0;
501 state.immune = false;
503 }
504 }
505
506 // Distinguish by current state
507 if (state.kind == Kind::empty) {
508 // With a probability of p_susceptible, set the cell's state to
509 // susceptible
510 if (_prob_distr(*this->_rng) < _params.p_susceptible) {
511 state.kind = Kind::susceptible;
513
514 // If a new susceptible cell appears it is immune with the
515 // probability p_immune.
516 if (_prob_distr(*this->_rng) < _params.p_immune) {
517 state.immune = true;
518 }
519 else {
520 state.immune = false;
521 }
522
523 // Initialize the probability p_transmit of the cell from
524 // the configuration node
525 state.p_transmit = State::initialize_p_transmit(
526 get_as<DataIO::Config>("p_transmit", this->_cfg),
527 this->_rng);
528
529 // The new susceptible cell does not yet have recoveries
530 state.num_recoveries = 0;
531
532 return state;
533 }
534 }
535 else if (state.kind == Kind::susceptible) {
536 // Increase the age of the susceptible cell
537 ++state.age;
538
539 // If the cell is immune nothing happens :)
540 // It can neither be infected through point infection nor through
541 // contact with exposed or infected cells
542 if (state.immune) {
543 return state;
544 }
545 else {
546 // Susceptible cell can be exposed by neighbor
547 // or by random-point-infection.
548
549 // Determine whether there will be a point infection resulting
550 // in an exposed agent.
551 if (_prob_distr(*this->_rng) < _params.p_exposed) {
552 // Yes, point infection occurred.
553 state.kind = Kind::exposed;
555 return state;
556 }
557 else {
558 // Go through neighbor cells (according to Neighborhood
559 // type) and check if they are infected
560 // (or an infection source).
561 // If yes, expose the cell with the probability p_transmit
562 // given by the neighbor's cell state if no random immunity
563 // given by p_random_immunity occurs.
564 for (const auto& nb : this->_cm.neighbors_of(cell)) {
565 // Get the neighbor cell's state
566 const auto& nb_state = nb->state;
567
568 if (nb_state.kind == Kind::infected or
570 nb_state.kind == Kind::source)
571 {
572 // With the probability given by the neighbors cell
573 // p_transmit become exposed if no random immunity
574 // occurs
575 if (_prob_distr(*this->_rng) <
576 ((1. - _params.p_random_immunity) *
577 nb_state.p_transmit))
578 {
579 state.kind = Kind::exposed;
581 return state;
582 }
583 }
584 }
585 }
586 }
587 }
588 else if (state.kind == Kind::exposed) {
589 // Increase the age of the exposed cell
590 ++state.age;
591
592 // Transition from the exposed state to infected with probability
593 // p_infected
594 if (_prob_distr(*this->_rng) < _params.p_infected) {
595 state.kind = Kind::infected;
597 return state;
598 }
599
600 return state;
601 }
602 else if (state.kind == Kind::infected) {
603 // Increase the age of the infected cell
604 ++state.age;
605
606 // Increment the exposed time because if the cell is infected
607 // the infected time adds to the total exposed time.
608 ++state.exposed_time;
609
610 if (_prob_distr(*this->_rng) < _params.p_recovered) {
611 state.kind = Kind::recovered;
612 state.immune = true;
613 ++state.num_recoveries;
615 }
616 else if (_prob_distr(*this->_rng) < _params.p_deceased) {
617 state.kind = Kind::deceased;
619 // Do not reset the cell states here to keep them for
620 // write out and analysis. Resetting happens in the deceased
621 // case below.
622 }
623 // else nothing happens and the cell stays infected the next time
624
625 return state;
626 }
627 else if (state.kind == Kind::recovered) {
628 // Increase the age of the recovered cell
629 ++state.age;
630
631 // Cells can lose their immunity and get susceptible again
632 if (_prob_distr(*this->_rng) < _params.p_lose_immunity) {
633 state.immune = false;
634 state.kind = Kind::susceptible;
636 }
637
638 return state;
639 }
640 else if (state.kind == Kind::deceased) {
641 // A former deceased cell gets empty
642 state.kind = Kind::empty;
643 state.immune = false;
644 state.num_recoveries = 0;
645
646 // Reset the age for the next susceptible cell
647 state.age = 0;
648
649 return state;
650 }
651 // else: other cell states need no update
652
653 // Return the (potentially changed) cell state for the next round
654 return state;
655 };
@ recovered
Cell is recovered.
@ deceased
Cell is deceased.
void increment_susceptible_to_exposed_random()
Increment counter for transitions from susceptible to exposed (random)
Definition counters.hh:78
void increment_infected_to_recovered()
Increment counter for transitions from infected to recovered.
Definition counters.hh:93
void increment_empty_to_susceptible()
Increment counter for transitions from empty to susceptible.
Definition counters.hh:63
void increment_recovered_to_susceptible()
Increment counter for transitions from recovered to susceptible.
Definition counters.hh:103
void increment_infected_to_deceased()
Increment counter for transitions from infected to deceased.
Definition counters.hh:98
void increment_living_to_empty()
Increment counter for transitions from living to empty.
Definition counters.hh:68
void increment_exposed_to_infected()
Increment counter for transitions from exposed to infected.
Definition counters.hh:88
void increment_susceptible_to_exposed_contact()
Increment counter for transitions from susceptible to exposed (contact)
Definition counters.hh:73
double p_deceased
Probability for a cell to desease.
Definition params.hh:287
double p_lose_immunity
The probability to loose immunity if a cell is recovered.
Definition params.hh:293
const double p_susceptible
Probability per site and time step to go from state empty to susceptible.
Definition params.hh:263
const double p_random_immunity
Definition params.hh:270
double p_empty
Probability for a cell to become empty.
Definition params.hh:290
double p_infected
Definition params.hh:281
double p_recovered
Probability for a cell to recover.
Definition params.hh:284
static double initialize_p_transmit(const DataIO::Config &cfg, const std::shared_ptr< RNG > &rng)
Initialize p_transmit from a configuration node.
Definition state.hh:171

◆ _write_ca_data

bool Utopia::Models::SEIRD::SEIRD::_write_ca_data
private

If false, writes only the non-spatial densities and counts data.


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