Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
51ab550
CHG: functional smm example with agegroups, rest is broken
kilianvolmer Aug 13, 2025
d78bd7c
CHG: functional base model with template parameter list (not used yet)
kilianvolmer Sep 9, 2025
f2babee
CHG: Another compiling status that is not leading anywhere
kilianvolmer Sep 9, 2025
bf4b839
CHG: Compiling example with multiple age groups
kilianvolmer Sep 9, 2025
cdba056
Compiling solution without code duplicates
kilianvolmer Sep 9, 2025
c0cb41b
CHG: semifunctional state
kilianvolmer Sep 12, 2025
ee5143b
CHG: Change numbers in rates
kilianvolmer Sep 26, 2025
4823827
CHG: Move Influence into AdoptionRate
kilianvolmer Sep 26, 2025
8932144
CHG: Update influences
kilianvolmer Oct 1, 2025
098e1ff
CHG: Change location of N, modify tests
kilianvolmer Oct 1, 2025
dcda987
[skip ci] CHG: Update Header
kilianvolmer Oct 1, 2025
ace1754
Merge branch 'main' into 1341-SMM-model-with-more-indices
kilianvolmer Oct 1, 2025
c58b74a
[skip ci] Update copyright information
kilianvolmer Oct 2, 2025
17cd0b9
CHG: REplace FLOAT test by double test
kilianvolmer Oct 2, 2025
f37fbe1
Revert "[skip ci] Update copyright information"
kilianvolmer Oct 9, 2025
97e7dc6
Merge branch 'main' into 1341-SMM-model-with-more-indices
reneSchm Nov 21, 2025
d367215
generalize Region and State
reneSchm Nov 21, 2025
72a3304
fix asserts for debug builds
reneSchm Nov 25, 2025
d47625c
change test to use region as part of status
reneSchm Nov 25, 2025
d2deb8f
CHG: improve docstrings
kilianvolmer Dec 15, 2025
168116b
CHG: Update smm.rst
kilianvolmer Dec 15, 2025
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
73 changes: 43 additions & 30 deletions cpp/examples/smm.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2020-2025 MEmilio
*
* Authors: Julia Bicker, René Schmieding
* Authors: Julia Bicker, René Schmieding, Kilian Volmer
*
* Contact: Martin J. Kuehn <Martin.Kuehn@DLR.de>
*
Expand All @@ -18,11 +18,12 @@
* limitations under the License.
*/

#include "memilio/config.h"
#include "memilio/epidemiology/age_group.h"
#include "smm/simulation.h"
#include "smm/model.h"
#include "smm/parameters.h"
#include "memilio/data/analyze_result.h"
#include "memilio/epidemiology/adoption_rate.h"

enum class InfectionState
{
Expand All @@ -33,61 +34,73 @@ enum class InfectionState
R,
D,
Count
};

struct Species : public mio::Index<Species> {
Species(size_t val)
: Index<Species>(val)
{
}
};

