Line data Source code
1 : /* 2 : * Copyright (C) 2020-2025 MEmilio 3 : * 4 : * Authors: Daniel Abele, Elisabeth Kluth, Khoa Nguyen, David Kerkmann 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_LOCATION_H 21 : #define MIO_ABM_LOCATION_H 22 : 23 : #include "abm/location_id.h" 24 : #include "abm/mask_type.h" 25 : #include "abm/parameters.h" 26 : #include "abm/location_type.h" 27 : 28 : #include "memilio/io/default_serialize.h" 29 : #include "boost/atomic/atomic.hpp" 30 : 31 : namespace mio 32 : { 33 : namespace abm 34 : { 35 : 36 : struct GeographicalLocation { 37 : double latitude; 38 : double longitude; 39 : 40 : /** 41 : * @brief Compare two GeographicalLocation%s. 42 : */ 43 9 : bool operator==(const GeographicalLocation& other) const 44 : { 45 9 : return (latitude == other.latitude && longitude == other.longitude); 46 : } 47 : 48 : bool operator!=(const GeographicalLocation& other) const 49 : { 50 : return !(latitude == other.latitude && longitude == other.longitude); 51 : } 52 : 53 : /// This method is used by the default serialization feature. 54 18 : auto default_serialize() 55 : { 56 36 : return Members("GraphicalLocation").add("latitude", latitude).add("longitude", longitude); 57 : } 58 : }; 59 : 60 : struct CellIndex : public mio::Index<CellIndex> { 61 5893 : CellIndex(size_t i) 62 5893 : : mio::Index<CellIndex>(i) 63 : { 64 5893 : } 65 : }; 66 : 67 : using ContactExposureRates = CustomIndexArray<boost::atomic<ScalarType>, CellIndex, VirusVariant, AgeGroup>; 68 : using AirExposureRates = CustomIndexArray<boost::atomic<ScalarType>, CellIndex, VirusVariant>; 69 : 70 : /** 71 : * @brief CellCapacity describes the size of a Cell. 72 : * It consists of a volume and a capacity in Person%s which is an upper bound for the number 73 : * of people that can be in the Cell at the same time. 74 : */ 75 : struct CellCapacity { 76 1534 : CellCapacity() 77 1534 : : volume(0) 78 1534 : , persons(std::numeric_limits<int>::max()) 79 : { 80 1534 : } 81 : uint32_t volume; ///< Volume of the Cell. 82 : uint32_t persons; ///< Maximal number of Person%s at the Cell. 83 : 84 : /// This method is used by the default serialization feature. 85 18 : auto default_serialize() 86 : { 87 36 : return Members("CellCapacity").add("volume", volume).add("persons", persons); 88 : } 89 : }; 90 : 91 : /** 92 : * @brief The Location can be split up into several Cell%s. 93 : * This allows a finer division of the people at the Location. 94 : */ 95 : struct Cell { 96 : CellCapacity m_capacity; 97 : 98 : /** 99 : * @brief Computes a relative cell size for the Cell. 100 : * @return The relative cell size for the Cell. 101 : */ 102 : ScalarType compute_space_per_person_relative() const; 103 : 104 : /// This method is used by the default serialization feature. 105 18 : auto default_serialize() 106 : { 107 36 : return Members("Cell").add("capacity", m_capacity); 108 : } 109 : }; // namespace mio 110 : 111 : /** 112 : * @brief All Location%s in the simulated Model where Person%s gather. 113 : */ 114 : class Location 115 : { 116 : public: 117 : /** 118 : * @brief Construct a Location with provided parameters. 119 : * @param[in] loc_type The #LocationType. 120 : * @param[in] loc_id The index of the Location in the Model. 121 : * @param[in] num_agegroups [Default: 1] The number of age groups in the model. 122 : * @param[in] model_id [Default: 0] The model id the Location is in. 123 : * @param[in] num_cells [Default: 1] The number of Cell%s in which the Location is divided. 124 : */ 125 : explicit Location(LocationType loc_type, LocationId loc_id, size_t num_agegroups = 1, int model_id = 0, 126 : uint32_t num_cells = 1); 127 : 128 : /** 129 : * @brief Construct a copy of a Location with a new ID. 130 : * @param[in] other The Location to copy from. 131 : * @param[in] id The ID for the new Location. 132 : */ 133 : explicit Location(const Location& other, LocationId id, int model_id = 0) 134 : : Location(other) 135 : { 136 : m_id = id; 137 : m_model_id = model_id; 138 : } 139 : 140 : /** 141 : * @brief Compare two Location%s. 142 : */ 143 36 : bool operator==(const Location& other) const 144 : { 145 36 : return (m_id == other.m_id); 146 : } 147 : 148 : bool operator!=(const Location& other) const 149 : { 150 : return !(*this == other); 151 : } 152 : 153 : /** 154 : * @brief Get the type of this Location. 155 : * @return The #LocationType of the Location. 156 : */ 157 4893 : LocationType get_type() const 158 : { 159 4893 : return m_type; 160 : } 161 : 162 : /** 163 : * @brief Get the location's identifier in a Model. 164 : * @return The location's LocationId by value. 165 : */ 166 42377 : LocationId get_id() const 167 : { 168 42377 : return m_id; 169 : } 170 : 171 : /** 172 : * @brief Get the Location specific Infection parameters. 173 : * @return Parameters of the Infection that are specific to this Location. 174 : * @{ 175 : */ 176 0 : LocalInfectionParameters& get_infection_parameters() 177 : { 178 0 : return m_parameters; 179 : } 180 : 181 2907 : const LocalInfectionParameters& get_infection_parameters() const 182 : { 183 2907 : return m_parameters; 184 : } 185 : /** @} */ 186 : 187 : /** 188 : * @brief Get the Cell%s of this Location. 189 : * @return The vector of all Cell%s of the Location. 190 : */ 191 10127 : const std::vector<Cell>& get_cells() const 192 : { 193 10127 : return m_cells; 194 : } 195 : 196 : /** 197 : * @brief Get the type of Mask that is demanded when entering this Location. 198 : * @return Least secure MaskType that is demanded when entering this Location. 199 : */ 200 58 : MaskType get_required_mask() const 201 : { 202 58 : return m_required_mask; 203 : } 204 : 205 : /** 206 : * @brief Set the required type of mask for entering this Location. 207 : * @param[in] type The Least secure MaskType that is demanded when entering this Location. 208 : */ 209 29 : void set_required_mask(MaskType type) 210 : { 211 29 : m_required_mask = type; 212 29 : } 213 : 214 : /** 215 : * @brief Set the CellCapacity of a Cell in the Location in persons and volume. 216 : * @param[in] persons Maximum number of Person%s that can visit the Cell at the same time. 217 : * @param[in] volume Volume of the Cell in m^3. 218 : * @param[in] cell_idx Index of the Cell. 219 : */ 220 189 : void set_capacity(uint32_t persons, uint32_t volume, uint32_t cell_idx = 0) 221 : { 222 189 : assert(cell_idx < m_cells.size() && "Given cell index is too large."); 223 189 : m_cells[cell_idx].m_capacity.persons = persons; 224 189 : m_cells[cell_idx].m_capacity.volume = volume; 225 189 : } 226 : 227 : /** 228 : * @brief Get the capacity of a specific Cell in persons and volume. 229 : * @param[in] cell_idx The index of the Cell. 230 : * @return The CellCapacity of the Cell. 231 : */ 232 263 : CellCapacity get_capacity(uint32_t cell_idx = 0) const 233 : { 234 263 : assert(cell_idx < m_cells.size() && "Given cell index is too large."); 235 263 : return m_cells[cell_idx].m_capacity; 236 : } 237 : 238 : /** 239 : * @brief Get the information whether masks are required to enter this Location. 240 : * @return True if masks are required to enter this Location. 241 : */ 242 9506 : bool is_mask_required() const 243 : { 244 9506 : return m_required_mask != MaskType::None; 245 : } 246 : 247 : /** 248 : * @brief Get the geographical location of the Location. 249 : * @return The geographical location of the Location. 250 : */ 251 90 : GeographicalLocation get_geographical_location() const 252 : { 253 90 : return m_geographical_location; 254 : } 255 : 256 : /** 257 : * @brief Set the geographical location of the Location. 258 : * @param[in] location The geographical location of the Location. 259 : */ 260 9 : void set_geographical_location(GeographicalLocation location) 261 : { 262 9 : m_geographical_location = location; 263 9 : } 264 : 265 : /// This method is used by the default serialization feature. 266 18 : auto default_serialize() 267 : { 268 36 : return Members("Location") 269 54 : .add("type", m_type) 270 54 : .add("id", m_id) 271 54 : .add("parameters", m_parameters) 272 54 : .add("cells", m_cells) 273 54 : .add("required_mask", m_required_mask) 274 54 : .add("geographical_location", m_geographical_location); 275 : } 276 : 277 : /** 278 : * @brief Get the model id the location is in. Is only relevant for graph ABM or hybrid model. 279 : * @return Model id of the location 280 : */ 281 1417 : int get_model_id() const 282 : { 283 1417 : return m_model_id; 284 : } 285 : 286 : private: 287 : friend DefaultFactory<Location>; 288 9 : Location() = default; 289 : 290 : LocationType m_type; ///< Type of the Location. 291 : LocationId m_id; ///< Unique identifier for the Location in the Model owning it. 292 : LocalInfectionParameters m_parameters; ///< Infection parameters for the Location. 293 : std::vector<Cell> m_cells{}; ///< A vector of all Cell%s that the Location is divided in. 294 : MaskType m_required_mask; ///< Least secure type of Mask that is needed to enter the Location. 295 : GeographicalLocation m_geographical_location; ///< Geographical location (longitude and latitude) of the Location. 296 : int m_model_id; ///< Model id the location is in. Only used for ABM graph model or hybrid graph model. 297 : }; 298 : 299 : } // namespace abm 300 : } // namespace mio 301 : 302 : #endif