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 
21 #ifndef MIO_ABM_GRAPH_ABMODEL_H
22 #define MIO_ABM_GRAPH_ABMODEL_H
23 
24 #include "abm/location_type.h"
25 #include "abm/model.h"
26 #include "abm/person_id.h"
27 #include "abm/time.h"
28 #include "abm/location_id.h"
30 #include "memilio/utils/logging.h"
31 #include "memilio/utils/mioomp.h"
32 #include "abm/mobility_rules.h"
33 #include "abm/mobility_rules.h"
34 #include <cstddef>
35 #include <cstdint>
36 #include <list>
37 #include <vector>
38 
39 namespace mio
40 {
41 using namespace abm;
42 class GraphABModel : public abm::Model
43 {
44  using Base = Model;
45 
46 public:
47  GraphABModel(size_t num_agegroups, int id,
48  std::vector<Base::MobilityRuleType> mobility_rules =
49  std::vector<Base::MobilityRuleType>{&get_buried, &return_home_when_recovered, &go_to_hospital,
52  : Base(num_agegroups, id)
53  {
54  Base::m_mobility_rules = mobility_rules;
55  }
56 
60  std::vector<size_t>& get_person_buffer()
61  {
62  return m_person_buffer;
63  }
64 
69  void remove_person(size_t pos)
70  {
71  Base::m_persons.erase(Base::m_persons.begin() + pos);
72  Base::m_activeness_statuses.erase(Base::m_activeness_statuses.begin() + pos);
73  Base::m_person_ids_equal_index = false;
74  }
75 
82  {
83  Base::begin_step(t, dt);
84  log_info("Graph ABM Model interaction.");
85  Base::interaction(t, dt);
86  log_info("Graph ABM Model mobility.");
87  perform_mobility(t, dt);
88  }
89 
90 private:
92  {
93  const uint32_t num_persons = static_cast<uint32_t>(Base::m_persons.size());
94  for (uint32_t person_index = 0; person_index < num_persons; ++person_index) {
95  if (Base::m_activeness_statuses[person_index]) {
96  Person& person = Base::m_persons[person_index];
97  auto personal_rng = PersonalRandomNumberGenerator(person);
98 
99  auto try_mobility_rule = [&](auto rule) -> bool {
100  //run mobility rule and check if change of location can actually happen
101  auto target_type = rule(personal_rng, person, t, dt, parameters);
102  if (person.get_assigned_location_model_id(target_type) == Base::m_id) {
103  const Location& target_location = Base::get_location(Base::find_location(target_type, person));
104  const LocationId current_location = person.get_location();
105  // the Person cannot move if they do not wear mask as required at targeted location
106  if (target_location.is_mask_required() &&
107  !person.is_compliant(personal_rng, InterventionType::Mask)) {
108  return false;
109  }
110  // the Person cannot move if the capacity of targeted Location is reached
111  if (target_location.get_id() == current_location ||
112  get_number_persons(target_location.get_id()) >= target_location.get_capacity().persons) {
113  return false;
114  }
115  // the Person cannot move if the performed TestingStrategy is positive
116  if (!m_testing_strategy.run_and_check(personal_rng, person, target_location, t)) {
117  return false;
118  }
119  // update worn mask to target location's requirements
120  if (target_location.is_mask_required()) {
121  // if the current MaskProtection level is lower than required, the Person changes mask
122  if (parameters.get<MaskProtection>()[person.get_mask().get_type()] <
123  parameters.get<MaskProtection>()[target_location.get_required_mask()]) {
124  person.set_mask(target_location.get_required_mask(), t);
125  }
126  }
127  else {
128  person.set_mask(MaskType::None, t);
129  }
130  Base::change_location(person, target_location.get_id());
131  return true;
132  }
133  else { //person moves to other world
134  Base::m_activeness_statuses[person_index] = false;
135  person.set_location(target_type, abm::LocationId::invalid_id(),
137  m_person_buffer.push_back(person_index);
138  m_are_exposure_caches_valid = false;
139  m_is_local_population_cache_valid = false;
140  return true;
141  }
142  };
143 
144  for (auto rule : Base::m_mobility_rules) {
145  bool applied = try_mobility_rule(rule);
146  //only use one mobility rule per person
147  if (applied) {
148  break;
149  }
150  }
151  }
152  }
153 
154  // check if a person makes a trip
155  size_t num_trips = Base::m_trip_list.num_trips();
156 
157  for (; Base::m_trip_list.get_current_index() < num_trips &&
158  Base::m_trip_list.get_next_trip_time().seconds() < (t + dt).time_since_midnight().seconds();
159  Base::m_trip_list.increase_index()) {
160  auto& trip = Base::m_trip_list.get_next_trip();
161  auto& person = get_person(trip.person_id);
162  auto person_index = Base::get_person_index(trip.person_id);
163  auto personal_rng = PersonalRandomNumberGenerator(person);
164  // skip the trip if the person is in quarantine or is dead
165  if (person.is_in_quarantine(t, parameters) || person.get_infection_state(t) == InfectionState::Dead) {
166  continue;
167  }
168  if (trip.destination_model_id == Base::m_id) {
169  auto& target_location = get_location(trip.destination);
170  // skip the trip if the Person wears mask as required at targeted location
171  if (target_location.is_mask_required() && !person.is_compliant(personal_rng, InterventionType::Mask)) {
172  continue;
173  }
174  // skip the trip if the performed TestingStrategy is positive
175  if (!Base::m_testing_strategy.run_and_check(personal_rng, person, target_location, t)) {
176  continue;
177  }
178  // all requirements are met, move to target location
179  change_location(person, target_location.get_id(), trip.trip_mode);
180  // update worn mask to target location's requirements
181  if (target_location.is_mask_required()) {
182  // if the current MaskProtection level is lower than required, the Person changes mask
183  if (parameters.get<MaskProtection>()[person.get_mask().get_type()] <
184  parameters.get<MaskProtection>()[target_location.get_required_mask()]) {
185  person.set_mask(target_location.get_required_mask(), t);
186  }
187  }
188  else {
189  person.set_mask(MaskType::None, t);
190  }
191  }
192  else { //person moves to other world
193  Base::m_activeness_statuses[person_index] = false;
194  person.set_location(abm::LocationType::Invalid, trip.destination, std::numeric_limits<int>::max());
195  m_person_buffer.push_back(person_index);
196  m_are_exposure_caches_valid = false;
197  m_is_local_population_cache_valid = false;
198  }
199  }
200  if (((t).days() < std::floor((t + dt).days()))) {
201  Base::m_trip_list.reset_index();
202  }
203  }
204 
205  std::vector<size_t> m_person_buffer;
206 };
207 } // namespace mio
208 
209 #endif //MIO_ABM_GRAPH_ABMODEL_H
Definition: graph_abmodel.h:43
std::vector< size_t > m_person_buffer
List with indices of persons that are subject to move to another node.
Definition: graph_abmodel.h:205
void evolve(TimePoint t, TimeSpan dt)
Evolve the Graph Model one time step.
Definition: graph_abmodel.h:81
void perform_mobility(TimePoint t, TimeSpan dt)
Definition: graph_abmodel.h:91
std::vector< size_t > & get_person_buffer()
Get person buffer.
Definition: graph_abmodel.h:60
void remove_person(size_t pos)
Removes person from the model.
Definition: graph_abmodel.h:69
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:47
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
Agents in the simulated Model that can carry and spread the Infection.
Definition: person.h:51
void set_location(LocationType type, LocationId id, int model_id)
Change the location of the person.
Definition: person.cpp:101
Mask & get_mask()
Get the current Mask of the Person.
Definition: person.h:299
int get_assigned_location_model_id(LocationType type) const
Returns the model id of an assigned location of the Person.
Definition: person.cpp:130
bool is_compliant(PersonalRandomNumberGenerator &rng, InterventionType intervention) const
Checks whether the Person complies an Intervention.
Definition: person.cpp:222
LocationId get_location() const
Get the current Location of the Person.
Definition: person.cpp:96
void set_mask(MaskType type, TimePoint t)
Change the mask to new type.
Definition: person.cpp:267
Random number generator of individual persons.
Definition: personal_rng.h:50
Represents a point in time.
Definition: time.h:175
A duration of time.
Definition: time.h:36
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
bool change_location(Person &person, const Location &destination, const TransportMode mode, const std::vector< uint32_t > &cells)
Change a persons location to another location.
Definition: model_functions.cpp:162
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:94
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