Skip to content

1306 further extend and review the documentation #1314

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 17 commits into
base: main
Choose a base branch
from
Draft
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ and, in particular, for
- Hybrid agent-metapopulation-based models: Bicker J, Schmieding R, Meyer-Hermann M, Kühn MJ. (2025). *Hybrid metapopulation agent-based epidemiological models for efficient insight on the individual scale: A contribution to green computing*. *Infectious Disease Modelling* 10(2): 571-590. `https://doi.org/10.1016/j.idm.2024.12.015`
- Graph Neural Networks: Schmidt A, Zunker H, Heinlein A, Kühn MJ. (2024). *Towards Graph Neural Network Surrogates Leveraging Mechanistic Expert Knowledge for Pandemic Response*. arXiv. `https://arxiv.org/abs/2411.06500`
- ODE-based models with Linear Chain Trick: Plötzke L, Wendler A, Schmieding R, Kühn MJ. (2024). *Revisiting the Linear Chain Trick in epidemiological models: Implications of underlying assumptions for numerical solutions*. Submitted for publication. `https://doi.org/10.48550/arXiv.2412.09140`
- Behavior-based ODE models: Zunker H, Dönges P, Lenz P, Contreras S, Kühn MJ. (2025). *Risk-mediated dynamic regulation of effective contacts de-synchronizes outbreaks in metapopulation epidemic models*. arXiv. `https://arxiv.org/abs/2502.14428`
- Behavior-based ODE models: Zunker H, Dönges P, Lenz P, Contreras S, Kühn MJ. (2025). *Risk-mediated dynamic regulation of effective contacts de-synchronizes outbreaks in metapopulation epidemic models*. *Chaos, Solitons & Fractals* 199:116782. `https://doi.org/10.1016/j.chaos.2025.116782`

**Getting started**

Expand Down
5 changes: 3 additions & 2 deletions docs/source/citation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Citing MEmilio

If you use MEmilio, please cite our work

- Kühn, Martin Joachim et al. (2025). *MEmilio - a High Performance Modular Epidemics Simulation Software (2022)*. Available at `https://github.com/SciCompMod/memilio <https://github.com/SciCompMod/memilio>`_ and `https://elib.dlr.de/213614/ <https://elib.dlr.de/213614/>`_.
- Bicker J, Kerkmann D, Korf S, Ploetzke L, Schmieding R, Wendler A, Zunker H et al. (2025). *MEmilio - a High Performance Modular Epidemics Simulation Software*. Available at `https://github.com/SciCompMod/memilio <https://github.com/SciCompMod/memilio>`_ and `https://elib.dlr.de/213614/ <https://elib.dlr.de/213614/>`_.

and, in particular, for

Expand All @@ -13,4 +13,5 @@ and, in particular, for
- **Hybrid agent-metapopulation-based models**: Bicker J, Schmieding R, Meyer-Hermann M, Kühn MJ. (2025). *Hybrid metapopulation agent-based epidemiological models for efficient insight on the individual scale: A contribution to green computing*. *Infectious Disease Modelling* 10(2): 571-590. `DOI:10.1016/j.idm.2024.12.015 <https://doi.org/10.1016/j.idm.2024.12.015>`_
- **Graph Neural Networks**: Schmidt A, Zunker H, Heinlein A, Kühn MJ. (2024).*Towards Graph Neural Network Surrogates Leveraging Mechanistic Expert Knowledge for Pandemic Response*. arXiv. `arXiv:2411.06500 <https://arxiv.org/abs/2411.06500>`_
- **ODE-based models with Linear Chain Trick**: Plötzke L, Wendler A, Schmieding R, Kühn MJ. (2024). *Revisiting the Linear Chain Trick in epidemiological models: Implications of underlying assumptions for numerical solutions*. Submitted for publication. `DOI:10.48550/arXiv.2412.09140 <https://doi.org/10.48550/arXiv.2412.09140>`_
- **Behavior-based ODE models**: Zunker H, Dönges P, Lenz P, Contreras S, Kühn MJ. (2025). *Risk-mediated dynamic regulation of effective contacts de-synchronizes outbreaks in metapopulation epidemic models*. arXiv. `arXiv:2502.14428 <https://arxiv.org/abs/2502.14428>`_
- **Behavior-based ODE models**: Zunker H, Dönges P, Lenz P, Contreras S, Kühn MJ. (2025). *Risk-mediated dynamic regulation of effective contacts de-synchronizes outbreaks in metapopulation epidemic models*. *Chaos, Solitons & Fractals* 199:116782. `DOI:10.1016/j.chaos.2025.116782 <https://doi.org/10.1016/j.chaos.2025.116782>`_

