Line data Source code
1 : /*
2 : * Copyright (C) 2020-2024 MEmilio
3 : *
4 : * Authors: Daniel Abele, Majid Abedi, Elisabeth Kluth, Khoa Nguyen
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 : #include "abm/mobility_rules.h"
21 : #include "abm/person.h"
22 : #include "abm/random_events.h"
23 : #include "abm/location_type.h"
24 :
25 : namespace mio
26 : {
27 : namespace abm
28 : {
29 :
30 27 : LocationType random_mobility(PersonalRandomNumberGenerator& rng, const Person& person, TimePoint t, TimeSpan dt,
31 : const Parameters& params)
32 : {
33 27 : auto current_loc = person.get_location_type();
34 27 : auto make_transition = [current_loc](auto l) {
35 90 : return std::make_pair(l, l == current_loc ? 0. : 1.);
36 27 : };
37 27 : if (t < params.get<LockdownDate>()) {
38 54 : return random_transition(rng, current_loc, dt,
39 18 : {make_transition(LocationType::Work), make_transition(LocationType::Home),
40 18 : make_transition(LocationType::School), make_transition(LocationType::SocialEvent),
41 36 : make_transition(LocationType::BasicsShop)});
42 : }
43 9 : return current_loc;
44 : }
45 :
46 855 : LocationType go_to_school(PersonalRandomNumberGenerator& /*rng*/, const Person& person, TimePoint t, TimeSpan dt,
47 : const Parameters& params)
48 : {
49 855 : auto current_loc = person.get_location_type();
50 :
51 2565 : if (current_loc == LocationType::Home && t < params.get<LockdownDate>() && t.day_of_week() < 5 &&
52 2277 : person.get_go_to_school_time(params) >= t.time_since_midnight() &&
53 1287 : person.get_go_to_school_time(params) < t.time_since_midnight() + dt &&
54 2610 : params.get<mio::abm::AgeGroupGotoSchool>()[person.get_age()] && person.goes_to_school(t, params) &&
55 1035 : !person.is_in_quarantine(t, params)) {
56 90 : return LocationType::School;
57 : }
58 : //return home
59 765 : if (current_loc == LocationType::School && t.hour_of_day() >= 15) {
60 9 : return LocationType::Home;
61 : }
62 756 : return current_loc;
63 : }
64 :
65 972 : LocationType go_to_work(PersonalRandomNumberGenerator& /*rng*/, const Person& person, TimePoint t, TimeSpan dt,
66 : const Parameters& params)
67 : {
68 972 : auto current_loc = person.get_location_type();
69 :
70 2916 : if (current_loc == LocationType::Home && t < params.get<LockdownDate>() &&
71 2628 : params.get<mio::abm::AgeGroupGotoWork>()[person.get_age()] && t.day_of_week() < 5 &&
72 1278 : t.time_since_midnight() + dt > person.get_go_to_work_time(params) &&
73 2916 : t.time_since_midnight() <= person.get_go_to_work_time(params) && person.goes_to_work(t, params) &&
74 1170 : !person.is_in_quarantine(t, params)) {
75 90 : return LocationType::Work;
76 : }
77 : //return home
78 882 : if (current_loc == LocationType::Work && t.hour_of_day() >= 17) {
79 9 : return LocationType::Home;
80 : }
81 873 : return current_loc;
82 : }
83 :
84 684 : LocationType go_to_shop(PersonalRandomNumberGenerator& rng, const Person& person, TimePoint t, TimeSpan dt,
85 : const Parameters& params)
86 : {
87 684 : auto current_loc = person.get_location_type();
88 : //leave
89 2097 : if (t.day_of_week() < 6 && t.hour_of_day() > 7 && t.hour_of_day() < 22 && current_loc == LocationType::Home &&
90 1413 : !person.is_in_quarantine(t, params)) {
91 729 : return random_transition(rng, current_loc, dt,
92 729 : {{LocationType::BasicsShop, params.get<BasicShoppingRate>()[person.get_age()]}});
93 : }
94 :
95 : //return home
96 441 : if (current_loc == LocationType::BasicsShop && person.get_time_at_location() >= hours(1)) {
97 27 : return LocationType::Home;
98 : }
99 :
100 414 : return current_loc;
101 : }
102 :
103 783 : LocationType go_to_event(PersonalRandomNumberGenerator& rng, const Person& person, TimePoint t, TimeSpan dt,
104 : const Parameters& params)
105 : {
106 783 : auto current_loc = person.get_location_type();
107 : //leave
108 1881 : if (current_loc == LocationType::Home && t < params.get<LockdownDate>() &&
109 2007 : ((t.day_of_week() <= 4 && t.hour_of_day() >= 19) || (t.day_of_week() >= 5 && t.hour_of_day() >= 10)) &&
110 1161 : !person.is_in_quarantine(t, params)) {
111 378 : return random_transition(rng, current_loc, dt,
112 252 : {{LocationType::SocialEvent,
113 378 : params.get<SocialEventRate>().get_matrix_at(t.days())[(size_t)person.get_age()]}});
114 : }
115 :
116 : //return home
117 1332 : if (current_loc == LocationType::SocialEvent && t.hour_of_day() >= 20 &&
118 675 : person.get_time_at_location() >= hours(2)) {
119 9 : return LocationType::Home;
120 : }
121 :
122 648 : return current_loc;
123 : }
124 :
125 846 : LocationType go_to_quarantine(PersonalRandomNumberGenerator& /*rng*/, const Person& person, TimePoint t,
126 : TimeSpan /*dt*/, const Parameters& params)
127 : {
128 846 : auto current_loc = person.get_location_type();
129 846 : if (person.is_in_quarantine(t, params) && current_loc != LocationType::Hospital &&
130 : current_loc != LocationType::ICU) {
131 9 : return LocationType::Home;
132 : }
133 837 : return current_loc;
134 : }
135 :
136 792 : LocationType go_to_hospital(PersonalRandomNumberGenerator& /*rng*/, const Person& person, const TimePoint t,
137 : TimeSpan /*dt*/, const Parameters& /*params*/)
138 : {
139 792 : auto current_loc = person.get_location_type();
140 792 : if (person.get_infection_state(t) == InfectionState::InfectedSevere) {
141 27 : return LocationType::Hospital;
142 : }
143 765 : return current_loc;
144 : }
145 :
146 675 : LocationType go_to_icu(PersonalRandomNumberGenerator& /*rng*/, const Person& person, const TimePoint t, TimeSpan /*dt*/,
147 : const Parameters& /*params*/)
148 : {
149 675 : auto current_loc = person.get_location_type();
150 675 : if (person.get_infection_state(t) == InfectionState::InfectedCritical) {
151 9 : return LocationType::ICU;
152 : }
153 666 : return current_loc;
154 : }
155 :
156 936 : LocationType return_home_when_recovered(PersonalRandomNumberGenerator& /*rng*/, const Person& person, const TimePoint t,
157 : TimeSpan /*dt*/, const Parameters& /*params*/)
158 : {
159 936 : auto current_loc = person.get_location_type();
160 2061 : if ((current_loc == LocationType::Hospital || current_loc == LocationType::ICU) &&
161 1125 : person.get_infection_state(t) == InfectionState::Recovered) {
162 27 : return LocationType::Home;
163 : }
164 909 : return current_loc;
165 : }
166 :
167 2781 : LocationType get_buried(PersonalRandomNumberGenerator& /*rng*/, const Person& person, const TimePoint t,
168 : TimeSpan /*dt*/, const Parameters& /*params*/)
169 : {
170 2781 : auto current_loc = person.get_location_type();
171 2781 : if (person.get_infection_state(t) == InfectionState::Dead) {
172 252 : return LocationType::Cemetery;
173 : }
174 2529 : return current_loc;
175 : }
176 :
177 : } // namespace abm
178 : } // namespace mio
|