Line data Source code
1 : /* 2 : * Copyright (C) 2020-2024 MEmilio 3 : * 4 : * Authors: Daniel Abele, Jan Kleinert, Martin J. Kuehn 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 SEIR_PARAMETERS_H 21 : #define SEIR_PARAMETERS_H 22 : 23 : #include "memilio/config.h" 24 : #include "memilio/epidemiology/age_group.h" 25 : #include "memilio/epidemiology/uncertain_matrix.h" 26 : #include "memilio/utils/custom_index_array.h" 27 : #include "memilio/utils/uncertain_value.h" 28 : #include "memilio/utils/parameter_set.h" 29 : 30 : namespace mio 31 : { 32 : namespace oseir 33 : { 34 : 35 : /*************************************** 36 : * Define Parameters of the SEIR model * 37 : ***************************************/ 38 : 39 : /** 40 : * @brief probability of getting infected from a contact 41 : */ 42 : template <typename FP = double> 43 : struct TransmissionProbabilityOnContact { 44 : using Type = CustomIndexArray<UncertainValue<FP>, AgeGroup>; 45 154 : static Type get_default(AgeGroup size) 46 : { 47 308 : return Type(size, 1.); 48 : } 49 : static std::string name() 50 : { 51 : return "TransmissionProbabilityOnContact"; 52 : } 53 : }; 54 : 55 : /** 56 : * @brief the latent time in day unit 57 : */ 58 : template <typename FP = double> 59 : struct TimeExposed { 60 : using Type = CustomIndexArray<UncertainValue<FP>, AgeGroup>; 61 154 : static Type get_default(AgeGroup size) 62 : { 63 308 : return Type(size, 5.2); 64 : } 65 : static std::string name() 66 : { 67 : return "TimeExposed"; 68 : } 69 : }; 70 : 71 : /** 72 : * @brief the infectious time in day unit 73 : */ 74 : template <typename FP = double> 75 : struct TimeInfected { 76 : using Type = CustomIndexArray<UncertainValue<FP>, AgeGroup>; 77 154 : static Type get_default(AgeGroup size) 78 : { 79 308 : return Type(size, 6.0); 80 : } 81 : static std::string name() 82 : { 83 : return "TimeInfected"; 84 : } 85 : }; 86 : 87 : /** 88 : * @brief the contact patterns within the society are modelled using a ContactMatrix 89 : */ 90 : template <class FP = ScalarType> 91 : struct ContactPatterns { 92 : using Type = UncertainContactMatrix<FP>; 93 154 : static Type get_default(AgeGroup size) 94 : { 95 154 : return Type(1, static_cast<Eigen::Index>((size_t)size)); 96 : } 97 : static std::string name() 98 : { 99 : return "ContactPatterns"; 100 : } 101 : }; 102 : 103 : template <typename FP = double> 104 : using ParametersBase = 105 : ParameterSet<TransmissionProbabilityOnContact<FP>, TimeExposed<FP>, TimeInfected<FP>, ContactPatterns<FP>>; 106 : 107 : /** 108 : * @brief Parameters of an age-resolved SECIR/SECIHURD model. 109 : */ 110 : template <typename FP = double> 111 : class Parameters : public ParametersBase<FP> 112 : { 113 : public: 114 154 : Parameters(AgeGroup num_agegroups) 115 : : ParametersBase<FP>(num_agegroups) 116 154 : , m_num_groups{num_agegroups} 117 : { 118 154 : } 119 : 120 324 : AgeGroup get_num_groups() const 121 : { 122 324 : return m_num_groups; 123 : } 124 : 125 : /** 126 : * @brief Checks whether all Parameters satisfy their corresponding constraints and applies them, if they do not. 127 : * Time spans cannot be negative and probabilities can only take values between [0,1]. 128 : * 129 : * Attention: This function should be used with care. It is necessary for some test problems to run through quickly, 130 : * but in a manual execution of an example, check_constraints() may be preferred. Note that the apply_constraints() 131 : * function can and will not set Parameters to meaningful values in an epidemiological or virological context, 132 : * as all models are designed to be transferable to multiple diseases. Consequently, only acceptable 133 : * (like 0 or 1 for probabilities or small positive values for time spans) values are set here and a manual adaptation 134 : * may often be necessary to have set meaningful values. 135 : * 136 : * @return Returns true if one ore more constraint were corrected, false otherwise. 137 : */ 138 54 : bool apply_constraints() 139 : { 140 54 : const double tol_times = 1e-1; 141 : 142 54 : int corrected = false; 143 : 144 108 : for (auto i = AgeGroup(0); i < AgeGroup(m_num_groups); ++i) { 145 54 : if (this->template get<TimeExposed<FP>>()[i] < tol_times) { 146 18 : log_warning( 147 : "Constraint check: Parameter TimeExposed changed from {:.4f} to {:.4f}. Please note that " 148 : "unreasonably small compartment stays lead to massively increased run time. Consider to cancel " 149 : "and reset parameters.", 150 9 : this->template get<TimeExposed<FP>>()[i], tol_times); 151 9 : this->template get<TimeExposed<FP>>()[i] = tol_times; 152 9 : corrected = true; 153 : } 154 54 : if (this->template get<TimeInfected<FP>>()[i] < tol_times) { 155 18 : log_warning( 156 : "Constraint check: Parameter TimeInfected changed from {:.4f} to {:.4f}. Please note that " 157 : "unreasonably small compartment stays lead to massively increased run time. Consider to cancel " 158 : "and reset parameters.", 159 9 : this->template get<TimeInfected<FP>>()[i], tol_times); 160 9 : this->template get<TimeInfected<FP>>()[i] = tol_times; 161 9 : corrected = true; 162 : } 163 108 : if (this->template get<TransmissionProbabilityOnContact<FP>>()[i] < 0.0 || 164 54 : this->template get<TransmissionProbabilityOnContact<FP>>()[i] > 1.0) { 165 18 : log_warning( 166 : "Constraint check: Parameter TransmissionProbabilityOnContact changed from {:0.4f} to {:d} ", 167 18 : this->template get<TransmissionProbabilityOnContact<FP>>()[i], 0.0); 168 9 : this->template get<TransmissionProbabilityOnContact<FP>>()[i] = 0.0; 169 9 : corrected = true; 170 : } 171 : } 172 54 : return corrected; 173 : } 174 : 175 : /** 176 : * @brief Checks whether all Parameters satisfy their corresponding constraints and logs an error 177 : * if constraints are not satisfied. 178 : * @return Returns true if one constraint is not satisfied, otherwise false. 179 : */ 180 143 : bool check_constraints() const 181 : { 182 143 : const double tol_times = 1e-1; 183 : 184 259 : for (auto i = AgeGroup(0); i < m_num_groups; i++) { 185 143 : if (this->template get<TimeExposed<FP>>()[i] < tol_times) { 186 18 : log_error( 187 : "Constraint check: Parameter TimeExposed {:.4f} smaller or equal {:.4f}. Please note that " 188 : "unreasonably small compartment stays lead to massively increased run time. Consider to cancel " 189 : "and reset parameters.", 190 18 : this->template get<TimeExposed<FP>>()[i], 0.0); 191 9 : return true; 192 : } 193 134 : if (this->template get<TimeInfected<FP>>()[i] < tol_times) { 194 18 : log_error( 195 : "Constraint check: Parameter TimeInfected {:.4f} smaller or equal {:.4f}. Please note that " 196 : "unreasonably small compartment stays lead to massively increased run time. Consider to cancel " 197 : "and reset parameters.", 198 18 : this->template get<TimeInfected<FP>>()[i], 0.0); 199 9 : return true; 200 : } 201 250 : if (this->template get<TransmissionProbabilityOnContact<FP>>()[i] < 0.0 || 202 125 : this->template get<TransmissionProbabilityOnContact<FP>>()[i] > 1.0) { 203 18 : log_error("Constraint check: Parameter TransmissionProbabilityOnContact {:.4f} smaller {:.4f} or " 204 : "greater {:.4f}", 205 18 : this->template get<TransmissionProbabilityOnContact<FP>>()[i], 0.0, 1.0); 206 9 : return true; 207 : } 208 : } 209 116 : return false; 210 : } 211 : 212 : private: 213 : Parameters(ParametersBase<FP>&& base) 214 : : ParametersBase<FP>(std::move(base)) 215 : , m_num_groups(this->template get<ContactPatterns<FP>>().get_cont_freq_mat().get_num_groups()) 216 : { 217 : } 218 : 219 : public: 220 : /** 221 : * deserialize an object of this class. 222 : * @see mio::deserialize 223 : */ 224 : template <class IOContext> 225 : static IOResult<Parameters> deserialize(IOContext& io) 226 : { 227 : BOOST_OUTCOME_TRY(auto&& base, ParametersBase<FP>::deserialize(io)); 228 : return success(Parameters(std::move(base))); 229 : } 230 : 231 : private: 232 : AgeGroup m_num_groups; 233 : }; 234 : } // namespace oseir 235 : } // namespace mio 236 : 237 : #endif // SEIR_PARAMETERS_H