Line data Source code
1 : /* 2 : * Copyright (C) 2020-2024 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 5616 : CellIndex(size_t i) 62 5616 : : mio::Index<CellIndex>(i) 63 : { 64 5616 : } 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 1468 : CellCapacity() 77 1468 : : volume(0) 78 1468 : , persons(std::numeric_limits<int>::max()) 79 : { 80 1468 : } 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] num_cells [Default: 1] The number of Cell%s in which the Location is divided. 123 : */ 124 : explicit Location(LocationType loc_type, LocationId loc_id, size_t num_agegroups = 1, uint32_t num_cells = 1); 125 : 126 : /** 127 : * @brief Construct a copy of a Location with a new ID. 128 : * @param[in] other The Location to copy from. 129 : * @param[in] id The ID for the new Location. 130 : */ 131 : explicit Location(const Location& other, LocationId id) 132 : : Location(other) 133 : { 134 : m_id = id; 135 : } 136 : 137 : /** 138 : * @brief Compare two Location%s. 139 : */ 140 36 : bool operator==(const Location& other) const 141 : { 142 36 : return (m_id == other.m_id); 143 : } 144 : 145 : bool operator!=(const Location& other) const 146 : { 147 : return !(*this == other); 148 : } 149 : 150 : /** 151 : * @brief Get the type of this Location. 152 : * @return The #LocationType of the Location. 153 : */ 154 4761 : LocationType get_type() const 155 : { 156 4761 : return m_type; 157 : } 158 : 159 : /** 160 : * @brief Get the location's identifier in a Model. 161 : * @return The location's LocationId by value. 162 : */ 163 47547 : LocationId get_id() const 164 : { 165 47547 : return m_id; 166 : } 167 : 168 : /** 169 : * @brief Get the Location specific Infection parameters. 170 : * @return Parameters of the Infection that are specific to this Location. 171 : * @{ 172 : */ 173 0 : LocalInfectionParameters& get_infection_parameters() 174 : { 175 0 : return m_parameters; 176 : } 177 : 178 2826 : const LocalInfectionParameters& get_infection_parameters() const 179 : { 180 2826 : return m_parameters; 181 : } 182 : /** @} */ 183 : 184 : /** 185 : * @brief Get the Cell%s of this Location. 186 : * @return The vector of all Cell%s of the Location. 187 : */ 188 9738 : const std::vector<Cell>& get_cells() const 189 : { 190 9738 : return m_cells; 191 : } 192 : 193 : /** 194 : * @brief Get the type of Mask that is demanded when entering this Location. 195 : * @return Least secure MaskType that is demanded when entering this Location. 196 : */ 197 54 : MaskType get_required_mask() const 198 : { 199 54 : return m_required_mask; 200 : } 201 : 202 : /** 203 : * @brief Set the required type of mask for entering this Location. 204 : * @param[in] type The Least secure MaskType that is demanded when entering this Location. 205 : */ 206 27 : void set_required_mask(MaskType type) 207 : { 208 27 : m_required_mask = type; 209 27 : } 210 : 211 : /** 212 : * @brief Set the CellCapacity of a Cell in the Location in persons and volume. 213 : * @param[in] persons Maximum number of Person%s that can visit the Cell at the same time. 214 : * @param[in] volume Volume of the Cell in m^3. 215 : * @param[in] cell_idx Index of the Cell. 216 : */ 217 189 : void set_capacity(uint32_t persons, uint32_t volume, uint32_t cell_idx = 0) 218 : { 219 189 : assert(cell_idx < m_cells.size() && "Given cell index is too large."); 220 189 : m_cells[cell_idx].m_capacity.persons = persons; 221 189 : m_cells[cell_idx].m_capacity.volume = volume; 222 189 : } 223 : 224 : /** 225 : * @brief Get the capacity of a specific Cell in persons and volume. 226 : * @param[in] cell_idx The index of the Cell. 227 : * @return The CellCapacity of the Cell. 228 : */ 229 243 : CellCapacity get_capacity(uint32_t cell_idx = 0) const 230 : { 231 243 : assert(cell_idx < m_cells.size() && "Given cell index is too large."); 232 243 : return m_cells[cell_idx].m_capacity; 233 : } 234 : 235 : /** 236 : * @brief Get the information whether masks are required to enter this Location. 237 : * @return True if masks are required to enter this Location. 238 : */ 239 9306 : bool is_mask_required() const 240 : { 241 9306 : return m_required_mask != MaskType::None; 242 : } 243 : 244 : /** 245 : * @brief Get the geographical location of the Location. 246 : * @return The geographical location of the Location. 247 : */ 248 90 : GeographicalLocation get_geographical_location() const 249 : { 250 90 : return m_geographical_location; 251 : } 252 : 253 : /** 254 : * @brief Set the geographical location of the Location. 255 : * @param[in] location The geographical location of the Location. 256 : */ 257 9 : void set_geographical_location(GeographicalLocation location) 258 : { 259 9 : m_geographical_location = location; 260 9 : } 261 : 262 : /// This method is used by the default serialization feature. 263 18 : auto default_serialize() 264 : { 265 36 : return Members("Location") 266 54 : .add("type", m_type) 267 54 : .add("id", m_id) 268 54 : .add("parameters", m_parameters) 269 54 : .add("cells", m_cells) 270 54 : .add("required_mask", m_required_mask) 271 54 : .add("geographical_location", m_geographical_location); 272 : } 273 : 274 : private: 275 : friend DefaultFactory<Location>; 276 9 : Location() = default; 277 : 278 : LocationType m_type; ///< Type of the Location. 279 : LocationId m_id; ///< Unique identifier for the Location in the Model owning it. 280 : LocalInfectionParameters m_parameters; ///< Infection parameters for the Location. 281 : std::vector<Cell> m_cells{}; ///< A vector of all Cell%s that the Location is divided in. 282 : MaskType m_required_mask; ///< Least secure type of Mask that is needed to enter the Location. 283 : GeographicalLocation m_geographical_location; ///< Geographical location (longitude and latitude) of the Location. 284 : }; 285 : 286 : } // namespace abm 287 : } // namespace mio 288 : 289 : #endif