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 SECIR_PARAMETERS_H
21 : #define SECIR_PARAMETERS_H
22 :
23 : #include "memilio/epidemiology/age_group.h"
24 : #include "memilio/epidemiology/dynamic_npis.h"
25 : #include "memilio/epidemiology/uncertain_matrix.h"
26 : #include "memilio/utils/custom_index_array.h"
27 : #include "memilio/utils/parameter_set.h"
28 : #include "memilio/utils/uncertain_value.h"
29 : #include <limits>
30 :
31 : namespace mio
32 : {
33 : namespace osecir
34 : {
35 :
36 : /*******************************************
37 : * Define Parameters of the SECIHURD model *
38 : *******************************************/
39 :
40 : /**
41 : * @brief the start day in the SECIR model
42 : * The start day defines in which season the simulation can be started
43 : * If the start day is 180 and simulation takes place from t0=0 to
44 : * tmax=100 the days 180 to 280 of the year are simulated
45 : */
46 : struct StartDay {
47 : using Type = double;
48 371 : static Type get_default(AgeGroup)
49 : {
50 371 : return 0.;
51 : }
52 32 : static std::string name()
53 : {
54 32 : return "StartDay";
55 : }
56 : };
57 :
58 : /**
59 : * @brief the seasonality in the SECIR model
60 : * the seasonality is given as (1+k*sin()) where the sine
61 : * curve is below one in summer and above one in winter
62 : */
63 : template <typename FP = double>
64 : struct Seasonality {
65 : using Type = UncertainValue<FP>;
66 371 : static Type get_default(AgeGroup)
67 : {
68 371 : return Type(0.);
69 : }
70 32 : static std::string name()
71 : {
72 32 : return "Seasonality";
73 : }
74 : };
75 :
76 : /**
77 : * @brief the icu capacity in the SECIR model
78 : */
79 : template <typename FP = double>
80 : struct ICUCapacity {
81 : using Type = UncertainValue<FP>;
82 371 : static Type get_default(AgeGroup)
83 : {
84 371 : return Type(std::numeric_limits<FP>::max());
85 : }
86 32 : static std::string name()
87 : {
88 32 : return "ICUCapacity";
89 : }
90 : };
91 :
92 : /**
93 : * @brief the (mean) latent time in day unit
94 : */
95 : template <typename FP = double>
96 : struct TimeExposed {
97 : using Type = CustomIndexArray<UncertainValue<FP>, AgeGroup>;
98 371 : static Type get_default(AgeGroup size)
99 : {
100 742 : return Type(size, 1.);
101 : }
102 32 : static std::string name()
103 : {
104 32 : return "TimeExposed";
105 : }
106 : };
107 :
108 : /**
109 : * @brief the (mean) time in day unit for asymptomatic cases that are infectious but
110 : * have not yet developed symptoms.
111 : */
112 : template <typename FP = double>
113 : struct TimeInfectedNoSymptoms {
114 : using Type = CustomIndexArray<UncertainValue<FP>, AgeGroup>;
115 371 : static Type get_default(AgeGroup size)
116 : {
117 742 : return Type(size, 1.);
118 : }
119 32 : static std::string name()
120 : {
121 32 : return "TimeInfectedNoSymptoms";
122 : }
123 : };
124 :
125 : /**
126 : * @brief the infectious time for symptomatic cases that are infected but
127 : * who do not need to be hsopitalized in the SECIR model in day unit
128 : */
129 : template <typename FP = double>
130 : struct TimeInfectedSymptoms {
131 : using Type = CustomIndexArray<UncertainValue<FP>, AgeGroup>;
132 371 : static Type get_default(AgeGroup size)
133 : {
134 742 : return Type(size, 1.);
135 : }
136 32 : static std::string name()
137 : {
138 32 : return "TimeInfectedSymptoms";
139 : }
140 : };
141 :
142 : /**
143 : * @brief the time people are 'simply' hospitalized before returning home in the SECIR model
144 : * in day unit
145 : */
146 : template <typename FP = double>
147 : struct TimeInfectedSevere {
148 : using Type = CustomIndexArray<UncertainValue<FP>, AgeGroup>;
149 371 : static Type get_default(AgeGroup size)
150 : {
151 742 : return Type(size, 1.);
152 : }
153 32 : static std::string name()
154 : {
155 32 : return "TimeInfectedSevere";
156 : }
157 : };
158 :
159 : /**
160 : * @brief the time people are treated by ICU before returning home in the SECIR model
161 : * in day unit
162 : */
163 : template <typename FP = double>
164 : struct TimeInfectedCritical {
165 : using Type = CustomIndexArray<UncertainValue<FP>, AgeGroup>;
166 371 : static Type get_default(AgeGroup size)
167 : {
168 742 : return Type(size, 1.);
169 : }
170 32 : static std::string name()
171 : {
172 32 : return "TimeInfectedCritical";
173 : }
174 : };
175 :
176 : /**
177 : * @brief probability of getting infected from a contact
178 : */
179 : template <typename FP = double>
180 : struct TransmissionProbabilityOnContact {
181 : using Type = CustomIndexArray<UncertainValue<FP>, AgeGroup>;
182 371 : static Type get_default(AgeGroup size)
183 : {
184 742 : return Type(size, 1.);
185 : }
186 32 : static std::string name()
187 : {
188 32 : return "TransmissionProbabilityOnContact";
189 : }
190 : };
191 :
192 : /**
193 : * @brief the relative InfectedNoSymptoms infectability
194 : */
195 : template <typename FP = double>
196 : struct RelativeTransmissionNoSymptoms {
197 : using Type = CustomIndexArray<UncertainValue<FP>, AgeGroup>;
198 371 : static Type get_default(AgeGroup size)
199 : {
200 742 : return Type(size, 1.);
201 : }
202 32 : static std::string name()
203 : {
204 32 : return "RelativeTransmissionNoSymptoms";
205 : }
206 : };
207 :
208 : /**
209 : * @brief the percentage of asymptomatic cases in the SECIR model
210 : */
211 : template <typename FP = double>
212 : struct RecoveredPerInfectedNoSymptoms {
213 : using Type = CustomIndexArray<UncertainValue<FP>, AgeGroup>;
214 371 : static Type get_default(AgeGroup size)
215 : {
216 742 : return Type(size, 0.);
217 : }
218 32 : static std::string name()
219 : {
220 32 : return "RecoveredPerInfectedNoSymptoms";
221 : }
222 : };
223 :
224 : /**
225 : * @brief the risk of infection from symptomatic cases in the SECIR model
226 : */
227 : template <typename FP = double>
228 : struct RiskOfInfectionFromSymptomatic {
229 : using Type = CustomIndexArray<UncertainValue<FP>, AgeGroup>;
230 371 : static Type get_default(AgeGroup size)
231 : {
232 742 : return Type(size, 1.);
233 : }
234 32 : static std::string name()
235 : {
236 32 : return "RiskOfInfectionFromSymptomatic";
237 : }
238 : };
239 :
240 : /**
241 : * @brief risk of infection from symptomatic cases increases as test and trace capacity is exceeded.
242 : */
243 : template <typename FP = double>
244 : struct MaxRiskOfInfectionFromSymptomatic {
245 : using Type = CustomIndexArray<UncertainValue<FP>, AgeGroup>;
246 371 : static Type get_default(AgeGroup size)
247 : {
248 742 : return Type(size, 0.);
249 : }
250 32 : static std::string name()
251 : {
252 32 : return "MaxRiskOfInfectionFromSymptomatic";
253 : }
254 : };
255 :
256 : /**
257 : * @brief the percentage of hospitalized patients per infected patients in the SECIR model
258 : */
259 : template <typename FP = double>
260 : struct SeverePerInfectedSymptoms {
261 : using Type = CustomIndexArray<UncertainValue<FP>, AgeGroup>;
262 371 : static Type get_default(AgeGroup size)
263 : {
264 742 : return Type(size, 0.);
265 : }
266 32 : static std::string name()
267 : {
268 32 : return "SeverePerInfectedSymptoms";
269 : }
270 : };
271 :
272 : /**
273 : * @brief the percentage of ICU patients per hospitalized patients in the SECIR model
274 : */
275 : template <typename FP = double>
276 : struct CriticalPerSevere {
277 : using Type = CustomIndexArray<UncertainValue<FP>, AgeGroup>;
278 371 : static Type get_default(AgeGroup size)
279 : {
280 742 : return Type(size, 0.);
281 : }
282 32 : static std::string name()
283 : {
284 32 : return "CriticalPerSevere";
285 : }
286 : };
287 :
288 : /**
289 : * @brief the percentage of dead patients per ICU patients in the SECIR model
290 : */
291 : template <typename FP = double>
292 : struct DeathsPerCritical {
293 : using Type = CustomIndexArray<UncertainValue<FP>, AgeGroup>;
294 371 : static Type get_default(AgeGroup size)
295 : {
296 742 : return Type(size, 0.);
297 : }
298 32 : static std::string name()
299 : {
300 32 : return "DeathsPerCritical";
301 : }
302 : };
303 :
304 : /**
305 : * @brief the contact patterns within the society are modelled using an UncertainContactMatrix
306 : */
307 : template <typename FP = double>
308 : struct ContactPatterns {
309 : using Type = UncertainContactMatrix<FP>;
310 371 : static Type get_default(AgeGroup size)
311 : {
312 371 : return Type(1, static_cast<Eigen::Index>((size_t)size));
313 : }
314 32 : static std::string name()
315 : {
316 32 : return "ContactPatterns";
317 : }
318 : };
319 :
320 : /**
321 : * @brief the NPIs that are enforced if certain infection thresholds are exceeded.
322 : */
323 : template <typename FP = double>
324 : struct DynamicNPIsInfectedSymptoms {
325 : using Type = DynamicNPIs<FP>;
326 371 : static Type get_default(AgeGroup /*size*/)
327 : {
328 371 : return {};
329 : }
330 32 : static std::string name()
331 : {
332 32 : return "DynamicNPIsInfectedSymptoms";
333 : }
334 : };
335 :
336 : /**
337 : * @brief The delay with which DynamicNPIs are implemented and enforced after exceedance of threshold.
338 : */
339 : template <typename FP = double>
340 : struct DynamicNPIsImplementationDelay {
341 : using Type = UncertainValue<FP>;
342 371 : static Type get_default(AgeGroup /*size*/)
343 : {
344 371 : return 0.;
345 : }
346 32 : static std::string name()
347 : {
348 32 : return "DynamicNPIsImplementationDelay";
349 : }
350 : };
351 :
352 : /**
353 : * @brief capacity to test and trace contacts of infected for quarantine per day.
354 : */
355 : template <typename FP = double>
356 : struct TestAndTraceCapacity {
357 : using Type = UncertainValue<FP>;
358 371 : static Type get_default(AgeGroup)
359 : {
360 371 : return Type(std::numeric_limits<FP>::max());
361 : }
362 32 : static std::string name()
363 : {
364 32 : return "TestAndTraceCapacity";
365 : }
366 : };
367 :
368 : /**
369 : * @brief Multiplier for the test and trace capacity to determine when it is considered overloaded.
370 : */
371 : template <typename FP = double>
372 : struct TestAndTraceCapacityMaxRisk {
373 : using Type = UncertainValue<FP>;
374 371 : static Type get_default(AgeGroup)
375 : {
376 371 : return Type(5.0);
377 : }
378 32 : static std::string name()
379 : {
380 32 : return "TestAndTraceCapacityMaxRisk";
381 : }
382 : };
383 :
384 : template <typename FP = double>
385 : using ParametersBase =
386 : ParameterSet<StartDay, Seasonality<FP>, ICUCapacity<FP>, TestAndTraceCapacity<FP>, TestAndTraceCapacityMaxRisk<FP>,
387 : ContactPatterns<FP>, DynamicNPIsImplementationDelay<FP>, DynamicNPIsInfectedSymptoms<FP>,
388 : TimeExposed<FP>, TimeInfectedNoSymptoms<FP>, TimeInfectedSymptoms<FP>, TimeInfectedSevere<FP>,
389 : TimeInfectedCritical<FP>, TransmissionProbabilityOnContact<FP>, RelativeTransmissionNoSymptoms<FP>,
390 : RecoveredPerInfectedNoSymptoms<FP>, RiskOfInfectionFromSymptomatic<FP>,
391 : MaxRiskOfInfectionFromSymptomatic<FP>, SeverePerInfectedSymptoms<FP>, CriticalPerSevere<FP>,
392 : DeathsPerCritical<FP>>;
393 :
394 : /**
395 : * @brief Parameters of an age-resolved SECIR/SECIHURD model.
396 : */
397 : template <typename FP = double>
398 : class Parameters : public ParametersBase<FP>
399 : {
400 : public:
401 371 : Parameters(AgeGroup num_agegroups)
402 : : ParametersBase<FP>(num_agegroups)
403 371 : , m_num_groups{num_agegroups}
404 : {
405 371 : }
406 :
407 414287 : AgeGroup get_num_groups() const
408 : {
409 414287 : return m_num_groups;
410 : }
411 :
412 : /**
413 : * Percentage of infected commuters that are not detected.
414 : */
415 18 : double& get_commuter_nondetection()
416 : {
417 18 : return m_commuter_nondetection;
418 : }
419 : double get_commuter_nondetection() const
420 : {
421 : return m_commuter_nondetection;
422 : }
423 :
424 : /**
425 : * Time in simulation before which no infected commuters are detected.
426 : */
427 18 : double& get_start_commuter_detection()
428 : {
429 18 : return m_start_commuter_detection;
430 : }
431 :
432 : double get_start_commuter_detection() const
433 : {
434 : return m_start_commuter_detection;
435 : }
436 :
437 : /**
438 : * Time in simulation after which no infected commuters are detected.
439 : */
440 18 : double& get_end_commuter_detection()
441 : {
442 18 : return m_end_commuter_detection;
443 : }
444 :
445 : double get_end_commuter_detection() const
446 : {
447 : return m_end_commuter_detection;
448 : }
449 :
450 : /**
451 : * Time in simulation after which no dynamic NPIs are applied.
452 : */
453 265 : double& get_end_dynamic_npis()
454 : {
455 265 : return m_end_dynamic_npis;
456 : }
457 : double get_end_dynamic_npis() const
458 : {
459 : return m_end_dynamic_npis;
460 : }
461 :
462 : /**
463 : * @brief Checks whether all Parameters satisfy their corresponding constraints and applies them, if they do not.
464 : * Time spans cannot be negative and probabilities can only take values between [0,1].
465 : *
466 : * Attention: This function should be used with care. It is necessary for some test problems to run through quickly,
467 : * but in a manual execution of an example, check_constraints() may be preferred. Note that the apply_constraints()
468 : * function can and will not set Parameters to meaningful values in an epidemiological or virological context,
469 : * as all models are designed to be transferable to multiple diseases. Consequently, only acceptable
470 : * (like 0 or 1 for probabilities or small positive values for time spans) values are set here and a manual adaptation
471 : * may often be necessary to have set meaningful values.
472 : *
473 : * @return Returns true if one ore more constraint were corrected, false otherwise.
474 : */
475 450 : bool apply_constraints()
476 : {
477 450 : const double tol_times = 1e-1; // accepted tolerance for compartment stays
478 :
479 450 : int corrected = false;
480 450 : if (this->template get<Seasonality<FP>>() < 0.0 || this->template get<Seasonality<FP>>() > 0.5) {
481 18 : log_warning("Constraint check: Parameter Seasonality changed from {:0.4f} to {:d}",
482 18 : this->template get<Seasonality<FP>>(), 0);
483 9 : this->template set<Seasonality<FP>>(0);
484 9 : corrected = true;
485 : }
486 :
487 450 : if (this->template get<ICUCapacity<FP>>() < 0.0) {
488 18 : log_warning("Constraint check: Parameter ICUCapacity changed from {:0.4f} to {:d}",
489 18 : this->template get<ICUCapacity<FP>>(), 0);
490 9 : this->template set<ICUCapacity<FP>>(0);
491 9 : corrected = true;
492 : }
493 :
494 450 : if (this->template get<DynamicNPIsImplementationDelay<FP>>() < 0.0) {
495 18 : log_warning("Constraint check: Parameter DynamicNPIsImplementationDelay changed from {} to {}",
496 18 : this->template get<DynamicNPIsImplementationDelay<FP>>(), 0);
497 9 : this->template set<DynamicNPIsImplementationDelay<FP>>(0);
498 9 : corrected = true;
499 : }
500 :
501 450 : if (this->template get<TestAndTraceCapacity<FP>>() < 0.0) {
502 18 : log_warning("Constraint check: Parameter TestAndTraceCapacity changed from {:0.4f} to {:d}",
503 18 : this->template get<TestAndTraceCapacity<FP>>(), 0);
504 9 : this->template get<TestAndTraceCapacity<FP>>() = 0;
505 9 : corrected = true;
506 : }
507 :
508 450 : if (this->template get<TestAndTraceCapacityMaxRisk<FP>>() < 0.0) {
509 18 : log_warning("Constraint check: Parameter TestAndTraceCapacityMaxRisk changed from {:0.4f} to {:d}",
510 18 : this->template get<TestAndTraceCapacityMaxRisk<FP>>(), 0);
511 9 : this->template get<TestAndTraceCapacityMaxRisk<FP>>() = 0;
512 9 : corrected = true;
513 : }
514 :
515 1287 : for (auto i = AgeGroup(0); i < AgeGroup(m_num_groups); ++i) {
516 837 : if (this->template get<TimeExposed<FP>>()[i] < tol_times) {
517 18 : log_warning("Constraint check: Parameter TimeExposed changed from {:.4f} to {:.4f}. Please "
518 : "note that unreasonably small compartment stays lead to massively increased run time. "
519 : "Consider to cancel and reset parameters.",
520 9 : this->template get<TimeExposed<FP>>()[i], tol_times);
521 9 : this->template get<TimeExposed<FP>>()[i] = tol_times;
522 9 : corrected = true;
523 : }
524 :
525 837 : if (this->template get<TimeInfectedNoSymptoms<FP>>()[i] < tol_times) {
526 18 : log_warning("Constraint check: Parameter TimeInfectedNoSymptoms changed from {:.4f} to {:.4f}. Please "
527 : "note that unreasonably small compartment stays lead to massively increased run time. "
528 : "Consider to cancel and reset parameters.",
529 9 : this->template get<TimeInfectedNoSymptoms<FP>>()[i], tol_times);
530 9 : this->template get<TimeInfectedNoSymptoms<FP>>()[i] = tol_times;
531 9 : corrected = true;
532 : }
533 :
534 837 : if (this->template get<TimeInfectedSymptoms<FP>>()[i] < tol_times) {
535 18 : log_warning("Constraint check: Parameter TimeInfectedSymptoms changed from {:.4f} to {:.4f}. Please "
536 : "note that unreasonably small compartment stays lead to massively increased run time. "
537 : "Consider to cancel and reset parameters.",
538 9 : this->template get<TimeInfectedSymptoms<FP>>()[i], tol_times);
539 9 : this->template get<TimeInfectedSymptoms<FP>>()[i] = tol_times;
540 9 : corrected = true;
541 : }
542 :
543 837 : if (this->template get<TimeInfectedSevere<FP>>()[i] < tol_times) {
544 18 : log_warning("Constraint check: Parameter TimeInfectedSevere changed from {:.4f} to {:.4f}. Please note "
545 : "that unreasonably small compartment stays lead to massively increased run time. Consider "
546 : "to cancel and reset parameters.",
547 9 : this->template get<TimeInfectedSevere<FP>>()[i], tol_times);
548 9 : this->template get<TimeInfectedSevere<FP>>()[i] = tol_times;
549 9 : corrected = true;
550 : }
551 :
552 837 : if (this->template get<TimeInfectedCritical<FP>>()[i] < tol_times) {
553 18 : log_warning("Constraint check: Parameter TimeInfectedCritical changed from {:.4f} to {:.4f}. Please "
554 : "note that unreasonably small compartment stays lead to massively increased run time. "
555 : "Consider to cancel and reset parameters.",
556 9 : this->template get<TimeInfectedCritical<FP>>()[i], tol_times);
557 9 : this->template get<TimeInfectedCritical<FP>>()[i] = tol_times;
558 9 : corrected = true;
559 : }
560 :
561 1674 : if (this->template get<TransmissionProbabilityOnContact<FP>>()[i] < 0.0 ||
562 837 : this->template get<TransmissionProbabilityOnContact<FP>>()[i] > 1.0) {
563 18 : log_warning(
564 : "Constraint check: Parameter TransmissionProbabilityOnContact changed from {:0.4f} to {:d} ",
565 18 : this->template get<TransmissionProbabilityOnContact<FP>>()[i], 0.0);
566 9 : this->template get<TransmissionProbabilityOnContact<FP>>()[i] = 0.0;
567 9 : corrected = true;
568 : }
569 :
570 837 : if (this->template get<RelativeTransmissionNoSymptoms<FP>>()[i] < 0.0) {
571 18 : log_warning("Constraint check: Parameter RelativeTransmissionNoSymptoms changed from {:0.4f} to {:d} ",
572 18 : this->template get<RelativeTransmissionNoSymptoms<FP>>()[i], 0);
573 9 : this->template get<RelativeTransmissionNoSymptoms<FP>>()[i] = 0;
574 9 : corrected = true;
575 : }
576 :
577 1674 : if (this->template get<RecoveredPerInfectedNoSymptoms<FP>>()[i] < 0.0 ||
578 837 : this->template get<RecoveredPerInfectedNoSymptoms<FP>>()[i] > 1.0) {
579 18 : log_warning("Constraint check: Parameter RecoveredPerInfectedNoSymptoms changed from {:0.4f} to {:d} ",
580 18 : this->template get<RecoveredPerInfectedNoSymptoms<FP>>()[i], 0);
581 9 : this->template get<RecoveredPerInfectedNoSymptoms<FP>>()[i] = 0;
582 9 : corrected = true;
583 : }
584 :
585 1665 : if (this->template get<RiskOfInfectionFromSymptomatic<FP>>()[i] < 0.0 ||
586 828 : this->template get<RiskOfInfectionFromSymptomatic<FP>>()[i] > 1.0) {
587 18 : log_warning("Constraint check: Parameter RiskOfInfectionFromSymptomatic changed from {:0.4f} to {:d}",
588 18 : this->template get<RiskOfInfectionFromSymptomatic<FP>>()[i], 0);
589 9 : this->template get<RiskOfInfectionFromSymptomatic<FP>>()[i] = 0;
590 9 : corrected = true;
591 : }
592 :
593 1665 : if (this->template get<SeverePerInfectedSymptoms<FP>>()[i] < 0.0 ||
594 828 : this->template get<SeverePerInfectedSymptoms<FP>>()[i] > 1.0) {
595 18 : log_warning("Constraint check: Parameter SeverePerInfectedSymptoms changed from {:0.4f} to {:d}",
596 18 : this->template get<SeverePerInfectedSymptoms<FP>>()[i], 0);
597 9 : this->template get<SeverePerInfectedSymptoms<FP>>()[i] = 0;
598 9 : corrected = true;
599 : }
600 :
601 1665 : if (this->template get<CriticalPerSevere<FP>>()[i] < 0.0 ||
602 828 : this->template get<CriticalPerSevere<FP>>()[i] > 1.0) {
603 18 : log_warning("Constraint check: Parameter CriticalPerSevere changed from {:0.4f} to {:d}",
604 18 : this->template get<CriticalPerSevere<FP>>()[i], 0);
605 9 : this->template get<CriticalPerSevere<FP>>()[i] = 0;
606 9 : corrected = true;
607 : }
608 :
609 1674 : if (this->template get<DeathsPerCritical<FP>>()[i] < 0.0 ||
610 837 : this->template get<DeathsPerCritical<FP>>()[i] > 1.0) {
611 18 : log_warning("Constraint check: Parameter DeathsPerCritical changed from {:0.4f} to {:d}",
612 18 : this->template get<DeathsPerCritical<FP>>()[i], 0);
613 9 : this->template get<DeathsPerCritical<FP>>()[i] = 0;
614 9 : corrected = true;
615 : }
616 : }
617 450 : return corrected;
618 : }
619 :
620 : /**
621 : * @brief Checks whether all Parameters satisfy their corresponding constraints and logs an error
622 : * if constraints are not satisfied.
623 : * @return Returns true if one constraint is not satisfied, otherwise false.
624 : */
625 371 : bool check_constraints() const
626 : {
627 371 : if (this->template get<Seasonality<FP>>() < 0.0 || this->template get<Seasonality<FP>>() > 0.5) {
628 18 : log_error("Constraint check: Parameter Seasonality smaller {:d} or larger {:d}", 0, 0.5);
629 9 : return true;
630 : }
631 :
632 362 : if (this->template get<ICUCapacity<FP>>() < 0.0) {
633 18 : log_error("Constraint check: Parameter ICUCapacity smaller {:d}", 0);
634 9 : return true;
635 : }
636 :
637 353 : if (this->template get<TestAndTraceCapacity<FP>>() < 0.0) {
638 18 : log_error("Constraint check: Parameter TestAndTraceCapacity smaller {:d}", 0);
639 9 : return true;
640 : }
641 :
642 344 : if (this->template get<TestAndTraceCapacityMaxRisk<FP>>() < 0.0) {
643 18 : log_error("Constraint check: Parameter TestAndTraceCapacityMaxRisk smaller {:d}", 0);
644 9 : return true;
645 : }
646 :
647 335 : if (this->template get<DynamicNPIsImplementationDelay<FP>>() < 0.0) {
648 18 : log_error("Constraint check: Parameter DynamicNPIsImplementationDelay smaller {:d}", 0);
649 9 : return true;
650 : }
651 :
652 326 : const double tol_times = 1e-1; // accepted tolerance for compartment stays
653 :
654 580 : for (auto i = AgeGroup(0); i < AgeGroup(m_num_groups); ++i) {
655 362 : if (this->template get<TimeExposed<FP>>()[i] < tol_times) {
656 18 : log_error("Constraint check: Parameter TimeExposed {:.4f} smaller {:.4f}. Please "
657 : "note that unreasonably small compartment stays lead to massively increased run time. "
658 : "Consider to cancel and reset parameters.",
659 9 : this->template get<TimeExposed<FP>>()[i], tol_times);
660 9 : return true;
661 : }
662 :
663 353 : if (this->template get<TimeInfectedNoSymptoms<FP>>()[i] < tol_times) {
664 18 : log_error("Constraint check: Parameter TimeInfectedNoSymptoms {:.4f} smaller {:.4f}. Please "
665 : "note that unreasonably small compartment stays lead to massively increased run time. "
666 : "Consider to cancel and reset parameters.",
667 9 : this->template get<TimeInfectedNoSymptoms<FP>>()[i], tol_times);
668 9 : return true;
669 : }
670 :
671 344 : if (this->template get<TimeInfectedSymptoms<FP>>()[i] < tol_times) {
672 18 : log_error("Constraint check: Parameter TimeInfectedSymptoms {:.4f} smaller {:.4f}. Please "
673 : "note that unreasonably small compartment stays lead to massively increased run time. "
674 : "Consider to cancel and reset parameters.",
675 9 : this->template get<TimeInfectedSymptoms<FP>>()[i], tol_times);
676 9 : return true;
677 : }
678 :
679 335 : if (this->template get<TimeInfectedSevere<FP>>()[i] < tol_times) {
680 18 : log_error("Constraint check: Parameter TimeInfectedSevere {:.4f} smaller {:.4f}. Please "
681 : "note that unreasonably small compartment stays lead to massively increased run time. "
682 : "Consider to cancel and reset parameters.",
683 9 : this->template get<TimeInfectedSevere<FP>>()[i], tol_times);
684 9 : return true;
685 : }
686 :
687 326 : if (this->template get<TimeInfectedCritical<FP>>()[i] < tol_times) {
688 18 : log_error("Constraint check: Parameter TimeInfectedCritical {:.4f} smaller {:.4f}. Please "
689 : "note that unreasonably small compartment stays lead to massively increased run time. "
690 : "Consider to cancel and reset parameters.",
691 9 : this->template get<TimeInfectedCritical<FP>>()[i], tol_times);
692 9 : return true;
693 : }
694 :
695 634 : if (this->template get<TransmissionProbabilityOnContact<FP>>()[i] < 0.0 ||
696 317 : this->template get<TransmissionProbabilityOnContact<FP>>()[i] > 1.0) {
697 18 : log_error("Constraint check: Parameter TransmissionProbabilityOnContact smaller {:d} or larger {:d}", 0,
698 18 : 1);
699 9 : return true;
700 : }
701 :
702 308 : if (this->template get<RelativeTransmissionNoSymptoms<FP>>()[i] < 0.0) {
703 18 : log_error("Constraint check: Parameter RelativeTransmissionNoSymptoms smaller {:d}", 0);
704 9 : return true;
705 : }
706 :
707 598 : if (this->template get<RecoveredPerInfectedNoSymptoms<FP>>()[i] < 0.0 ||
708 299 : this->template get<RecoveredPerInfectedNoSymptoms<FP>>()[i] > 1.0) {
709 18 : log_error("Constraint check: Parameter RecoveredPerInfectedNoSymptoms smaller {:d} or larger {:d}", 0,
710 18 : 1);
711 9 : return true;
712 : }
713 :
714 571 : if (this->template get<RiskOfInfectionFromSymptomatic<FP>>()[i] < 0.0 ||
715 281 : this->template get<RiskOfInfectionFromSymptomatic<FP>>()[i] > 1.0) {
716 18 : log_error("Constraint check: Parameter RiskOfInfectionFromSymptomatic smaller {:d} or larger {:d}", 0,
717 18 : 1);
718 9 : return true;
719 : }
720 :
721 553 : if (this->template get<SeverePerInfectedSymptoms<FP>>()[i] < 0.0 ||
722 272 : this->template get<SeverePerInfectedSymptoms<FP>>()[i] > 1.0) {
723 18 : log_error("Constraint check: Parameter SeverePerInfectedSymptoms smaller {:d} or larger {:d}", 0, 1);
724 9 : return true;
725 : }
726 :
727 535 : if (this->template get<CriticalPerSevere<FP>>()[i] < 0.0 ||
728 263 : this->template get<CriticalPerSevere<FP>>()[i] > 1.0) {
729 18 : log_error("Constraint check: Parameter CriticalPerSevere smaller {:d} or larger {:d}", 0, 1);
730 9 : return true;
731 : }
732 :
733 526 : if (this->template get<DeathsPerCritical<FP>>()[i] < 0.0 ||
734 263 : this->template get<DeathsPerCritical<FP>>()[i] > 1.0) {
735 18 : log_error("Constraint check: Parameter DeathsPerCritical smaller {:d} or larger {:d}", 0, 1);
736 9 : return true;
737 : }
738 : }
739 218 : return false;
740 : }
741 :
742 : private:
743 9 : Parameters(ParametersBase<FP>&& base)
744 9 : : ParametersBase<FP>(std::move(base))
745 18 : , m_num_groups(this->template get<ContactPatterns<FP>>().get_cont_freq_mat().get_num_groups())
746 : {
747 9 : }
748 :
749 : public:
750 : /**
751 : * deserialize an object of this class.
752 : * @see mio::deserialize
753 : */
754 : template <class IOContext>
755 9 : static IOResult<Parameters> deserialize(IOContext& io)
756 : {
757 9 : BOOST_OUTCOME_TRY(auto&& base, ParametersBase<FP>::deserialize(io));
758 9 : return success(Parameters(std::move(base)));
759 9 : }
760 :
761 : private:
762 : AgeGroup m_num_groups;
763 : double m_commuter_nondetection = 0.0;
764 : double m_start_commuter_detection = 0.0;
765 : double m_end_commuter_detection = 0.0;
766 : double m_end_dynamic_npis = std::numeric_limits<double>::max();
767 : };
768 :
769 : /**
770 : * @brief WIP !! TO DO: returns the actual, approximated reproduction rate
771 : */
772 : //double get_reprod_rate(Parameters const& params, double t, std::vector<double> const& yt);
773 :
774 : } // namespace osecir
775 : } // namespace mio
776 :
777 : #endif // SECIR_PARAMETERS_H
|