simulation.h Source File

CPP API: simulation.h Source File
models/d_abm/simulation.h
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2020-2026 MEmilio
3 *
4 * Authors: René Schmieding, Julia Bicker
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 
21 #ifndef MIO_D_ABM_SIMULATION_H
22 #define MIO_D_ABM_SIMULATION_H
23 
24 #include "d_abm/model.h"
25 #include "memilio/config.h"
28 
29 namespace mio
30 {
31 
32 namespace dabm
33 {
34 
39 template <class Implementation>
41 {
42  using Status = typename Implementation::Status;
43 
44 public:
46 
53  Simulation(const Model& model, ScalarType t0 = 0, ScalarType dt = 0.1)
54  : m_t0(t0)
55  , m_dt(dt)
56  , m_model(std::make_unique<Model>(model))
57  , m_result(t0, m_model->time_point())
58  {
59  assert(dt > 0);
60  m_current_rates.reserve(m_model->populations.size());
61  m_current_events.reserve(m_model->populations.size());
62  }
63 
69  void advance(const ScalarType t_max)
70  {
71  // draw time until an adoption takes place
72  ScalarType waiting_time = mio::ExponentialDistribution<ScalarType>::get_instance()(m_model->get_rng(), 1.0);
73  while (m_t0 < t_max) {
74  ScalarType dt = std::min({m_dt, t_max - m_t0});
75  ScalarType remaining_time = dt;
76  while (remaining_time > 0) {
77  compute_current_rates_and_events(); // lambda_k (aka f-hat(N))
78  ScalarType cumulative_adoption_rate =
79  std::accumulate(m_current_rates.begin(), m_current_rates.end(), 0.0); // Lambda
80  // status update
81  if (waiting_time < cumulative_adoption_rate * remaining_time) {
82  // draw which adoption takes place
83  const size_t event_id =
84  mio::DiscreteDistribution<size_t>::get_instance()(m_model->get_rng(), m_current_rates);
85  Event& event = m_current_events[event_id];
86  // perform adoption
87  m_model->adopt(event.agent, event.new_status);
88  // draw new waiting time
89  remaining_time -= waiting_time / cumulative_adoption_rate;
90  waiting_time = mio::ExponentialDistribution<ScalarType>::get_instance()(m_model->get_rng(), 1.0);
91  }
92  else {
93  // no event, decrease waiting time
94  waiting_time -= cumulative_adoption_rate * remaining_time;
95  break;
96  }
97  }
98  // position update
99  for (auto& agent : m_model->populations) {
100  m_model->move(m_t0, dt, agent);
101  }
102  m_t0 += dt;
103  // store result
104  m_result.add_time_point(m_t0, m_model->time_point());
105  }
106  }
107 
113  {
114  return m_result;
115  }
117  {
118  return m_result;
119  }
120 
124  const Model& get_model() const
125  {
126  return *m_model;
127  }
129  {
130  return *m_model;
131  }
132 
133 private:
137  struct Event {
138  typename Model::Agent& agent;
140  };
141 
146  {
147  m_current_rates.clear();
148  m_current_events.clear();
149  // compute rate for each (agent, status) combination
150  for (auto& agent : m_model->populations) {
151  for (int s = 0; s < static_cast<int>(Status::Count); s++) {
152  Status new_status = static_cast<Status>(s);
153  // check if an adoption from the agents status is possible
154  auto adoption_rate = m_model->adoption_rate(agent, new_status);
155  if (adoption_rate > 0) {
156  // add rate and corresponding event
157  m_current_rates.push_back(adoption_rate);
158  m_current_events.push_back({agent, new_status});
159  }
160  }
161  }
162  }
163 
165  std::unique_ptr<Model> m_model;
166  std::vector<ScalarType> m_current_rates;
167  std::vector<Event> m_current_events;
169 };
170 } //namespace dabm
171 } // namespace mio
172 
173 #endif
Eigen::Ref< Vector > add_time_point()
add one uninitialized time point
Definition: time_series.h:221
Wrap an implementation of a diffusive ABM so it can be run by the d_abm::Simulation.
Definition: d_abm/model.h:37
typename Implementation::Agent Agent
An agent is expected to contain at least a status and a position.
Definition: d_abm/model.h:76
A specialized Simulation for mio::dabm::Model.
Definition: models/d_abm/simulation.h:41
std::unique_ptr< Model > m_model
Pointer to the model used in the simulation.
Definition: models/d_abm/simulation.h:165
std::vector< Event > m_current_events
Contains an event corresponding to each rate in m_current_rates.
Definition: models/d_abm/simulation.h:167
TimeSeries< ScalarType > & get_result()
Returns the final simulation result.
Definition: models/d_abm/simulation.h:112
Model & get_model()
Definition: models/d_abm/simulation.h:128
std::vector< ScalarType > m_current_rates
Current adoption rates.
Definition: models/d_abm/simulation.h:166
const Model & get_model() const
Returns the model used in the simulation.
Definition: models/d_abm/simulation.h:124
Simulation(const Model &model, ScalarType t0=0, ScalarType dt=0.1)
Set up the simulation for a diffusive ABM.
Definition: models/d_abm/simulation.h:53
void advance(const ScalarType t_max)
Advance simulation to tmax.
Definition: models/d_abm/simulation.h:69
mio::TimeSeries< ScalarType > m_result
Result time series.
Definition: models/d_abm/simulation.h:168
typename Implementation::Status Status
Definition: models/d_abm/simulation.h:42
const TimeSeries< ScalarType > & get_result() const
Definition: models/d_abm/simulation.h:116
ScalarType m_t0
Definition: models/d_abm/simulation.h:164
void compute_current_rates_and_events()
Calculate current values for m_current_rates and m_current_events.
Definition: models/d_abm/simulation.h:145
ScalarType m_dt
Start time of the simulation and integration step size.
Definition: models/d_abm/simulation.h:164
double ScalarType
Configuration of memilio library.
Definition: memilio/config.h:30
static min_max_return_type< ad::internal::active_type< AD_TAPE_REAL, DATA_HANDLER_1 >, ad::internal::active_type< AD_TAPE_REAL, DATA_HANDLER_1 > >::type min(const ad::internal::active_type< AD_TAPE_REAL, DATA_HANDLER_1 > &a, const ad::internal::active_type< AD_TAPE_REAL, DATA_HANDLER_1 > &b)
Definition: ad.hpp:2599
A collection of classes to simplify handling of matrix shapes in meta programming.
Definition: models/abm/analyze_result.h:30
Definition: io.h:94
Struct defining an adoption event for an agent and target infection state.
Definition: models/d_abm/simulation.h:137
Status new_status
Definition: models/d_abm/simulation.h:139
Model::Agent & agent
Definition: models/d_abm/simulation.h:138