flow_simulation.h Source File

CPP API: flow_simulation.h Source File
flow_simulation.h
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2020-2026 MEmilio
3 *
4 * Authors: Rene Schmieding, 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 MIO_COMPARTMENTS_FLOW_SIMULATION_H
21 #define MIO_COMPARTMENTS_FLOW_SIMULATION_H
22 
27 
28 namespace mio
29 {
30 
36 template <typename FP, IsFlowModel<FP> M>
37 class FlowSimulation : public details::FlowSimulationBase<FP, M, OdeIntegrator<FP>>
38 {
39 public:
41  using Model = M;
42 
49  FlowSimulation(Model const& model, FP t0 = 0., FP dt = 0.1)
50  : Base(model, std::make_unique<DefaultIntegratorCore<FP>>(), t0, dt)
51  , m_pop(model.get_initial_values().size())
52  {
53  }
54 
62  Eigen::Ref<Eigen::VectorX<FP>> advance(FP tmax)
63  {
64  // the derivfunktion (i.e. the lambda passed to m_integrator.advance below) requires that there are at least
65  // as many entries in m_flow_result as in Base::m_result
66  assert(Base::get_flows().get_num_time_points() == Base::get_result().get_num_time_points());
67  const auto result = Base::advance(
68  [this](auto&& flows, auto&& t, auto&& dflows_dt) {
69  const auto& pop_result = this->get_result();
70  const auto& model = this->get_model();
71  // compute current population
72  // flows contains the accumulated outflows of each compartment for each target compartment at time t.
73  // Using that the ODEs are linear expressions of the flows, get_derivatives can compute the total change
74  // in population from t0 to t.
75  // To incorporate external changes to the last values of pop_result (e.g. by applying mobility), we only
76  // calculate the change in population starting from the last available time point in m_result, instead
77  // of starting at t0. To do that, the following difference of flows is used.
78  model.get_derivatives(flows - Base::get_flows().get_value(pop_result.get_num_time_points() - 1),
79  m_pop); // note: overwrites values in pop
80  // add the "initial" value of the ODEs (using last available time point in pop_result)
81  // If no changes were made to the last value in m_result outside of FlowSimulation, the following
82  // line computes the same as `model.get_derivatives(flows, x); x += model.get_initial_values();`.
83  m_pop += pop_result.get_last_value();
84  // compute the current change in flows with respect to the current population
85  dflows_dt.setZero();
86  model.get_flows(m_pop, m_pop, t, dflows_dt); // this result is used by the integrator
87  },
88  tmax, Base::get_flows());
90  return result;
91  }
92 
93 private:
94  Eigen::VectorX<FP> m_pop;
95 };
96 
110 template <typename FP, class Model, class Sim = FlowSimulation<FP, Model>>
111 std::vector<TimeSeries<FP>> simulate_flows(FP t0, FP tmax, FP dt, Model const& model,
112  std::unique_ptr<OdeIntegratorCore<FP>>&& integrator_core = nullptr)
113 {
114  model.check_constraints();
115  Sim sim(model, t0, dt);
116  if (integrator_core) {
117  sim.set_integrator_core(std::move(integrator_core));
118  }
119  sim.advance(tmax);
120  return {sim.get_result(), sim.get_flows()};
121 }
122 
123 } // namespace mio
124 
125 #endif // MIO_COMPARTMENTS_FLOW_SIMULATION_H
This is an adaptive IntegratorCore.
Definition: stepper_wrapper.h:59
A class for simulating a FlowModel.
Definition: flow_simulation.h:38
Eigen::VectorX< FP > m_pop
pre-allocated temporary, used during computation of flow derivatives
Definition: flow_simulation.h:94
Eigen::Ref< Eigen::VectorX< FP > > advance(FP tmax)
Run the simulation up to a given time.
Definition: flow_simulation.h:62
M Model
Definition: flow_simulation.h:41
FlowSimulation(Model const &model, FP t0=0., FP dt=0.1)
Set up the simulation with an ODE solver.
Definition: flow_simulation.h:49
Interface class defining the integration step used in a SystemIntegrator.
Definition: integrator.h:48
The Model of the Simulation.
Definition: abm/model.h:54
Base class to define a FlowSimulation.
Definition: flow_simulation_base.h:42
void compute_population_results()
Computes the distribution of the Population to the InfectionStates based on the simulated flows.
Definition: flow_simulation_base.h:90
TimeSeries< FP > & get_flows()
Returns the simulation result describing the transitions between compartments for each time step.
Definition: flow_simulation_base.h:72
Eigen::Ref< Eigen::VectorX< FP > > advance(const Integrands &... fs, FP tmax, TimeSeries< FP > &results)
Run the simulation up to a given time.
Definition: simulation_base.h:165
const Model & get_model() const
Get a reference to the model owned and used by the simulation.
Definition: simulation_base.h:131
TimeSeries< FP > & get_result()
Returns the simulation result describing the model population in each time step.
Definition: simulation_base.h:116
int size(Comm comm)
Return the size of the given communicator.
Definition: miompi.cpp:75
A collection of classes to simplify handling of matrix shapes in meta programming.
Definition: models/abm/analyze_result.h:30
std::vector< TimeSeries< FP > > simulate_flows(FP t0, FP tmax, FP dt, Model const &model, std::unique_ptr< OdeIntegratorCore< FP >> &&integrator_core=nullptr)
Run a FlowSimulation of a FlowModel.
Definition: flow_simulation.h:111
Definition: io.h:94