Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion cpp/benchmarks/flow_simulation_ode_secirvvs.h
Original file line number Diff line number Diff line change
Expand Up @@ -719,7 +719,8 @@ void setup_model(Model& model)
model.parameters.template get<osecirvvs::ReducTimeInfectedMild<ScalarType>>()[AgeGroup(0)] = 0.9;

model.parameters.template get<osecirvvs::Seasonality<ScalarType>>() = 0.2;

// The function apply_constraints() ensures that all parameters are within their defined bounds.
// Note that negative values are set to zero instead of stopping the simulation.
model.apply_constraints();
}

Expand Down
3 changes: 2 additions & 1 deletion cpp/examples/graph_stochastic_mobility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ int main(int /*argc*/, char** /*argv*/)
contact_matrix.add_damping(
Eigen::MatrixX<ScalarType>::Constant((size_t)num_age_groups, (size_t)num_age_groups, 0.6),
mio::SimulationTime<ScalarType>(5.));

// The function apply_constraints() ensures that all parameters are within their defined bounds.
// Note that negative values are set to zero instead of stopping the simulation.
model.apply_constraints();

//modify model for second node
Expand Down
3 changes: 2 additions & 1 deletion cpp/examples/ode_secir.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ int main()
model.parameters.get<mio::osecir::SeverePerInfectedSymptoms<ScalarType>>() = 0.2;
model.parameters.get<mio::osecir::CriticalPerSevere<ScalarType>>() = 0.25;
model.parameters.get<mio::osecir::DeathsPerCritical<ScalarType>>() = 0.3;

// The function apply_constraints() ensures that all parameters are within their defined bounds.
// Note that negative values are set to zero instead of stopping the simulation.
model.apply_constraints();

// Using default Integrator
Expand Down
9 changes: 2 additions & 7 deletions cpp/examples/ode_secir_ageres.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,6 @@ int main()
ScalarType nb_total_t0 = 10000, nb_exp_t0 = 100, nb_inf_t0 = 50, nb_car_t0 = 50, nb_hosp_t0 = 20, nb_icu_t0 = 10,
nb_rec_t0 = 10, nb_dead_t0 = 0;

// alpha = alpha_in; // percentage of asymptomatic cases
// beta = beta_in; // risk of infection from the infected symptomatic patients
// rho = rho_in; // hospitalized per infected
// theta = theta_in; // icu per hospitalized
// delta = delta_in; // deaths per ICUs

mio::osecir::Model<ScalarType> model(3);
auto nb_groups = model.parameters.get_num_groups();
ScalarType fact = 1.0 / (ScalarType)(size_t)nb_groups;
Expand Down Expand Up @@ -82,7 +76,8 @@ int main()
params.get<mio::osecir::CriticalPerSevere<ScalarType>>()[i] = 0.25;
params.get<mio::osecir::DeathsPerCritical<ScalarType>>()[i] = 0.3;
}

// The function apply_constraints() ensures that all parameters are within their defined bounds.
// Note that negative values are set to zero instead of stopping the simulation.
model.apply_constraints();

mio::ContactMatrixGroup<ScalarType>& contact_matrix = params.get<mio::osecir::ContactPatterns<ScalarType>>();
Expand Down
3 changes: 2 additions & 1 deletion cpp/examples/ode_secir_feedback.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ void initialize_model(mio::osecir::Model<double>& model, int total_population, d
model.populations[{mio::AgeGroup(0), mio::osecir::InfectionState::Dead}] = 0;
model.populations.set_difference_from_total({mio::AgeGroup(0), mio::osecir::InfectionState::Susceptible},
total_population);

// The function apply_constraints() ensures that all parameters are within their defined bounds.
// Note that negative values are set to zero instead of stopping the simulation.
model.apply_constraints();
}

Expand Down
2 changes: 2 additions & 0 deletions cpp/examples/ode_secir_feedback_graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ create_graph(int num_nodes, int total_population, double cont_freq)
else {
model.populations[{mio::AgeGroup(0), mio::osecir::InfectionState::Susceptible}] = total_population;
}
// The function apply_constraints() ensures that all parameters are within their defined bounds.
// Note that negative values are set to zero instead of stopping the simulation.
model.apply_constraints();

// Determine the index for the ICU state (InfectedCritical) for the feedback mechanism
Expand Down
3 changes: 2 additions & 1 deletion cpp/examples/ode_secir_parameter_study.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@ int main()
params.get<mio::osecir::CriticalPerSevere<ScalarType>>()[i] = 0.25;
params.get<mio::osecir::DeathsPerCritical<ScalarType>>()[i] = 0.3;
}

