20 #ifndef MIO_MOBILITY_GRAPH_SIMULATION_H
21 #define MIO_MOBILITY_GRAPH_SIMULATION_H
34 template <
class GraphT,
class Timepo
int,
class Timespan,
class edge_f,
class node_f>
91 template <
typename FP,
class Graph,
class Timepoint,
class Timespan,
103 auto dt = Base::m_dt;
104 while (Base::m_t < t_max) {
105 if (Base::m_t + dt > t_max) {
106 dt = t_max - Base::m_t;
109 for (
auto& n : Base::m_graph.nodes()) {
110 Base::m_node_func(Base::m_t, dt, n.property);
115 for (
auto& e : Base::m_graph.edges()) {
116 Base::m_edge_func(Base::m_t, dt, e.property, Base::m_graph.nodes()[e.start_node_idx].property,
117 Base::m_graph.nodes()[e.end_node_idx].property);
123 template <
typename FP,
class Graph>
141 :
Base(t0, dt, g, node_func,
std::move(edge_func))
142 , m_rates(
Base::m_graph.edges().
size() *
143 Base::m_graph.edges()[0].property.get_parameters().get_coefficients().get_shape().rows())
148 :
Base(t0, dt,
std::move(g), node_func,
std::move(edge_func))
149 , m_rates(
Base::m_graph.edges().
size() *
150 Base::m_graph.edges()[0].property.get_parameters().get_coefficients().get_shape().rows())
157 ScalarType normalized_waiting_time = ExponentialDistribution<ScalarType>::get_instance()(m_rng, 1.0);
158 std::vector<ScalarType> dt_cand(Base::m_graph.nodes().
size());
160 size_t parameters_per_edge =
161 size_t(Base::m_graph.edges()[0].property.get_parameters().get_coefficients().get_shape().rows());
162 std::vector<ScalarType> transition_rates(parameters_per_edge * Base::m_graph.edges().
size());
163 while (Base::m_t < t_max) {
164 Base::m_dt =
std::min({Base::m_dt, t_max - Base::m_t});
166 cumulative_rate = get_cumulative_transition_rate();
167 if (cumulative_rate * Base::m_dt >
168 normalized_waiting_time) {
173 size_t event = mio::DiscreteDistribution<size_t>::get_instance()(m_rng, m_rates);
175 auto& event_edge = Base::m_graph.edges()[
event / parameters_per_edge];
177 auto flat_index =
event % parameters_per_edge;
180 for (
size_t node_iter = 0; node_iter < Base::m_graph.nodes().size(); ++node_iter) {
181 auto& node = Base::m_graph.nodes()[node_iter];
182 Base::m_node_func(Base::m_t, normalized_waiting_time / cumulative_rate, node.property);
186 Base::m_t += normalized_waiting_time / cumulative_rate;
189 Base::m_dt -= normalized_waiting_time / cumulative_rate;
192 Base::m_edge_func(event_edge.property, flat_index,
193 Base::m_graph.nodes()[event_edge.start_node_idx].property,
194 Base::m_graph.nodes()[event_edge.end_node_idx].property);
197 cumulative_rate = get_cumulative_transition_rate();
200 normalized_waiting_time = ExponentialDistribution<ScalarType>::get_instance()(m_rng, 1.0);
202 }
while (cumulative_rate * Base::m_dt > normalized_waiting_time);
205 normalized_waiting_time -= cumulative_rate * Base::m_dt;
209 for (
size_t node_iter = 0; node_iter < Base::m_graph.nodes().size(); ++node_iter) {
210 auto& node = Base::m_graph.nodes()[node_iter];
211 Base::m_node_func(Base::m_t, Base::m_dt, node.property);
213 dt_cand[node_iter] = node.property.get_simulation().get_dt();
217 Base::m_t += Base::m_dt;
219 Base::m_dt = *std::min_element(dt_cand.begin(), dt_cand.end());
232 FP cumulative_transition_rate = 0.0;
233 for (
auto& e : Base::m_graph.edges()) {
234 cumulative_transition_rate +=
235 e.property.get_transition_rates(Base::m_graph.nodes()[e.start_node_idx].property).sum();
237 return cumulative_transition_rate;
243 for (
auto& e : Base::m_graph.edges()) {
244 auto edge_rates = e.property.get_transition_rates(Base::m_graph.nodes()[e.start_node_idx].property);
245 for (Eigen::Index
i = 0;
i < edge_rates.size(); ++
i) {
246 const auto compartment_value =
247 Base::m_graph.nodes()[e.start_node_idx].property.get_result().get_last_value()[
i];
248 rates[j] = (compartment_value < 1.0) ? 0.0 : edge_rates(
i);
259 template <
typename FP,
typename Timepo
int,
class Timespan,
class Graph,
class NodeF,
class EdgeF>
263 t0, dt, std::forward<Graph>(g), std::forward<NodeF>(node_func), std::forward<EdgeF>(edge_func));
266 template <
typename FP,
class Graph,
class NodeF,
class EdgeF>
270 t0, dt, std::forward<Graph>(g), std::forward<NodeF>(node_func), std::forward<EdgeF>(edge_func));
279 template <
typename FP,
typename Sim,
typename ContactPatterns>
283 template <
typename FP,
class Graph>
294 using SimT = decltype(
m_graph.
nodes()[0].property.get_simulation());
296 "Graph node simulation must be a FeedbackSimulation.");
308 while (
m_t < t_max) {
316 node.property.get_simulation().advance(
m_t + dt_eff,
m_dt);
323 edge.property.apply_mobility(
m_t,
m_dt, node_from.property, node_to.property);
346 auto& first_node_sim =
m_graph.
nodes()[0].property.get_simulation();
347 auto& first_node_icu = first_node_sim.get_parameters().template get<ICUOccupancyHistory<FP>>();
351 FP total_population = 0;
352 for (Eigen::Index
i = 0;
i < first_node_icu.get_num_time_points(); ++
i) {
353 Eigen::VectorXd sum = Eigen::VectorXd::Zero(first_node_icu.get_num_elements());
355 auto& sim = node.property.get_simulation();
356 auto& icu_history = sim.get_parameters().template get<ICUOccupancyHistory<FP>>();
357 sum += icu_history.get_value(
i) * node.property.get_simulation().get_model().populations.get_total();
358 total_population += node.property.get_simulation().get_model().populations.get_total();
371 std::unordered_map<int, FP> regional_population;
374 regional_population[region_id] += node.property.get_simulation().get_model().populations.get_total();
377 auto& first_node_sim =
m_graph.
nodes()[0].property.get_simulation();
378 auto& first_node_icu = first_node_sim.get_parameters().template get<ICUOccupancyHistory<FP>>();
379 Eigen::Index num_time_points = first_node_icu.get_num_time_points();
380 Eigen::Index num_elements = first_node_icu.get_num_elements();
383 std::unordered_map<int, std::vector<Eigen::VectorXd>> regional_sums;
384 for (
auto const& [region_id, _] : regional_population) {
385 regional_sums[region_id] =
386 std::vector<Eigen::VectorXd>(num_time_points, Eigen::VectorXd::Zero(num_elements));
392 auto& sim = node.property.get_simulation();
393 auto& icu_history = sim.get_parameters().template get<ICUOccupancyHistory<FP>>();
394 FP pop = node.property.get_simulation().get_model().populations.get_total();
395 for (Eigen::Index
i = 0;
i < num_time_points; ++
i) {
396 regional_sums[region_id][
i] += icu_history.get_value(
i) * pop;
402 for (
auto const& [region_id, sum_vec] : regional_sums) {
404 for (Eigen::Index
i = 0;
i < num_time_points; ++
i) {
405 ts.
add_time_point(first_node_icu.get_time(
i), sum_vec[
i] / regional_population[region_id]);
417 FP total_population = 0;
420 auto& sim = node.property.get_simulation();
421 auto& icu_history = sim.get_parameters().template get<ICUOccupancyHistory<FP>>();
422 sum += icu_history.get_last_value() * node.property.get_simulation().get_model().populations.get_total();
423 total_population += node.property.get_simulation().get_model().populations.get_total();
435 std::unordered_map<int, FP> regional_population;
437 Eigen::VectorXd sum = Eigen::VectorXd::Zero(regional_data.get_num_elements());
440 auto& sim = node.property.get_simulation();
441 auto& icu_history = sim.get_parameters().template get<ICUOccupancyHistory<FP>>();
442 sum += icu_history.get_last_value() *
443 node.property.get_simulation().get_model().populations.get_total();
444 regional_population[region_id] +=
445 node.property.get_simulation().get_model().populations.get_total();
448 regional_data.add_time_point(
m_t, sum / regional_population[region_id]);
460 auto& sim = node.property.get_simulation();
Definition: graph_simulation.h:285
bool m_initialized
Definition: graph_simulation.h:469
Graph & get_graph()
Definition: graph_simulation.h:334
std::unordered_map< int, mio::TimeSeries< FP > > m_regional_icu_occupancy
Definition: graph_simulation.h:471
void calculate_regional_icu_occupancy()
Calculates the regional ICU occupancy for each region.
Definition: graph_simulation.h:369
void update_regional_icu_occupancy()
Updates the regional ICU occupancy for each region with the latest values.
Definition: graph_simulation.h:432
Graph m_graph
Definition: graph_simulation.h:466
mio::TimeSeries< FP > m_global_icu_occupancy
Definition: graph_simulation.h:470
void distribute_icu_data()
Distributes the calculated global and regional ICU occupancy data to each node.
Definition: graph_simulation.h:456
void calculate_global_icu_occupancy()
Calculates the global ICU occupancy based on the ICU history of all nodes.
Definition: graph_simulation.h:344
FP m_t
Definition: graph_simulation.h:467
FeedbackGraphSimulation(Graph &&g, FP t0, FP dt)
Definition: graph_simulation.h:287
void update_global_icu_occupancy()
Updates the global ICU occupancy with the latest values from all nodes.
Definition: graph_simulation.h:415
FP m_dt
Definition: graph_simulation.h:468
void advance(FP t_max)
Definition: graph_simulation.h:299
A generic feedback simulation extending existing simulations with a feedback mechanism.
Definition: feedback_simulation.h:214
abstract simulation on a graph with alternating node and edge actions
Definition: graph_simulation.h:36
Graph m_graph
Definition: graph_simulation.h:86
Graph && get_graph() &&
Definition: graph_simulation.h:78
node_function m_node_func
Definition: graph_simulation.h:87
Timepoint get_t() const
Definition: graph_simulation.h:63
edge_f edge_function
Definition: graph_simulation.h:41
edge_function m_edge_func
Definition: graph_simulation.h:88
const Graph & get_graph() const &
Definition: graph_simulation.h:73
GraphSimulationBase(Timepoint t0, Timespan dt, const Graph &g, const node_function &node_func, const edge_function &&edge_func)
Definition: graph_simulation.h:43
GraphT Graph
Definition: graph_simulation.h:38
Graph & get_graph() &
Definition: graph_simulation.h:68
node_f node_function
Definition: graph_simulation.h:40
Timepoint m_t
Definition: graph_simulation.h:84
Timespan m_dt
Definition: graph_simulation.h:85
GraphSimulationBase(Timepoint t0, Timespan dt, Graph &&g, const node_function &node_func, const edge_function &&edge_func)
Definition: graph_simulation.h:53
Definition: graph_simulation.h:129
typename Base::node_function node_function
Definition: graph_simulation.h:135
RandomNumberGenerator m_rng
Definition: graph_simulation.h:256
void advance(FP t_max)
Definition: graph_simulation.h:154
std::vector< FP > m_rates
Definition: graph_simulation.h:255
GraphSimulationStochastic(FP t0, FP dt, const Graph &g, const node_function &node_func, const edge_function &&edge_func)
Definition: graph_simulation.h:139
RandomNumberGenerator & get_rng()
Definition: graph_simulation.h:223
typename Base::edge_function edge_function
Definition: graph_simulation.h:136
FP get_cumulative_transition_rate()
Definition: graph_simulation.h:229
GraphSimulationStochastic(FP t0, FP dt, Graph &&g, const node_function &node_func, const edge_function &&edge_func)
Definition: graph_simulation.h:147
void get_rates(std::vector< FP > &rates)
Definition: graph_simulation.h:240
Definition: graph_simulation.h:96
void advance(Timepoint t_max=1.0)
Definition: graph_simulation.h:101
generic graph structure
Definition: graph.h:153
auto edges()
range of edges
Definition: graph.h:267
NodePropertyT NodeProperty
Definition: graph.h:155
auto nodes()
range of nodes
Definition: graph.h:251
EdgePropertyT EdgeProperty
Definition: graph.h:156
stores vectors of values at time points (or some other abstract variable) the value at each time poin...
Definition: time_series.h:58
Eigen::Ref< Vector > add_time_point()
add one uninitialized time point
Definition: time_series.h:221
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
trait_value< T >::RETURN_TYPE & value(T &x)
Definition: ad.hpp:3308
int size(Comm comm)
Return the size of the given communicator.
Definition: miompi.cpp:75
StateId get_state_id(int county)
get the id of the state that the specified county is in.
Definition: regions.cpp:32
A collection of classes to simplify handling of matrix shapes in meta programming.
Definition: models/abm/analyze_result.h:30
auto i
Definition: io.h:809
auto make_graph_sim_stochastic(FP t0, FP dt, Graph &&g, NodeF &&node_func, EdgeF &&edge_func)
Definition: graph_simulation.h:267
auto make_graph_sim(Timepoint t0, Timespan dt, Graph &&g, NodeF &&node_func, EdgeF &&edge_func)
Definition: graph_simulation.h:260
Definition: graph_simulation.h:276