model.h Source File

CPP API: model.h Source File
ode_seirdb/model.h
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2020-2026 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 SEIRDB_MODEL_H
21 #define SEIRDB_MODEL_H
22 
24 #include "memilio/config.h"
30 #include "ode_seirdb/parameters.h"
31 
33 GCC_CLANG_DIAGNOSTIC(ignored "-Wshadow")
34 #include <Eigen/Dense>
36 
37 namespace mio
38 {
39 namespace oseirdb
40 {
41 
42 /********************
43  * define the model *
44  ********************/
45 
46 // clang-format off
52 // clang-format on
53 template <typename FP>
54 class Model
55  : public FlowModel<FP, InfectionState, mio::Populations<FP, AgeGroup, InfectionState>, Parameters<FP>, Flows>
56 {
58 
59 public:
60  using typename Base::ParameterSet;
61  using typename Base::Populations;
62 
63  Model(const Populations& pop, const ParameterSet& params)
64  : Base(pop, params)
65  {
66  }
67 
68  Model(int num_agegroups)
69  : Base(Populations({AgeGroup(num_agegroups), InfectionState::Count}), ParameterSet(AgeGroup(num_agegroups)))
70  {
71  }
72 
73  void get_flows(Eigen::Ref<const Eigen::VectorX<FP>> pop, Eigen::Ref<const Eigen::VectorX<FP>> y, FP t,
74  Eigen::Ref<Eigen::VectorX<FP>> flows) const override
75  {
76  const Index<AgeGroup> age_groups = reduce_index<Index<AgeGroup>>(this->populations.size());
77  const auto& params = this->parameters;
78 
79  for (auto i : make_index_range(age_groups)) {
80  const size_t Si = this->populations.get_flat_index({i, InfectionState::Susceptible});
81  const size_t Ei = this->populations.get_flat_index({i, InfectionState::Exposed});
82  const size_t Ii = this->populations.get_flat_index({i, InfectionState::Infected});
83  const size_t Di = this->populations.get_flat_index({i, InfectionState::Dead});
84 
85  for (auto j : make_index_range(age_groups)) {
86  const size_t Sj = this->populations.get_flat_index({j, InfectionState::Susceptible});
87  const size_t Ej = this->populations.get_flat_index({j, InfectionState::Exposed});
88  const size_t Ij = this->populations.get_flat_index({j, InfectionState::Infected});
89  const size_t Rj = this->populations.get_flat_index({j, InfectionState::Recovered});
90  const size_t Dj = this->populations.get_flat_index({j, InfectionState::Dead});
91  const size_t Bj = this->populations.get_flat_index({j, InfectionState::Buried});
92 
93  const FP Nj = pop[Sj] + pop[Ej] + pop[Ij] + pop[Rj] + pop[Dj] + pop[Bj];
94  const FP divNj = (Nj < Limits<FP>::zero_tolerance()) ? FP(0.0) : FP(1.0 / Nj);
95  const FP contact_rate = params.template get<ContactPatterns<FP>>().get_cont_freq_mat().get_matrix_at(
96  SimulationTime<FP>(t))(i.get(), j.get()) *
97  divNj;
98  const FP coeffStoE = contact_rate * params.template get<TransmissionProbabilityOnContact<FP>>()[i];
99  const FP coeffStoEDead = contact_rate * params.template get<TransmissionProbabilityFromDead<FP>>()[i];
100 
101  flows[Base::template get_flat_flow_index<InfectionState::Susceptible, InfectionState::Exposed>(i)] +=
102  y[Si] * (coeffStoE * pop[Ij] + coeffStoEDead * pop[Dj]);
103  }
104  flows[Base::template get_flat_flow_index<InfectionState::Exposed, InfectionState::Infected>(i)] =
105  (1.0 / params.template get<TimeExposed<FP>>()[i]) * y[Ei];
106 
107  const FP inv_time_infected = 1.0 / params.template get<TimeInfected<FP>>()[i];
108  const FP prob_recover = params.template get<ProbabilityToRecover<FP>>()[i];
109  const FP prob_die = 1.0 - prob_recover;
110  flows[Base::template get_flat_flow_index<InfectionState::Infected, InfectionState::Recovered>(i)] =
111  inv_time_infected * prob_recover * y[Ii];
112  flows[Base::template get_flat_flow_index<InfectionState::Infected, InfectionState::Dead>(i)] =
113  inv_time_infected * prob_die * y[Ii];
114  flows[Base::template get_flat_flow_index<InfectionState::Dead, InfectionState::Buried>(i)] =
115  (1.0 / params.template get<TimeToBurial<FP>>()[i]) * y[Di];
116  }
117  }
118 
123  template <class IOContext>
124  void serialize(IOContext& io) const
125  {
126  auto obj = io.create_object("Model");
127  obj.add_element("Parameters", this->parameters);
128  obj.add_element("Populations", this->populations);
129  }
130 
135  template <class IOContext>
136  static IOResult<Model> deserialize(IOContext& io)
137  {
138  auto obj = io.expect_object("Model");
139  auto par = obj.expect_element("Parameters", Tag<ParameterSet>{});
140  auto pop = obj.expect_element("Populations", Tag<Populations>{});
141  return apply(
142  io,
143  [](auto&& par_, auto&& pop_) {
144  return Model{pop_, par_};
145  },
146  par, pop);
147  }
148 };
149 
150 } // namespace oseirdb
151 } // namespace mio
152 
153 #endif // SEIRDB_MODEL_H
mio::Index< Tag > size() const
returns the size along the dimension provided as template parameter
Definition: custom_index_array.h:204
size_t get_flat_index(Index const &index) const
get_flat_index returns the flat index into the stored array, given the indices of each category
Definition: custom_index_array.h:309
A FlowModel is a CompartmentalModel defined by the flows between compartments.
Definition: flow_model.h:74
A class template for compartment populations.
Definition: populations.h:55
double simulation time.
Definition: damping.h:58
Parameters of the simulation that are the same everywhere within the Model.
Definition: abm/parameters.h:764
Definition: ode_seirdb/model.h:56
void get_flows(Eigen::Ref< const Eigen::VectorX< FP >> pop, Eigen::Ref< const Eigen::VectorX< FP >> y, FP t, Eigen::Ref< Eigen::VectorX< FP >> flows) const override
Definition: ode_seirdb/model.h:73
Model(const Populations &pop, const ParameterSet &params)
Definition: ode_seirdb/model.h:63
void serialize(IOContext &io) const
serialize this.
Definition: ode_seirdb/model.h:124
Model(int num_agegroups)
Definition: ode_seirdb/model.h:68
static IOResult< Model > deserialize(IOContext &io)
deserialize an object of this class.
Definition: ode_seirdb/model.h:136
Parameters of an age-resolved SEIRDB model.
Definition: ode_seirdb/parameters.h:161
#define GCC_CLANG_DIAGNOSTIC(...)
Definition: compiler_diagnostics.h:62
A collection of classes to simplify handling of matrix shapes in meta programming.
Definition: models/abm/analyze_result.h:30
Range< MultiIndexIterator< Index< Categories... > > > make_index_range(Index< Categories... > dimensions)
Construct a range that can be used to iterate over all MultiIndices in the given dimensions.
Definition: index_range.h:168
boost::outcome_v2::in_place_type_t< T > Tag
Type that is used for overload resolution.
Definition: io.h:407
auto i
Definition: io.h:809
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
The AgeGroup struct is used as a dynamically sized tag for all age dependent categories.
Definition: age_group.h:32
mio::Populations< FP, AgeGroup, InfectionState > Populations
Definition: compartmental_model.h:62
A Flow defines a possible transition between two Compartments in a FlowModel.
Definition: flow.h:33
Collection of types. Each type is mapped to an index of type size_t.
Definition: type_list.h:32