model.h Source File

CPP API: model.h Source File
ode_mseirs4/model.h
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2020-2026 MEmilio
3 *
4 * Authors: Henrik Zunker
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 ODE_MSEIRS4_MODEL_H
21 #define ODE_MSEIRS4_MODEL_H
22 
26 #include "ode_mseirs4/parameters.h"
27 
28 #include <numbers>
29 
30 namespace mio
31 {
32 namespace omseirs4
33 {
34 
35 template <typename FP = ScalarType>
36 class Model : public mio::CompartmentalModel<FP, InfectionState, mio::Populations<FP, InfectionState>, Parameters<FP>>
37 {
39 
40 public:
41  using typename Base::ParameterSet;
42  using typename Base::Populations;
43 
44  Model(const Populations& pop, const ParameterSet& params)
45  : Base(pop, params)
46  {
47  }
48 
51  {
52  }
53 
54  void get_derivatives(Eigen::Ref<const Eigen::VectorX<FP>> pop, Eigen::Ref<const Eigen::VectorX<FP>> y, FP t,
55  Eigen::Ref<Eigen::VectorX<FP>> dydt) const override
56  {
57  auto& params = this->parameters;
58  const FP b0 = params.template get<BaseTransmissionRate<FP>>();
59  const FP b1 = params.template get<SeasonalAmplitude<FP>>();
60  const FP phi = params.template get<SeasonalPhase<FP>>();
61  const FP mu = params.template get<NaturalBirthDeathRate<FP>>();
62  const FP xi = params.template get<LossMaternalImmunityRate<FP>>();
63  const FP sigma = params.template get<ProgressionRate<FP>>();
64  const FP nu = params.template get<RecoveryRate<FP>>();
65  const FP gamma = params.template get<ImmunityWaningRate<FP>>();
66  const FP f2 = params.template get<Beta2Factor<FP>>();
67  const FP f3 = params.template get<Beta3Factor<FP>>();
68  const FP f4 = params.template get<Beta4Factor<FP>>();
69 
70  const FP two_pi = FP(2) * std::numbers::pi_v<ScalarType>;
71  const FP beta1 = b0 * (FP(1) + b1 * std::cos(two_pi * (t / FP(365.0)) + phi));
72  const FP beta2 = f2 * beta1;
73  const FP beta3 = f3 * beta1;
74  const FP beta4 = f4 * beta1;
75 
76  auto idx = [&](InfectionState s) {
77  return static_cast<size_t>(s);
78  };
79 
80  const FP I_total = y[idx(InfectionState::I1)] + y[idx(InfectionState::I2)] + y[idx(InfectionState::I3)] +
81  y[idx(InfectionState::I4)];
82  const FP R_total = y[idx(InfectionState::R1)] + y[idx(InfectionState::R2)] + y[idx(InfectionState::R3)] +
83  y[idx(InfectionState::R4)];
84  const FP N = pop.sum();
85  const FP inv_N = (N > Limits<FP>::zero_tolerance())
86  ? FP(1) / N
87  : FP(0.0); // avoid excessive force of infection or division by zero when empty
88  const FP lambda1 = beta1 * I_total * inv_N;
89  const FP lambda2 = beta2 * I_total * inv_N;
90  const FP lambda3 = beta3 * I_total * inv_N;
91  const FP lambda4 = beta4 * I_total * inv_N;
92 
93  // dM
94  dydt[idx(InfectionState::MaternalImmune)] = mu * R_total - (xi + mu) * y[idx(InfectionState::MaternalImmune)];
95 
96  // dS1
97  dydt[idx(InfectionState::S1)] = mu * (N - R_total) + xi * y[idx(InfectionState::MaternalImmune)] -
98  mu * y[idx(InfectionState::S1)] - lambda1 * y[idx(InfectionState::S1)];
99 
100  // dE1..E4
101  dydt[idx(InfectionState::E1)] =
102  lambda1 * y[idx(InfectionState::S1)] - (mu + sigma) * y[idx(InfectionState::E1)];
103  dydt[idx(InfectionState::E2)] =
104  lambda2 * y[idx(InfectionState::S2)] - (mu + sigma) * y[idx(InfectionState::E2)];
105  dydt[idx(InfectionState::E3)] =
106  lambda3 * y[idx(InfectionState::S3)] - (mu + sigma) * y[idx(InfectionState::E3)];
107  dydt[idx(InfectionState::E4)] =
108  lambda4 * y[idx(InfectionState::S4)] - (mu + sigma) * y[idx(InfectionState::E4)];
109 
110  // dI1..I4
111  dydt[idx(InfectionState::I1)] = sigma * y[idx(InfectionState::E1)] - (nu + mu) * y[idx(InfectionState::I1)];
112  dydt[idx(InfectionState::I2)] = sigma * y[idx(InfectionState::E2)] - (nu + mu) * y[idx(InfectionState::I2)];
113  dydt[idx(InfectionState::I3)] = sigma * y[idx(InfectionState::E3)] - (nu + mu) * y[idx(InfectionState::I3)];
114  dydt[idx(InfectionState::I4)] = sigma * y[idx(InfectionState::E4)] - (nu + mu) * y[idx(InfectionState::I4)];
115 
116  // dR1..R4
117  dydt[idx(InfectionState::R1)] = nu * y[idx(InfectionState::I1)] - (mu + gamma) * y[idx(InfectionState::R1)];
118  dydt[idx(InfectionState::R2)] = nu * y[idx(InfectionState::I2)] - (mu + gamma) * y[idx(InfectionState::R2)];
119  dydt[idx(InfectionState::R3)] = nu * y[idx(InfectionState::I3)] - (mu + gamma) * y[idx(InfectionState::R3)];
120  dydt[idx(InfectionState::R4)] = nu * y[idx(InfectionState::I4)] - (mu + gamma) * y[idx(InfectionState::R4)];
121 
122  // dS2,S3,S4
123  dydt[idx(InfectionState::S2)] =
124  gamma * y[idx(InfectionState::R1)] - mu * y[idx(InfectionState::S2)] - lambda2 * y[idx(InfectionState::S2)];
125  dydt[idx(InfectionState::S3)] =
126  gamma * y[idx(InfectionState::R2)] - mu * y[idx(InfectionState::S3)] - lambda3 * y[idx(InfectionState::S3)];
127  dydt[idx(InfectionState::S4)] = gamma * (y[idx(InfectionState::R3)] + y[idx(InfectionState::R4)]) -
128  mu * y[idx(InfectionState::S4)] - lambda4 * y[idx(InfectionState::S4)];
129  }
130 
135  template <class IOContext>
136  void serialize(IOContext& io) const
137  {
138  auto obj = io.create_object("Model");
139  obj.add_element("Parameters", this->parameters);
140  obj.add_element("Populations", this->populations);
141  }
142 
147  template <class IOContext>
148  static IOResult<Model> deserialize(IOContext& io)
149  {
150  auto obj = io.expect_object("Model");
151  auto par = obj.expect_element("Parameters", Tag<ParameterSet>{});
152  auto pop = obj.expect_element("Populations", Tag<Populations>{});
153  return apply(
154  io,
155  [](auto&& par_, auto&& pop_) {
156  return Model{pop_, par_};
157  },
158  par, pop);
159  }
160 };
161 
162 } // namespace omseirs4
163 } // namespace mio
164 
165 #endif // ODE_MSEIRS4_MODEL_H
A class template for compartment populations.
Definition: populations.h:55
Parameters of the simulation that are the same everywhere within the Model.
Definition: abm/parameters.h:764
Definition: ode_mseirs4/model.h:37
void get_derivatives(Eigen::Ref< const Eigen::VectorX< FP >> pop, Eigen::Ref< const Eigen::VectorX< FP >> y, FP t, Eigen::Ref< Eigen::VectorX< FP >> dydt) const override
Definition: ode_mseirs4/model.h:54
static IOResult< Model > deserialize(IOContext &io)
deserialize an object of this class.
Definition: ode_mseirs4/model.h:148
Model(const Populations &pop, const ParameterSet &params)
Definition: ode_mseirs4/model.h:44
void serialize(IOContext &io) const
serialize this.
Definition: ode_mseirs4/model.h:136
Model()
Definition: ode_mseirs4/model.h:49
Definition: ode_mseirs4/parameters.h:183
ad::internal::unary_intermediate< AD_TAPE_REAL, ad::internal::active_type< AD_TAPE_REAL, DATA_HANDLER_1 >, ad::operations::ad_cos< AD_TAPE_REAL > > cos(const ad::internal::active_type< AD_TAPE_REAL, DATA_HANDLER_1 > &x1)
Definition: ad.hpp:924
InfectionState
Definition: ode_mseirs4/infection_state.h:28
A collection of classes to simplify handling of matrix shapes in meta programming.
Definition: models/abm/analyze_result.h:30
boost::outcome_v2::in_place_type_t< T > Tag
Type that is used for overload resolution.
Definition: io.h:407
details::ApplyResultT< F, T... > apply(IOContext &io, F f, const IOResult< T > &... rs)
Evaluate a function with zero or more unpacked IOResults as arguments.
Definition: io.h:481
boost::outcome_v2::unchecked< T, IOStatus > IOResult
Value-or-error type for operations that return a value but can fail.
Definition: io.h:353
CompartmentalModel is a template for a compartmental model for an array of initial populations and a ...
Definition: compartmental_model.h:59
mio::Populations< FP, InfectionState > Populations
Definition: compartmental_model.h:62
static constexpr FP zero_tolerance()=delete