graph_abmodel.h Source File

CPP API: graph_abmodel.h Source File
graph_abmodel.h
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2020-2026 MEmilio
3 *
4 * Authors: Julia Bicker
5 *
6 * Contact: Martin J. Kuehn <Martin.Kuehn@DLR.de>
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20 #ifndef MIO_ABM_GRAPH_ABMODEL_H
21 #define MIO_ABM_GRAPH_ABMODEL_H
22 
23 #include "abm/location_type.h"
24 #include "abm/model.h"
25 #include "abm/person_id.h"
26 #include "abm/time.h"
27 #include "abm/location_id.h"
28 #include "memilio/utils/logging.h"
29 #include "abm/mobility_rules.h"
30 #include "abm/mobility_rules.h"
31 #include <cstdint>
32 #include <vector>
33 
34 namespace mio
35 {
36 namespace abm
37 {
38 
39 class GraphABModel : public abm::Model
40 {
41  using Base = Model;
42 
43 public:
44  GraphABModel(size_t num_agegroups, int id,
45  std::vector<Base::MobilityRuleType> mobility_rules =
46  std::vector<Base::MobilityRuleType>{&get_buried, &return_home_when_recovered, &go_to_hospital,
49  : Base(num_agegroups, id)
50  {
51  Base::m_mobility_rules = mobility_rules;
52  }
53 
57  std::vector<size_t>& get_person_buffer()
58  {
59  return m_person_buffer;
60  }
61 
66  void remove_person(size_t pos)
67  {
68  Base::m_persons.erase(Base::m_persons.begin() + pos);
71  }
72 
79  {
80  Base::begin_step(t, dt);
81  log_info("Graph ABM Model interaction.");
82  Base::interaction(t, dt);
83  log_info("Graph ABM Model mobility.");
84  perform_mobility(t, dt);
85  }
86 
87 private:
89  {
90  const uint32_t num_persons = static_cast<uint32_t>(Base::m_persons.size());
91  for (uint32_t person_index = 0; person_index < num_persons; ++person_index) {
92  if (Base::m_activeness_statuses[person_index]) {
93  Person& person = Base::m_persons[person_index];
94  auto personal_rng = PersonalRandomNumberGenerator(Base::get_rng(), person);
95 
96  auto try_mobility_rule = [&](auto rule) -> bool {
97  //run mobility rule and check if change of location can actually happen
98  auto target_type = rule(personal_rng, person, t, dt, parameters);
99  if (person.get_assigned_location_model_id(target_type) == Base::m_id) {
100  const Location& target_location = Base::get_location(Base::find_location(target_type, person));
101  const LocationId current_location = person.get_location();
102  // the Person cannot move if they do not wear mask as required at targeted location
103  if (target_location.is_mask_required() &&
104  !person.is_compliant(personal_rng, InterventionType::Mask)) {
105  return false;
106  }
107  // the Person cannot move if the capacity of targeted Location is reached
108  if (target_location.get_id() == current_location ||
109  get_number_persons(target_location.get_id()) >= target_location.get_capacity().persons) {
110  return false;
111  }
112  // the Person cannot move if the performed TestingStrategy is positive
113  if (!m_testing_strategy.run_and_check(personal_rng, person, target_location, t)) {
114  return false;
115  }
116  // update worn mask to target location's requirements
117  if (target_location.is_mask_required()) {
118  // if the current MaskProtection level is lower than required, the Person changes mask
119  if (parameters.get<MaskProtection>()[person.get_mask().get_type()] <
120  parameters.get<MaskProtection>()[target_location.get_required_mask()]) {
121  person.set_mask(target_location.get_required_mask(), t);
122  }
123  }
124  else {
125  person.set_mask(MaskType::None, t);
126  }
127  Base::change_location(person, target_location.get_id());
128  return true;
129  }
130  else { //person moves to other world
131  Base::m_activeness_statuses[person_index] = false;
132  person.set_location(target_type, abm::LocationId::invalid_id(),
134  m_person_buffer.push_back(person_index);
137  return true;
138  }
139  };
140 
141  for (auto rule : Base::m_mobility_rules) {
142  bool applied = try_mobility_rule(rule);
143  //only use one mobility rule per person
144  if (applied) {
145  break;
146  }
147  }
148  }
149  }
150 
151  // check if a person makes a trip
152  size_t num_trips = Base::m_trip_list.num_trips();
153 
154  for (; Base::m_trip_list.get_current_index() < num_trips &&
155  Base::m_trip_list.get_next_trip_time().seconds() < (t + dt).time_since_midnight().seconds();
157  auto& trip = Base::m_trip_list.get_next_trip();
158  auto& person = get_person(trip.person_id);
159  auto person_index = Base::get_person_index(trip.person_id);
160  auto personal_rng = PersonalRandomNumberGenerator(Base::get_rng(), person);
161  // skip the trip if the person is in quarantine or is dead
162  if (person.is_in_quarantine(t, parameters) || person.get_infection_state(t) == InfectionState::Dead) {
163  continue;
164  }
165  if (trip.destination_model_id == Base::m_id) {
166  auto& target_location = get_location(trip.destination);
167  // skip the trip if the Person wears mask as required at targeted location
168  if (target_location.is_mask_required() && !person.is_compliant(personal_rng, InterventionType::Mask)) {
169  continue;
170  }
171  // skip the trip if the performed TestingStrategy is positive
172  if (!Base::m_testing_strategy.run_and_check(personal_rng, person, target_location, t)) {
173  continue;
174  }
175  // all requirements are met, move to target location
176  change_location(person, target_location.get_id(), trip.trip_mode);
177  // update worn mask to target location's requirements
178  if (target_location.is_mask_required()) {
179  // if the current MaskProtection level is lower than required, the Person changes mask
180  if (parameters.get<MaskProtection>()[person.get_mask().get_type()] <
181  parameters.get<MaskProtection>()[target_location.get_required_mask()]) {
182  person.set_mask(target_location.get_required_mask(), t);
183  }
184  }
185  else {
186  person.set_mask(MaskType::None, t);
187  }
188  }
189  else { //person moves to other world
190  Base::m_activeness_statuses[person_index] = false;
191  person.set_location(abm::LocationType::Invalid, trip.destination, std::numeric_limits<int>::max());
192  m_person_buffer.push_back(person_index);
195  }
196  }
197  if (((t).days() < std::floor((t + dt).days()))) {
199  }
200  }
201 
202  std::vector<size_t> m_person_buffer;
203 };
204 
205 } // namespace abm
206 } // namespace mio
207 
208 #endif //MIO_ABM_GRAPH_ABMODEL_H
const ParameterTagTraits< Tag >::Type & get() const
get value of a parameter
Definition: parameter_set.h:262
Definition: graph_abmodel.h:40
void evolve(TimePoint t, TimeSpan dt)
Evolve the Graph Model one time step.
Definition: graph_abmodel.h:78
GraphABModel(size_t num_agegroups, int id, std::vector< Base::MobilityRuleType > mobility_rules=std::vector< Base::MobilityRuleType >{&get_buried, &return_home_when_recovered, &go_to_hospital, &go_to_icu, &go_to_school, &go_to_work, &go_to_shop, &go_to_event, &go_to_quarantine})
Definition: graph_abmodel.h:44
std::vector< size_t > & get_person_buffer()
Get person buffer.
Definition: graph_abmodel.h:57
std::vector< size_t > m_person_buffer
List with indices of persons that are subject to move to another node.
Definition: graph_abmodel.h:202
Model Base
Definition: graph_abmodel.h:41
void remove_person(size_t pos)
Removes person from the model.
Definition: graph_abmodel.h:66
void perform_mobility(TimePoint t, TimeSpan dt)
Definition: graph_abmodel.h:88
All Locations in the simulated Model where Persons gather.
Definition: location.h:92
LocationId get_id() const
Get the location's identifier in a Model.
Definition: location.h:143
bool is_mask_required() const
Get the information whether masks are required to enter this Location.
Definition: location.h:219
CellCapacity get_capacity(uint32_t cell_idx=0) const
Get the capacity of a specific Cell in persons and volume.
Definition: location.h:209
MaskType get_required_mask() const
Get the type of Mask that is demanded when entering this Location.
Definition: location.h:177
MaskType get_type() const
Get the MaskType of this Mask.
Definition: mask.h:49
The Model of the Simulation.
Definition: abm/model.h:54
TestingStrategy m_testing_strategy
List of TestingSchemes that are checked for testing.
Definition: abm/model.h:695
void interaction(TimePoint t, TimeSpan dt)
Persons interact at their Location and may become infected.
Definition: abm/model.cpp:91
TripList m_trip_list
List of all Trips the Persons do.
Definition: abm/model.h:696
void begin_step(TimePoint t, TimeSpan dt)
Prepare the Model for the next Simulation step.
Definition: abm/model.cpp:337
bool m_person_ids_equal_index
Current number of Persons in a given location.
Definition: abm/model.h:701
uint32_t get_person_index(PersonId person_id) const
Get index of person in m_persons.
Definition: abm/model.h:523
bool m_is_local_population_cache_valid
Current number of Persons in a given location.
Definition: abm/model.h:682
bool m_are_exposure_caches_valid
Current number of Persons in a given location.
Definition: abm/model.h:683
const Person & get_person(PersonId person_id) const
Get a reference to a Person from this Model.
Definition: abm/model.h:385
LocationId find_location(LocationType type, const PersonId person) const
Find an assigned Location of a Person.
Definition: abm/model.cpp:376
Model(size_t num_agegroups, int id=0)
Create a Model.
Definition: abm/model.h:70
int m_id
Model id. Is only used for abm graph model or hybrid model.
Definition: abm/model.h:686
std::vector< MobilityRuleType > m_mobility_rules
Rules that govern the mobility between Locations.
Definition: abm/model.h:698
std::vector< char > m_activeness_statuses
Vector with activeness status for every person.
Definition: abm/model.h:689
const Location & get_location(LocationId id) const
Get a reference to a location in this Model.
Definition: abm/model.h:472
RandomNumberGenerator & get_rng()
Get the RandomNumberGenerator used by this Model for random events.
Definition: abm/model.h:339
Parameters parameters
The simulation parameters of the Model.
Definition: abm/model.h:331
void change_location(PersonId person, LocationId destination, TransportMode mode=TransportMode::Unknown, const std::vector< uint32_t > &cells={0})
Let a Person change to another Location.
Definition: abm/model.h:449
std::vector< Person > m_persons
Vector of every Person.
Definition: abm/model.h:687
size_t get_number_persons(LocationId location) const
Get the total number of Persons at the Location.
Definition: abm/model.h:415
Agents in the simulated Model that can carry and spread the Infection.
Definition: person.h:50
void set_location(LocationType type, LocationId id, int model_id)
Change the location of the person.
Definition: person.cpp:98
Mask & get_mask()
Get the current Mask of the Person.
Definition: person.h:298
int get_assigned_location_model_id(LocationType type) const
Returns the model id of an assigned location of the Person.
Definition: person.cpp:127
bool is_compliant(PersonalRandomNumberGenerator &rng, InterventionType intervention) const
Checks whether the Person complies an Intervention.
Definition: person.cpp:219
LocationId get_location() const
Get the current Location of the Person.
Definition: person.cpp:93
void set_mask(MaskType type, TimePoint t)
Change the mask to new type.
Definition: person.cpp:264
Random number generator of individual persons.
Definition: personal_rng.h:49
bool run_and_check(PersonalRandomNumberGenerator &rng, Person &person, const Location &location, TimePoint t)
Runs the TestingStrategy and potentially tests a Person when entering.
Definition: testing_strategy.cpp:134
Represents a point in time.
Definition: time.h:175
A duration of time.
Definition: time.h:36
uint32_t get_current_index() const
Get the current index.
Definition: trip_list.h:153
const Trip & get_next_trip() const
Get the next Trip.
Definition: trip_list.cpp:29
void reset_index()
Reset the current index to 0.
Definition: trip_list.h:136
size_t num_trips() const
Get the length of the TripList.
Definition: trip_list.h:145
void increase_index()
Increment the current index to select the next Trip.
Definition: trip_list.h:128
static double floor(const ad::internal::active_type< AD_TAPE_REAL, DATA_HANDLER_1 > &x)
Definition: ad.hpp:2451
static min_max_return_type< ad::internal::active_type< AD_TAPE_REAL, DATA_HANDLER_1 >, ad::internal::active_type< AD_TAPE_REAL, DATA_HANDLER_1 > >::type max(const ad::internal::active_type< AD_TAPE_REAL, DATA_HANDLER_1 > &a, const ad::internal::active_type< AD_TAPE_REAL, DATA_HANDLER_1 > &b)
Definition: ad.hpp:2596
LocationType return_home_when_recovered(PersonalRandomNumberGenerator &, const Person &person, const TimePoint t, TimeSpan, const Parameters &)
Persons in the hospital/icu return home when they recover.
Definition: mobility_rules.cpp:159
LocationType go_to_event(PersonalRandomNumberGenerator &rng, const Person &person, TimePoint t, TimeSpan dt, const Parameters &params)
Persons might go to social events.
Definition: mobility_rules.cpp:104
LocationType go_to_school(PersonalRandomNumberGenerator &, const Person &person, TimePoint t, TimeSpan dt, const Parameters &params)
School age children go to school in the morning and return later in the day.
Definition: mobility_rules.cpp:47
LocationType go_to_icu(PersonalRandomNumberGenerator &, const Person &person, const TimePoint t, TimeSpan, const Parameters &)
Persons in the hospital may be put in intensive care.
Definition: mobility_rules.cpp:149
TimeSpan seconds(int seconds)
Create a TimeSpan of a specified number of seconds.
Definition: time.h:321
LocationType go_to_work(PersonalRandomNumberGenerator &, const Person &person, TimePoint t, TimeSpan dt, const Parameters &params)
Adults go to work in the morning and return later in the day.
Definition: mobility_rules.cpp:66
LocationType get_buried(PersonalRandomNumberGenerator &, const Person &person, const TimePoint t, TimeSpan, const Parameters &)
Persons in the icu go to cemetery when they are dead.
Definition: mobility_rules.cpp:170
TimeSpan days(int days)
Create a TimeSpan with a specified number of days.
Definition: time.h:348
LocationType go_to_shop(PersonalRandomNumberGenerator &rng, const Person &person, TimePoint t, TimeSpan dt, const Parameters &params)
Adults may go shopping in their free time.
Definition: mobility_rules.cpp:85
LocationType go_to_hospital(PersonalRandomNumberGenerator &, const Person &person, const TimePoint t, TimeSpan, const Parameters &)
Infected Persons may be hospitalized.
Definition: mobility_rules.cpp:139
LocationType go_to_quarantine(PersonalRandomNumberGenerator &, const Person &person, TimePoint t, TimeSpan, const Parameters &params)
Persons who are in quarantine should go home.
Definition: mobility_rules.cpp:128
A collection of classes to simplify handling of matrix shapes in meta programming.
Definition: models/abm/analyze_result.h:30
requires details::IsElementReference< M > RowMajorIterator< M, false > begin(M &m)
create a non-const iterator to first element of the matrix m.
Definition: eigen_util.h:421
void log_info(spdlog::string_view_t fmt, const Args &... args)
Definition: logging.h:108
uint32_t persons
Maximal number of Persons at the Cell.
Definition: location.h:59
Unique identifier for a Location within a Model.
Definition: location_id.h:34
static const LocationId invalid_id()
Value for invalid IDs.
Definition: location_id.h:48
Effectiveness of a Mask of a certain MaskType% against an Infection%.
Definition: abm/parameters.h:382