// The function apply_constraints() ensures that all parameters are within their defined bounds.
// Note that negative values are set to zero instead of stopping the simulation.
params.apply_constraints();

mio::ContactMatrixGroup<ScalarType>& contact_matrix = params.get<mio::osecir::ContactPatterns<ScalarType>>();
Expand Down
3 changes: 2 additions & 1 deletion cpp/examples/ode_secir_read_graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ int main(int argc, char** argv)
params.get<mio::osecir::CriticalPerSevere<ScalarType>>()[i] = 0.25;
params.get<mio::osecir::DeathsPerCritical<ScalarType>>()[i] = 0.3;
}

// The function apply_constraints() ensures that all parameters are within their defined bounds.
// Note that negative values are set to zero instead of stopping the simulation.
params.apply_constraints();

mio::ContactMatrixGroup<ScalarType>& contact_matrix = params.get<mio::osecir::ContactPatterns<ScalarType>>();
Expand Down
3 changes: 2 additions & 1 deletion cpp/examples/ode_secir_save_results.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ int main()
params.get<mio::osecir::CriticalPerSevere<ScalarType>>()[i] = 0.25;
params.get<mio::osecir::DeathsPerCritical<ScalarType>>()[i] = 0.3;
}

// The function apply_constraints() ensures that all parameters are within their defined bounds.
// Note that negative values are set to zero instead of stopping the simulation.
params.apply_constraints();

mio::ContactMatrixGroup<ScalarType>& contact_matrix = params.get<mio::osecir::ContactPatterns<ScalarType>>();
Expand Down
3 changes: 2 additions & 1 deletion cpp/examples/ode_secirts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,8 @@ int main()
mio::SimulationTime<ScalarType>(30.));

model.parameters.get<mio::osecirts::Seasonality<ScalarType>>() = 0.2;

// The function apply_constraints() ensures that all parameters are within their defined bounds.
// Note that negative values are set to zero instead of stopping the simulation.
model.apply_constraints();

mio::TimeSeries<ScalarType> result = mio::osecirts::simulate<ScalarType>(t0, tmax, dt, model);
Expand Down
3 changes: 2 additions & 1 deletion cpp/examples/ode_secirvvs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,8 @@ int main()
model.parameters.get<mio::osecirvvs::ReducTimeInfectedMild<double>>()[mio::AgeGroup(0)] = 0.9;

model.parameters.get<mio::osecirvvs::Seasonality<double>>() = 0.2;

// The function apply_constraints() ensures that all parameters are within their defined bounds.
// Note that negative values are set to zero instead of stopping the simulation.
model.apply_constraints();

// use adaptive Runge-Kutta-Fehlberg45 scheme as integrator
Expand Down
3 changes: 2 additions & 1 deletion cpp/examples/ode_seir_ageres.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ int main()
mio::ContactMatrix<ScalarType>(Eigen::MatrixX<ScalarType>::Constant(num_groups, num_groups, fact * cont_freq));
contact_matrix.add_damping(Eigen::MatrixX<ScalarType>::Constant(num_groups, num_groups, 0.7),
mio::SimulationTime<ScalarType>(30.));

// The function apply_constraints() ensures that all parameters are within their defined bounds.
// Note that negative values are set to zero instead of stopping the simulation.
model.apply_constraints();

auto seir = mio::simulate<ScalarType>(t0, tmax, dt, model);
Expand Down
3 changes: 2 additions & 1 deletion cpp/examples/ode_sir_ageres.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ int main()
mio::ContactMatrix<ScalarType>(Eigen::MatrixXd::Constant(num_groups, num_groups, fact * cont_freq));
contact_matrix.add_damping(Eigen::MatrixXd::Constant(num_groups, num_groups, 0.7),
mio::SimulationTime<ScalarType>(30.));

// The function apply_constraints() ensures that all parameters are within their defined bounds.
// Note that negative values are set to zero instead of stopping the simulation.
model.apply_constraints();

auto sir = mio::simulate<ScalarType>(t0, tmax, dt, model);
Expand Down
2 changes: 1 addition & 1 deletion docs/source/cpp/individual_models.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Individual-based models

There are two individual- or agent-based models (ABMs) implemented in MEmilio.
The diffusive ABM realizes agent movement through a diffusion process with disease transmission and progression modeled by stochastic jump processes.
The mobility-based ABM is much more advanced and realizes agent movement between discrete locations by either mobility rules or so-called trips.
The (mobility-based) ABM is much more advanced and realizes agent movement between discrete locations by either mobility rules or so-called trips.
Additionally, agents have much more features e.g. an individual infection history as well as features related to quarantine or immunization.