24 changes: 16 additions & 8 deletions docs/source/cpp/development.rst
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
Development
=================================
===========

.. _performance-monitoring-cpp:

Performance monitoring
---------------------------------
----------------------

LIKWID
~~~~~~
Expand All @@ -30,11 +30,15 @@ Set the CMake variable ``MEMILIO_USE_LIKWID=ON`` to enable LIKWID support and ru
For more details see the LIKWID documentation, available `here <https://github.com/RRZE-HPC/likwid/wiki/likwid-perfctr>`_.

Agent-based model benchmarks
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

There is a suite of benchmarks for the ABM that can be used to check performance. The suite contains setups of different sizes. If you added a new feature (i.e., you didn't just fix a bug in an existing feature), make sure the feature is actually used by the benchmark. Add it to the benchmark if necessary, then run the benchmark to see if the cost for the new feature is acceptable and as expected.
There is a suite of benchmarks for the ABM that are used to check its performance. The suite contains setups of different sizes, to check that the model maintains its linear scaling.

Most new features will add some overhead, but this needs to be limited and in proportion to the added value of the feature so runtime doesn't grow out of control. Optional features that can be disabled should only incur minimal overhead. If you did not add any new feature, just run the benchmark before and after your changes to make sure there are no performance regressions. This process will hopefully be automated soon by running benchmarks in the CI.
When you make any changes to the ABM or code used by it, run the benchmarks to check that its performance did not degrade. What exactly impacts the ABM's performance can be hard to tell (even parameter values may change its runtime), so it is best to run the bencharks on any change to the main library or the ABM specific code.

If you added a new feature (i.e., you didn't just fix a bug in an existing feature), make sure the feature is actually used by the benchmark. Add it to the benchmark if necessary, then run the benchmark to see if the cost for the new feature is acceptable and as expected.

Most new features will add some overhead, but this needs to be limited and in proportion to the added value of the feature so runtime doesn't grow out of control. Optional features that can be disabled should only incur minimal overhead. Always make sure there are no major performance regressions compared to the code in the current *main* branch.

Build the benchmarks by defining the CMake variable ``MEMILIO_BUILD_BENCHMARKS=ON`` in the build. Make sure to use a **Release** build to test performance.

Expand Down Expand Up @@ -91,6 +95,10 @@ However, it can be expensive because long-running benchmarks are repeated.

**Suggested workflow:**

1. Run with 5–10 repetitions to check variance.
2. Increase ``benchmark_min_time`` until variance is acceptable.
3. Continue benchmarking with 1 repetition and the adjusted minimum time.
1. Use the benchmark to check the performance of your current changes:

1. Run with 5–10 repetitions to check variance.
2. Increase ``benchmark_min_time`` until variance is acceptable.
3. Continue benchmarking with 1 repetition and the adjusted minimum time.

2. Repeat the benchmark *on the main branch* with the same ``benchmark_min_time`` and compare the results.
2 changes: 1 addition & 1 deletion docs/source/cpp/diffusive_abm.rst
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ There are no non-pharmaceutical interventions (NPIs) explicitly implemented in t
.. code-block:: cpp

//Reduce the transmission risk by 10%
model.get_adoption_rates().at({mio::mpm::Region(0), Status::S, Status::E}).factor *= 0.9;
model.get_adoption_rates().at({mio::regions::Region(0), Status::S, Status::E}).factor *= 0.9;

Simulation
-----------
Expand Down
25 changes: 7 additions & 18 deletions docs/source/cpp/glct.rst
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
Generalized Linear Chain Trick model
====================================

MEmilio implements a SECIR-type model utilizing the Generalized Linear Chain Trick (GLCT). This is a generalization of
the LCT model and allows for phase-type distributed stay times in the compartments. Phase-type distributions are dense
MEmilio implements a SECIR-type model utilizing the Generalized Linear Chain Trick (GLCT). This is a generalization of
the LCT model. In contrast to simpler ODE models that assume (possibly unrealistic) exponentially distributed stay times, the GLCT allows for more realistic, phase-type distributed stay times in the compartments through the use of subcompartments. Phase-type distributions are dense
in the field of all positive-valued distributions. Therefore, for any positive-valued distribution, a phase-type
distribution of arbitrary precision can be identified. Note that the resulting system can still be described by ODEs.
distribution of arbitrary precision can be identified. Note that the resulting system can still be described by an ordinary differential equation system.

In the following, we present the general structure of the GLCT model. The particular model documentation with examples
is linked at the bottom of this page.

Infection states
----------------

The model contains a list of **InfectionState**\s that define particular features of the subpopulations in the particular state.
The model contains a list of **InfectionState**s that define particular features of the subpopulations in the particular state.

.. code-block:: RST

Expand Down Expand Up @@ -43,10 +43,10 @@ a set of contact matrices of arbitrary length and which can represent the differ
schools, workplaces, or homes. The matrices can be loaded or stored in the particular example.
In the **ContactPatterns**, each matrix element stores baseline contact rates :math:`c_{i,j}` between sociodemographic
group :math:`i` to group :math:`j`. The dimension of the matrix is automatically defined by the model initiation and it is reduced
to one value if no stratifcation is used. The values can be adjusted during the simulation, e.g., through implementing
to one value if no stratification is used. The values can be adjusted during the simulation, e.g., through implementing
nonpharmaceutical interventions, see the section on :ref:`Nonpharmaceutical Interventions`.
Parameters can get accessed via ``model.parameters.get<Param<double>>()`` and set via either
``model.parameters.get<Param<double>>() = value`` or ``model.parameters.set<Param<double>>(value)``.
Parameters can be accessed via ``model.parameters.get<Param<double>>()`` and set via either
``model.parameters.set<Param<double>>(value)`` or ``model.parameters.get<Param<double>>() = value``.


Initial conditions
Expand Down Expand Up @@ -114,17 +114,6 @@ and its documentation.

In the following, we give detailed explanations of the GLCT-SECIR model.

Introduction
-------------

This model is based on the Generalized Linear Chain Trick (GLCT).

The GLCT provides the option to use phase-type distributed stay times in the compartments through the use of subcompartments. The Generalized Linear Chain Trick is an extension of the Linear Chain Trick (as the name already suggests). Phase-type distributions are dense in the field of all positive-valued distributions. Therefore, for any positive-valued distribution, a phase-type distribution of arbitrary precision can be identified.
The normal ODE models have (possibly unrealistic) exponentially distributed stay times.
The GLCT model can still be described by an ordinary differential equation system.



List of models
-----------------------------

Expand Down
20 changes: 10 additions & 10 deletions docs/source/cpp/io.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ This document describes utilities for reading and writing data from and to files

- The serialization framework, that can be used to define the structure of data without using a specific file format.
There are implementations of the framework for different formats. The framework is described in detail below, also
see the `serialization example <../../examples/serialize.cpp>`__.
see the `serialization example <https://github.com/SciCompMod/memilio/blob/main/cpp/examples/serialize.cpp>`__.

- The command line interface, that can be used to set (and get) values of a ``ParameterSet``.

Expand Down Expand Up @@ -101,7 +101,7 @@ The default serialization is intentionally less flexible than the serialize and

- Every class member itself must be serializable, deserializable and assignable.

This feature is primarily meant to make data classes easy to (de)serialize, avoiding some repitition that is necessary
This feature is primarily meant to make data classes easy to (de)serialize, avoiding some repetition that is necessary
when writing both a serialize and deserialize function. It can, however, be used for any class that should be
serialized in its entirety, and that does not need to make any decisions or computations while doing so. For example,
default serialization cannot be used if your class has optional members or values, or if one of its members is stored
Expand Down Expand Up @@ -272,8 +272,8 @@ Working with the History object
The History object provides a way to save data throughout the simulation process. It offers an interface where users can
define the data to be saved from a given object using Loggers and the method of saving it using Writers. Afterward, the
user can access this data from the History object and manipulate it. For a basic Logger use case, refer to
`this example <../../examples/history.cpp>`__. For an example demonstrating using a Logger in the ABM, refer to
`this example <../../examples/abm_history_example.cpp>`__.
`this example <https://github.com/SciCompMod/memilio/blob/main/cpp/examples/history.cpp>`__. For an example demonstrating using a Logger in the ABM, refer to
`this example <https://github.com/SciCompMod/memilio/blob/main/cpp/examples/abm_history_object.cpp>`__.

Loggers
~~~~~~~
Expand All @@ -293,7 +293,7 @@ functions is the same as the one given to the ``History`` member-function ``Hist
Users can derive their Loggers from ``LogOnce`` or ``LogAlways`` to use a predefined ``should_log`` function.
``LogOnce`` logs only at the first call of ``Logger::log()``, while ``LogAlways`` logs every time ``log`` is called.
All implemented Loggers must be default constructible/destructible. For user-defined examples in the ABM, refer to
`this file <../../models/abm/common_abm_loggers.h>`__.
`this file <https://github.com/SciCompMod/memilio/blob/main/cpp/models/abm/common_abm_loggers.h>`__.

.. code-block:: cpp

Expand Down Expand Up @@ -324,9 +324,9 @@ user-implemented ``Writer`` must have a ``Data`` Type and implement the
- ``add_record``: This manipulates the passed Data member of the ``History`` class to store the value ``t`` returned by
the Loggers. It is used whenever ``History::log`` is called and ``Logger::should_log`` is true.

A predefined universal ``Writer`` called ``DataWriterToMemory`` is already implemented in `history.h <history.h>`__.
A predefined universal ``Writer`` called ``DataWriterToMemory`` is already implemented in `history.h <https://github.com/SciCompMod/memilio/blob/main/cpp/memilio/io/history.h>`__.
This stores the data from the loggers in a tuple of vectors every time the Logger is called. Another ``Writer`` named
``TimeSeriesWriter`` can be found in `this file <../../models/abm/common_abm_loggers.h>`__, which saves data in a
``TimeSeriesWriter`` can be found in `this file <https://github.com/SciCompMod/memilio/blob/main/cpp/models/abm/common_abm_loggers.h>`__, which saves data in a
Timeseries. The according Logger has to have a suitable return type.

.. code-block:: cpp
Expand Down Expand Up @@ -354,9 +354,9 @@ For this, the lifetime of the ``History`` has to be as long as one wants to have
should not be constructed in the function it is called in when data is needed later.

To access data from a specific Logger, one can use ``std::get<x>`` where x is the position of the Logger in the template
argument list of the ``History`` object. Refer to `this example <../../examples/history.cpp>`__ for a simple
implementation of a history object and `this full ABM example <../../simulation/abm.cpp>`__ for a more advanced use case
argument list of the ``History`` object. Refer to `this example <https://github.com/SciCompMod/memilio/blob/main/cpp/examples/history.cpp>`__ for a simple
implementation of a history object and `this full ABM example <https://github.com/SciCompMod/memilio/blob/main/cpp/simulations/abm.cpp>`__ for a more advanced use case
of the History object with several History objects in use.

As mentioned, if multiple Writers have to be used simultaneously, a separate History object is needed for each Writer.
For a use case of this, refer to `the ABM Simulation advance function <../../models/abm/simulation.cpp>`__.
For a use case of this, refer to `the ABM Simulation advance function <https://github.com/SciCompMod/memilio/blob/main/cpp/models/abm/simulation.h>`__.
6 changes: 3 additions & 3 deletions docs/source/cpp/lct.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ is linked at the bottom of this page.
Infection states
----------------

The model contains a list of **InfectionState**\s that define particular features of the subpopulations in the particular state.
The model contains a list of **InfectionState**s that define particular features of the subpopulations in the particular state.

.. code-block:: RST

Expand Down Expand Up @@ -51,9 +51,9 @@ a set of contact matrices of arbitrary length and which can represent the differ
schools, workplaces, or homes. The matrices can be loaded or stored in the particular example.
In the **ContactPatterns**, each matrix element stores baseline contact rates :math:`c_{i,j}` between sociodemographic
group :math:`i` to group :math:`j`. The dimension of the matrix is automatically defined by the model initiation and it is reduced
to one value if no stratifcation is used. The values can be adjusted during the simulation, e.g., through implementing
to one value if no stratification is used. The values can be adjusted during the simulation, e.g., through implementing
nonpharmaceutical interventions, see the section on :ref:`Nonpharmaceutical Interventions`.
Parameters can get accessed via ``model.parameters.get<Param<double>>()`` and set via either
Parameters can be accessed via ``model.parameters.get<Param<double>>()`` and set via either
``model.parameters.get<Param<double>>() = value`` or ``model.parameters.set<Param<double>>(value)``.


Expand Down
Loading