int main()
{
using Age = mio::AgeGroup;
using Status = mio::Index<InfectionState, Age, Species>;
using mio::regions::Region;
using enum InfectionState;

//Example how to run the stochastic metapopulation models with four regions
const size_t num_regions = 4;
using Model = mio::smm::Model<ScalarType, num_regions, InfectionState>;
const size_t num_regions = 4;
const size_t num_age_groups = 1;
const size_t num_species = 1;
using Model = mio::smm::Model<ScalarType, InfectionState, Status, Region>;

ScalarType numE = 12, numC = 4, numI = 12, numR = 0, numD = 0;

Model model;
Model model(Status{Count, Age(num_age_groups), Species(num_species)}, Region(num_regions));
//Population are distributed uniformly to the four regions
for (size_t r = 0; r < num_regions; ++r) {
model.populations[{mio::regions::Region(r), InfectionState::S}] =
(1000 - numE - numC - numI - numR - numD) / num_regions;
model.populations[{mio::regions::Region(r), InfectionState::E}] = numE / num_regions;
model.populations[{mio::regions::Region(r), InfectionState::C}] = numC / num_regions;
model.populations[{mio::regions::Region(r), InfectionState::I}] = numI / num_regions;
model.populations[{mio::regions::Region(r), InfectionState::R}] = numR / num_regions;
model.populations[{mio::regions::Region(r), InfectionState::D}] = numD / num_regions;
model.populations[{Region(r), S, Age(0), Species(0)}] = (1000 - numE - numC - numI - numR - numD) / num_regions;
model.populations[{Region(r), E, Age(0), Species(0)}] = numE / num_regions;
model.populations[{Region(r), C, Age(0), Species(0)}] = numC / num_regions;
model.populations[{Region(r), I, Age(0), Species(0)}] = numI / num_regions;
model.populations[{Region(r), R, Age(0), Species(0)}] = numR / num_regions;
model.populations[{Region(r), D, Age(0), Species(0)}] = numD / num_regions;
}

using AR = mio::smm::AdoptionRates<ScalarType, Status, Region>;
using TR = mio::smm::TransitionRates<ScalarType, Status, Region>;

//Set infection state adoption and spatial transition rates
std::vector<mio::AdoptionRate<ScalarType, InfectionState>> adoption_rates;
std::vector<mio::smm::TransitionRate<ScalarType, InfectionState>> transition_rates;
AR::Type adoption_rates;
TR::Type transition_rates;
for (size_t r = 0; r < num_regions; ++r) {
adoption_rates.push_back({InfectionState::S,
InfectionState::E,
mio::regions::Region(r),
adoption_rates.push_back({{S, Age(0), Species(0)},
{E, Age(0), Species(0)},
Region(r),
0.1,
{{InfectionState::C, 1}, {InfectionState::I, 0.5}}});
adoption_rates.push_back({InfectionState::E, InfectionState::C, mio::regions::Region(r), 1.0 / 5., {}});
adoption_rates.push_back({InfectionState::C, InfectionState::R, mio::regions::Region(r), 0.2 / 3., {}});
adoption_rates.push_back({InfectionState::C, InfectionState::I, mio::regions::Region(r), 0.8 / 3., {}});
adoption_rates.push_back({InfectionState::I, InfectionState::R, mio::regions::Region(r), 0.99 / 5., {}});
adoption_rates.push_back({InfectionState::I, InfectionState::D, mio::regions::Region(r), 0.01 / 5., {}});
{{{C, Age(0), Species(0)}, 1}, {{I, Age(0), Species(0)}, 0.5}}});
adoption_rates.push_back({{C, Age(0), Species(0)}, {R, Age(0), Species(0)}, Region(r), 0.2 / 3., {}});
adoption_rates.push_back({{E, Age(0), Species(0)}, {C, Age(0), Species(0)}, Region(r), 1.0 / 5., {}});
adoption_rates.push_back({{C, Age(0), Species(0)}, {I, Age(0), Species(0)}, Region(r), 0.8 / 3., {}});
adoption_rates.push_back({{I, Age(0), Species(0)}, {R, Age(0), Species(0)}, Region(r), 0.99 / 5., {}});
adoption_rates.push_back({{I, Age(0), Species(0)}, {D, Age(0), Species(0)}, Region(r), 0.01 / 5., {}});
}

//Agents in infection state D do not transition
for (size_t s = 0; s < static_cast<size_t>(InfectionState::D); ++s) {
for (size_t s = 0; s < static_cast<size_t>(D); ++s) {
for (size_t i = 0; i < num_regions; ++i) {
for (size_t j = 0; j < num_regions; ++j)
if (i != j) {
transition_rates.push_back(
{InfectionState(s), mio::regions::Region(i), mio::regions::Region(j), 0.01});
transition_rates.push_back(
{InfectionState(s), mio::regions::Region(j), mio::regions::Region(i), 0.01});
transition_rates.push_back({{InfectionState(s), Age(0), Species(0)}, Region(i), Region(j), 0.01});
transition_rates.push_back({{InfectionState(s), Age(0), Species(0)}, Region(j), Region(i), 0.01});
}
}
}

model.parameters.get<mio::smm::AdoptionRates<ScalarType, InfectionState>>() = adoption_rates;
model.parameters.get<mio::smm::TransitionRates<ScalarType, InfectionState>>() = transition_rates;
model.parameters.get<AR>() = adoption_rates;
model.parameters.get<TR>() = transition_rates;

ScalarType dt = 0.1;
ScalarType tmax = 30.0;
Expand Down
12 changes: 6 additions & 6 deletions cpp/memilio/epidemiology/adoption_rate.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2020-2025 MEmilio
*
* Authors: René Schmieding, Julia Bicker
* Authors: René Schmieding, Julia Bicker, Kilian Volmer
*
* Contact: Martin J. Kuehn <Martin.Kuehn@DLR.de>
*
Expand All @@ -20,9 +20,8 @@
#ifndef MIO_EPI_ADOPTIONRATE_H
#define MIO_EPI_ADOPTIONRATE_H

#include "memilio/utils/index.h"
#include "memilio/config.h"
#include "memilio/geography/regions.h"
#include <vector>

namespace mio
{
Expand All @@ -44,14 +43,15 @@ struct Influence {
* In the d_abm and smm simulations, "from" is implicitly an influence, scaled by "factor". This is multiplied by
* the sum over all "influences", which scale their "status" with the respective "factor".
* @tparam Status An infection state enum.
* @tparam Region An (multi)-index.
*/
template <typename FP, class Status>
template <typename FP, class Status, class Region = mio::regions::Region>
struct AdoptionRate {
Status from; // i
Status to; // j
mio::regions::Region region; // k
Region region; // k
FP factor; // gammahat_{ij}^k
std::vector<Influence<FP, Status>> influences; // influences[tau] = ( Psi_{i,j,tau} , gamma_{i,j,tau} )
std::vector<Influence<FP, Status>> influences; // influences[tau] = ( Psi_{i,j,tau} , gamma_{i,j,tau} )};
};

} // namespace mio
Expand Down
13 changes: 13 additions & 0 deletions cpp/memilio/epidemiology/populations.h
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,19 @@ class Populations : public CustomIndexArray<UncertainValue<FP>, Categories...>
}
};

/**
* @brief Population template specialization for Index types.
*
* @tparam FP Floating point type
* @tparam Categories Index categories
*/

template <typename FP, class... Categories>
class Populations<FP, Index<Categories...>> : public Populations<FP, Categories...>
{
using Populations<FP, Categories...>::Populations;
};

} // namespace mio

#endif // MIO_EPI_POPULATIONS_H
Loading