Expand Down
2 changes: 1 addition & 1 deletion docs/source/cpp/models/glsecir.rst
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ For age-resolved models, you can apply different dampings to different groups:



For more complex scenarios, such as real-world lockdown modeling, you can implement detailed NPIs with location-specific dampings. The GLCT-SECIR model supports contact matrices for different locations (e.g., home, school, work, other) and can apply different dampings to each location.
For more complex scenarios, such as real-world venue closures or lockdown modeling, you can implement detailed NPIs with location-specific dampings. The GLCT-SECIR model supports contact matrices for different locations (e.g., home, school, work, other) and can apply different dampings to each location.

Example for defining different contact locations:

Expand Down
10 changes: 6 additions & 4 deletions docs/source/cpp/models/isecir.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ IDE-based SECIR-type model
The IDE-SECIR module models and simulates an epidemic using integro-differential equations allowing for
arbitrary stay time distributions in the compartments. The model is particularly suited for pathogens with pre- or
asymptomatic infection states and when severe or critical states are possible. The model assumes perfect immunity after
recovery and is thus only suited for epidemic use cases.
In the following, we present the model in detail.
recovery. It is thus only suited for epidemic use cases and, mostly, early epidemic phases.

* A generalization of the model in the application sense that includes three immunity layers and vaccination is the :doc:`ODE-SECIRVVS model <osecirvvs>`. However, this model does not allow for arbitrary stay time distributions.
* A generalization of the model in the application sense that includes three immunity layers, vaccination, and waning immunity is the :doc:`ODE-SECIRTS model <osecirts>`. However, this model does not allow for arbitrary stay time distributions.

Below is a visualization of the infection states and transitions. The variables :math:`\sigma_{z_1}^{z_2}` refer to a transition from a compartment :math:`z_1` to a compartment :math:`z_2`.

