Utopia 2
Framework for studying models of complex & adaptive systems.
Loading...
Searching...
No Matches
SEIRD.hh
Go to the documentation of this file.
1#ifndef UTOPIA_MODELS_SEIRD_HH
2#define UTOPIA_MODELS_SEIRD_HH
3
4#include <functional>
5#include <random>
6
7// Utopia-related includes
11#include <utopia/core/select.hh>
12
13// SEIRD-realted includes
14#include "counters.hh"
15#include "params.hh"
16#include "state.hh"
17
18
20{
21// ++ Type definitions ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
22
23// Specialize the CellTraits type helper for this model
30
33
34// ++ Model definition ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
35
37
40class SEIRD : public Model<SEIRD, CDTypes>
41{
42 public:
45
47 using DataGroup = typename Base::DataGroup;
48
50 using DataSet = typename Base::DataSet;
51
54
56 using Cell = typename CellManager::Cell;
57
60
63
64 private:
65 // Base members: _time, _name, _cfg, _hdfgrp, _rng, _monitor, _space
66 // ... but you should definitely check out the documentation ;)
67
68 // -- Members -------------------------------------------------------------
71
74
76 std::uniform_real_distribution<double> _prob_distr;
77
79 unsigned int _cluster_id_cnt;
80
82 std::vector<std::shared_ptr<CellManager::Cell>> _cluster_members;
83
85
90 std::array<double, static_cast<char>(Kind::COUNT)> _densities;
91
94
95
96 // .. Data-Output related members .........................................
98 const int _compression;
99
102
104 std::shared_ptr<DataSet> _dset_densities;
105
107 std::shared_ptr<DataSet> _dset_counts;
108
110 std::shared_ptr<DataSet> _dset_kind;
111
113 std::shared_ptr<DataSet> _dset_immune;
114
116 std::shared_ptr<DataSet> _dset_num_recoveries;
117
119 std::shared_ptr<DataSet> _dset_age;
120
122 std::shared_ptr<DataSet> _dset_cluster_id;
123
124
125 public:
127
135 template<class ParentModel>
136 SEIRD(const std::string& name,
138 const DataIO::Config& custom_cfg = {})
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 }
257
258 protected:
259 // .. Helper functions ....................................................
261
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 };
287
289
294 {
295 // reset cluster counter
296 _cluster_id_cnt = 0;
298 }
299
301
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 }
359
361
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 }
418
420
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 }
468
469 // .. Rule functions ......................................................
470
472
480 RuleFunc _update = [this](const auto& cell) {
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 };
656
658 RuleFunc _identify_cluster = [this](const auto& cell) {
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 };
694
696
700 RuleFunc _move_away_from_infected = [this](const auto& cell) {
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 };
730
732
736 RuleFunc _move_randomly = [this](const auto& cell) {
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 };
767
768 public:
769 // -- Public Interface ----------------------------------------------------
770 // .. Simulation Control ..................................................
771
773
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 }
813
815
817 void monitor()
818 {
820 this->_monitor.set_entry("densities", _densities);
821 this->_monitor.set_entry("counts", _counts.counts());
822 }
823
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 }
876};
877
878} // namespace Utopia::Models::SEIRD
879
880#endif // UTOPIA_MODELS_SEIRD_HH
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
CellContainer< Cell > select_cells(Args &&... args) const
Select cells using the Utopia::select_entities interface.
Definition cell_manager.hh:342
CellContainer< Cell > neighbors_of(const Cell &cell) const
Retrieve the given cell's neighbors.
Definition cell_manager.hh:458
const CellContainer< Cell > & cells() const
Return const reference to the managed CA cells.
Definition cell_manager.hh:219
Utopia::Cell< CDCellTraits > 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
Monitor _monitor
The monitor.
Definition model.hh:188
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
Time _time
Model-internal current time stamp.
Definition model.hh:170
const std::string _name
Name of the model instance.
Definition model.hh:149
typename ModelTypes::DataGroup DataGroup
Data type that is used for storing datasets.
Definition model.hh:122
const std::shared_ptr< spdlog::logger > _log
The (model) logger.
Definition model.hh:164
const std::shared_ptr< RNG > _rng
The RNG shared between models.
Definition model.hh:161
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
SEIRD model on a grid.
Definition SEIRD.hh:41
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
typename CellManager::Cell Cell
Type of a cell.
Definition SEIRD.hh:56
typename Base::DataGroup DataGroup
Data type for a data group.
Definition SEIRD.hh:47
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
void monitor()
Monitor model information.
Definition SEIRD.hh:817
Utopia::CellContainer< Cell > CellContainer
Type of a container of shared pointers to cells.
Definition SEIRD.hh:59
void identify_clusters()
Identify clusters.
Definition SEIRD.hh:293
void immunity_control()
Apply immunity control.
Definition SEIRD.hh:371
std::vector< std::shared_ptr< CellManager::Cell > > _cluster_members
A temporary container for use in cluster identification.
Definition SEIRD.hh:82
void transmission_control()
Apply transmission control.
Definition SEIRD.hh:427
typename Base::DataSet DataSet
Data type for a dataset.
Definition SEIRD.hh:50
RuleFunc _identify_cluster
Identify each cluster of susceptibles.
Definition SEIRD.hh:658
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
RuleFunc _move_randomly
Move randomly to a neighboring cell if that cell is empty.
Definition SEIRD.hh:736
void write_data()
Write data.
Definition SEIRD.hh:825
std::shared_ptr< DataSet > _dset_immune
2D dataset (cell ID and time) of cell's immunity
Definition SEIRD.hh:113
RuleFunc _move_away_from_infected
Move the agent on the cell away from an infected neighboring cell.
Definition SEIRD.hh:700
CellManager _cm
The cell manager.
Definition SEIRD.hh:70
typename CellManager::RuleFunc RuleFunc
Rule function type.
Definition SEIRD.hh:62
std::uniform_real_distribution< double > _prob_distr
The range [0, 1] distribution to use for probability checks.
Definition SEIRD.hh:76
void perform_step()
Iterate a single time step.
Definition SEIRD.hh:779
SEIRD(const std::string &name, ParentModel &parent_model, const DataIO::Config &custom_cfg={})
Construct the SEIRD model.
Definition SEIRD.hh:136
void exposure_control()
Apply exposure control.
Definition SEIRD.hh:311
void update_densities()
Update the densities array.
Definition SEIRD.hh:268
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
RuleFunc _update
Define the update rule.
Definition SEIRD.hh:480
YAML::Node Config
Type of a variadic dictionary-like data structure used throughout Utopia.
Definition types.hh:71
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
@ neighbors
Iterate over neighbors (adjacent_vertices).
@ condition
Select if a condition is fulfilled.
@ sample
Select a random sample of entities with a known sample size.
Definition counters.hh:10
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)
@ recovered
Cell is recovered.
@ infected
Cell is infected.
@ deceased
Cell is deceased.
@ exposed
Cell is exposed to the dease but not yet infected.
@ susceptible
Cell represents a susceptible.
EntityContainer< CellType > CellContainer
Type of the variably sized container for cells.
Definition types.hh:26
The entity traits struct gathers types to be used for specializing an entity.
Definition entity.hh:49
Wrapper struct for defining model class data types.
Definition model.hh:92
A struct holding counters for state transitions and other global counters.
Definition counters.hh:21
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
const auto & labels()
The labels cooresponding to each entry of the counts array.
Definition counters.hh:58
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
static constexpr std::size_t size
Number of counters.
Definition counters.hh:25
void increment_move_randomly()
Increment counter for random movement events.
Definition counters.hh:108
void increment_susceptible_to_exposed_controlled()
Increment counter for transitions from susceptible to exposed (control)
Definition counters.hh:83
void increment_infected_to_deceased()
Increment counter for transitions from infected to deceased.
Definition counters.hh:98
auto counts()
Return a copy of the current value of all counts.
Definition counters.hh:53
void increment_living_to_empty()
Increment counter for transitions from living to empty.
Definition counters.hh:68
void increment_move_away_from_infected()
Increment counter for movement events away from an infected agent.
Definition counters.hh:113
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
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
const bool enabled
Whether exposure control is enabled.
Definition params.hh:26
TimesValuesQueue change_p_exposed
Change p_expose to new value at given times.
Definition params.hh:39
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 bool enabled
Whether immunity control is enabled.
Definition params.hh:111
Parameters of the SEIRD.
Definition params.hh:261
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 ImmunityContParams immunity_control
Immunity control parameters.
Definition params.hh:305
bool move_away_from_infected
Whether to globally allow moving away from infected neighboring cells.
Definition params.hh:296
double p_move_randomly
Probability to move randomly if the neighboring cell is empty.
Definition params.hh:299
const double p_random_immunity
Definition params.hh:270
double p_immune
Probability per transition to susceptible via p_susceptible to be immune.
Definition params.hh:266
double p_exposed
Definition params.hh:274
const TransmitContParams transmission_control
Transmit control parameters.
Definition params.hh:308
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
const ExposureContParams exposure_control
Exposure control parameters.
Definition params.hh:302
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
const bool enabled
Whether immunity control is enabled.
Definition params.hh:197
TimesValuesQueue change_p_transmit
Change p_transmit to new value at given times.
Definition params.hh:205