Expand Down Expand Up @@ -53,7 +55,7 @@ The possible transitions between the **InfectionState**\s are:
`InfectedSevereToInfectedCritical`
`InfectedSevereToRecovered`
`InfectedCriticalToDead`
`InfectedCriticalToRecovered
`InfectedCriticalToRecovered`


Sociodemographic Stratification
Expand Down Expand Up @@ -230,7 +232,7 @@ For age-resolved models, you can apply different dampings to different groups:
mio::SimulationTime(30.));


For more complex scenarios, such as real-world lockdown modeling, you can implement detailed NPIs with location-specific dampings. The SECIR model supports contact matrices for different locations (e.g., home, school, work, other) and can apply different dampings to each location.
For more complex scenarios, such as real-world venue closures or lockdown modeling, you can implement detailed NPIs with location-specific dampings. The IDE-SECIR model supports contact matrices for different locations (e.g., home, school, work, other) and can apply different dampings to each location.

Example for defining different contact locations:

Expand Down
15 changes: 9 additions & 6 deletions docs/source/cpp/models/lsecir.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@
LCT-based SECIR-type model
==========================

The LCT-SECIR module models and simulates an epidemic using an ODE-based approach while making use of the Linear Chain
This provides the option of Erlang distributed stay times in the compartments through the use of subcompartments.
The model is particularly suited for pathogens with pre- or asymptomatic infection states and when severe or critical states are possible. The model assumes perfect immunity after recovery and is thus only suited for epidemic use cases.
The LCT-SECIR module models and simulates an epidemic using an ODE-based SECIR-type model approach while making use of the Linear Chain Trick (LCT).
Throught the LCT, exponentially distributed stay times are replaced by Gamma or Erlang distributed stay times by defining the compartments through the use of subcompartments.
The model is particularly suited for pathogens with pre- or asymptomatic infection states and when severe or critical states are possible. The model assumes perfect immunity after recovery. It is thus only suited for epidemic use cases and, mostly, early epidemic phases.

Below is a visualization of the infection states and transitions without a stratification according to socisdemographic groups.
* A generalization of the model that allows for arbitrary distributed stay times is the :doc:`IDE-SECIR model <isecir>`.
* A generalization of the model in the application sense that includes three immunity layers and vaccination is the :doc:`ODE-SECIRVVS model <osecirvvs>`. However, this model does not allow for arbitrary stay time distributions.
* A generalization of the model in the application sense that includes three immunity layers, vaccination, and waning immunity is the :doc:`ODE-SECIRTS model <osecirts>`. However, this model does not allow for arbitrary stay time distributions.

Below is a visualization of the infection states and transitions without a stratification according to sociodemographic groups.

.. image:: https://github.com/SciCompMod/memilio/assets/70579874/6a5d5a95-20f9-4176-8894-c091bd48bfb7
:alt: tikzLCTSECIR
Expand Down Expand Up @@ -220,8 +224,7 @@ For age-resolved models, you can apply different dampings to different groups:
contact_matrix.add_damping(Eigen::VectorX<ScalarType>::Constant(num_agegroups, 0.7).asDiagonal(),
mio::SimulationTime(30.));


For more complex scenarios, such as real-world lockdown modeling, you can implement detailed NPIs with location-specific dampings. The LCT-SECIR model supports contact matrices for different locations (e.g., home, school, work, other) and can apply different dampings to each location.
For more complex scenarios, such as real-world venue closures or lockdown modeling, you can implement detailed NPIs with location-specific dampings. The LCT-SECIR model supports contact matrices for different locations (e.g., home, school, work, other) and can apply different dampings to each location.

Example for defining different contact locations:

Expand Down
22 changes: 16 additions & 6 deletions docs/source/cpp/models/osecir.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@ ODE-based SECIR-type model

The ODE-SECIR module models and simulates an epidemic using an ODE-based SECIR-type model approach.
The model is particularly suited for pathogens with pre- or asymptomatic infection states and when severe or critical
symptoms are possible. The model assumes perfect immunity after recovery and is thus only suited for epidemic use cases.
symptoms are possible. The model assumes perfect immunity after recovery. It is thus only suited for epidemic use cases
and, mostly, early epidemic phases.

* A generalization of the model that allows for Gamma or Erlang distributed stay times is the :doc:`LCT-SECIR model <lsecir>`.
* A generalization of the model that allows for arbitrary distributed stay times is the :doc:`IDE-SECIR model <isecir>`.
* A generalization of the model that includes three immunity layers and vaccination is the :doc:`ODE-SECIRVVS model <osecirvvs>`.
* A generalization of the model that includes three immunity layers, vaccination, and waning immunity is the :doc:`ODE-SECIRTS model <osecirts>`.

The infection states and the transitions (also see next two sections) are visualized in the following graph.

Expand Down Expand Up @@ -187,9 +193,7 @@ For age-resolved models, you can apply different dampings to different groups:
contact_matrix.add_damping(Eigen::VectorX<ScalarType>::Constant((size_t)nb_groups, 0.7).asDiagonal(),
mio::SimulationTime(30.));

The SECIR model also supports dynamic NPIs based on epidemic thresholds. These are implemented in the model specific **Simulation** class and are automatically triggered based on predefined criteria, such as the percentage of infected individuals in the population.

For more complex scenarios, such as real-world lockdown modeling, you can implement detailed NPIs with location-specific dampings. The SECIR model supports contact matrices for different locations (e.g., home, school, work, other) and can apply different dampings to each location.
For more complex scenarios, such as real-world venue closures or lockdown modeling, you can implement detailed NPIs with location-specific dampings. The ODE-SECIR model supports contact matrices for different locations (e.g., home, school, work, other) and can apply different dampings to each location.

Example for defining different contact locations:

Expand Down Expand Up @@ -251,7 +255,13 @@ A complex lockdown scenario with multiple interventions starting on a specific d
contact_dampings.push_back(social_events(start_lockdown, 0.6, 0.8));
contact_dampings.push_back(physical_distancing(start_lockdown, 0.4, 0.6));

For dynamic NPIs that are automatically activated based on thresholds:
A more advanced structure to automatically activate interventions based on threshold criteria is given by **DynamicNPIs**.
Dynamic NPIs can be configured to trigger when the number of symptomatic infected individuals exceeds a certain relative threshold in the population.
In contrast to static NPIs which are active as long as no other NPI gets implemented, dynamic NPIs are checked at regular intervals and get
activated for a defined duration when the threshold is exceeded. As above, different dampings `contact_dampings` can be assigned to different contact locations
and are then triggered all at once the threshold is exceeded.
The following example shows how to set up dynamic NPIs based on the number of 200 symptomatic infected individuals per 100,000 population.
It will be active for at least 14 days and checked every 3 days. If the last check after day 14 is negative, the NPI will be deactivated.

.. code-block:: cpp

Expand All @@ -260,7 +270,7 @@ For dynamic NPIs that are automatically activated based on thresholds:
dynamic_npis.set_interval(mio::SimulationTime(3.0)); // Check every 3 days
dynamic_npis.set_duration(mio::SimulationTime(14.0)); // Apply for 14 days
dynamic_npis.set_base_value(100'000); // Per 100,000 population
dynamic_npis.set_threshold(200.0, dampings); // Trigger at 200 cases per 100,000
dynamic_npis.set_threshold(200.0, contact_dampings); // Trigger at 200 cases per 100,000


Simulation
Expand Down
Loading