Skip to content
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

646 use graph model with ABMs v3 #1085

Open
wants to merge 107 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
107 commits
Select commit Hold shift + click to select a range
f272d9c
add ABM simulation node and edge
jubicker Jun 7, 2024
1f29e1c
graph abm implementation
jubicker Jul 11, 2024
5e91137
remove warning surpression for boost
jubicker Jul 11, 2024
22a2a60
merge main
jubicker Jul 11, 2024
4368cb5
add CMakeList
jubicker Jul 12, 2024
81df1a8
CMake List Bug fix
jubicker Jul 12, 2024
5b2c64a
fix include
jubicker Jul 12, 2024
414c3f4
bug fix
jubicker Jul 12, 2024
4e2a733
test
jubicker Jul 15, 2024
8f1d7cb
test apply_mobility
jubicker Jul 15, 2024
7400802
extend apply_mobility test
jubicker Jul 16, 2024
b314715
error in abm_minimal example
jubicker Jul 16, 2024
dbbd068
test for apply mobility
jubicker Jul 17, 2024
196275f
finx clang bug
jubicker Jul 18, 2024
a5a4e88
abm minimal bug fix
jubicker Jul 18, 2024
3367fa6
Merge branch '646-use-graph-model-with-abms-v2' of https://github.com…
jubicker Jul 18, 2024
8cce390
graph_abm example
jubicker Jul 18, 2024
2fc9026
graph abm example
jubicker Jul 19, 2024
ef4c0b1
merge main
jubicker Jul 22, 2024
0ece6be
fix merge conflicts
jubicker Jul 23, 2024
b773193
fix test
jubicker Jul 23, 2024
b4d44d5
graph abm example
jubicker Jul 25, 2024
ae95301
remove unnecessary comment
jubicker Jul 25, 2024
5ebd62f
Merge branch '646-use-graph-model-with-abms-v2' of https://github.com…
jubicker Jul 25, 2024
e22009b
fix bug
jubicker Jul 25, 2024
11c3ae8
delete dbugging comments
jubicker Jul 26, 2024
1f85548
Merge branch '646-use-graph-model-with-abms-v2' of https://github.com…
jubicker Jul 26, 2024
fdad4da
benchmark inactive persons
jubicker Jul 31, 2024
509854c
merge main
jubicker Aug 1, 2024
b5b9338
fix merge conflicts
jubicker Aug 1, 2024
5ef826d
[ci skip] model wrapper
jubicker Aug 5, 2024
8ec2fcf
add tests
jubicker Aug 7, 2024
07b268a
msvc is a diva
jubicker Aug 7, 2024
8623ad3
add location model id to constructor
jubicker Aug 7, 2024
d4e3765
review comments
jubicker Aug 7, 2024
7f59e08
Merge branch '646-use-graph-model-with-abms-v3' of https://github.com…
jubicker Aug 7, 2024
a34989e
bug fix
jubicker Aug 7, 2024
9d76ae6
add example
jubicker Aug 7, 2024
267aa52
merge main
jubicker Aug 7, 2024
56c9708
fix bindings
jubicker Aug 7, 2024
251012c
python bindings
jubicker Aug 7, 2024
b9a777d
fix python test
jubicker Aug 8, 2024
8478a94
fix python test
jubicker Aug 8, 2024
41f7f21
adjust benchmark
jubicker Aug 8, 2024
c29f670
extend tests
jubicker Aug 8, 2024
62a790e
Merge branch '646-use-graph-model-with-abms-v3' of https://github.com…
jubicker Aug 8, 2024
af1e7f6
test ci
jubicker Aug 8, 2024
983ca21
ci test
jubicker Aug 9, 2024
59c4450
ci test
jubicker Aug 9, 2024
a8e84a4
ci test
jubicker Aug 9, 2024
9e568d7
test ci
jubicker Aug 9, 2024
53d19a1
ci
jubicker Aug 9, 2024
f8897e4
test ci
jubicker Aug 9, 2024
e4a75fd
ci test
jubicker Aug 9, 2024
cadfecd
CI comment out node.evolve
jubicker Aug 9, 2024
99c1d4c
CI comment in node.evolve
jubicker Aug 9, 2024
6b8d9b0
log in test
jubicker Aug 9, 2024
336998a
test
jubicker Aug 9, 2024
b5a6a0b
test
jubicker Aug 9, 2024
7484ce9
more tests
jubicker Aug 9, 2024
53c45e2
more logs
jubicker Aug 9, 2024
de0cae6
bug fix
jubicker Aug 12, 2024
4daeac6
another bug fix
jubicker Aug 12, 2024
ef0bff3
logs
jubicker Aug 12, 2024
afdbc6d
more logs
jubicker Aug 12, 2024
39d3b48
test log
jubicker Aug 12, 2024
f0aafd4
rename world.get_location
jubicker Aug 12, 2024
de4fd46
more logs
jubicker Aug 12, 2024
c5bc31b
log fix
jubicker Aug 12, 2024
0632c13
log
jubicker Aug 12, 2024
db910b7
Mock exponential dist in test
jubicker Aug 12, 2024
31935e4
don't use trip and mobility rules
jubicker Aug 12, 2024
72200ee
make mobility rules input
jubicker Aug 13, 2024
c285c38
remove logs
jubicker Aug 13, 2024
b659311
rework add_person such that person id can be kept
jubicker Nov 21, 2024
50bcd3b
merge main
jubicker Nov 21, 2024
bece66b
bug fix after merge
jubicker Nov 21, 2024
8237f36
finx abm python bindings
jubicker Nov 21, 2024
a6e9c82
python test abm
jubicker Nov 21, 2024
cb977f1
python bindings template abm simulation
jubicker Nov 21, 2024
b2023af
abm python bindings
jubicker Nov 22, 2024
58d4bb1
merge main
jubicker Dec 3, 2024
1e69b4d
Debug logs
jubicker Dec 6, 2024
0a822ef
Merge branch '646-use-graph-model-with-abms-v3' of https://github.com…
jubicker Dec 6, 2024
1eabac2
Update cpp/examples/graph_abm.cpp
jubicker Jan 8, 2025
944736f
Apply suggestions from code review
jubicker Jan 8, 2025
ecdd68a
merge main
jubicker Jan 8, 2025
26fe99f
add unique person id
jubicker Jan 10, 2025
66896aa
review comment
jubicker Jan 10, 2025
8a97b5c
fix CI
jubicker Jan 10, 2025
a106505
bug fix
jubicker Jan 13, 2025
34ebe3b
remove const from id getter
jubicker Jan 13, 2025
f21f37f
sort m_persons vector before moving persons between nodes
jubicker Jan 14, 2025
6a76553
unique id
jubicker Jan 14, 2025
e0f3be1
extend tests
jubicker Jan 14, 2025
788724a
fix test
jubicker Jan 14, 2025
a807dd0
[CI Skip] test
jubicker Jan 14, 2025
7a4d6d6
[ci skip]
jubicker Jan 14, 2025
17ff528
test
jubicker Jan 14, 2025
c3c92c5
test
jubicker Jan 14, 2025
c7e60a8
ci
jubicker Jan 14, 2025
f221fb3
ci
jubicker Jan 14, 2025
bfb7b72
fix CI
jubicker Jan 14, 2025
ad4a5fd
Rename model_wrapper to graph_abmodel
jubicker Jan 15, 2025
dd58d68
rename evolve to advance in graph
jubicker Jan 15, 2025
3eaa51a
introduce local index and global id
jubicker Jan 15, 2025
830aff3
add tests
jubicker Jan 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
1 change: 1 addition & 0 deletions cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ if(MEMILIO_BUILD_MODELS)
add_subdirectory(models/sde_sir)
add_subdirectory(models/sde_sirs)
add_subdirectory(models/sde_seirvv)
add_subdirectory(models/graph_abm)
endif()

if(MEMILIO_BUILD_EXAMPLES)
Expand Down
8 changes: 4 additions & 4 deletions cpp/benchmarks/abm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

#include "benchmark/benchmark.h"

mio::abm::Simulation make_simulation(size_t num_persons, std::initializer_list<uint32_t> seeds)
mio::abm::Simulation<> make_simulation(size_t num_persons, std::initializer_list<uint32_t> seeds)
{
auto rng = mio::RandomNumberGenerator();
rng.seed(seeds);
Expand All @@ -26,7 +26,7 @@ mio::abm::Simulation make_simulation(size_t num_persons, std::initializer_list<u
auto age = mio::AgeGroup(mio::UniformIntDistribution<size_t>::get_instance()(
model.get_rng(), size_t(0), model.parameters.get_num_groups() - 1));
auto person = model.add_person(home, age);
model.assign_location(person, home);
model.assign_location(uint32_t(i), home);
home_size++;
}

Expand All @@ -40,10 +40,10 @@ mio::abm::Simulation make_simulation(size_t num_persons, std::initializer_list<u
std::generate(locs.begin(), locs.end(), [&] {
return model.add_location(loc_type);
});
for (auto& person : model.get_persons()) {
for (size_t p = 0; p < num_persons; ++p) {
auto loc_idx =
mio::UniformIntDistribution<size_t>::get_instance()(model.get_rng(), size_t(0), num_locs - 1);
model.assign_location(person.get_id(), locs[loc_idx]);
model.assign_location(uint32_t(p), locs[loc_idx]);
}
}

Expand Down
10 changes: 7 additions & 3 deletions cpp/examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,10 @@ add_executable(history_example history.cpp)
target_link_libraries(history_example PRIVATE memilio)
target_compile_options(history_example PRIVATE ${MEMILIO_CXX_FLAGS_ENABLE_WARNING_ERRORS})

add_executable(graph_abm_example graph_abm.cpp)
target_link_libraries(graph_abm_example PRIVATE memilio graph_abm abm)
target_compile_options(graph_abm_example PRIVATE ${MEMILIO_CXX_FLAGS_ENABLE_WARNING_ERRORS})

if(MEMILIO_HAS_JSONCPP)
add_executable(ode_secir_read_graph_example ode_secir_read_graph.cpp)
target_link_libraries(ode_secir_read_graph_example PRIVATE memilio ode_secir)
Expand Down Expand Up @@ -164,7 +168,7 @@ if(MEMILIO_HAS_HDF5)
endif()

if(MEMILIO_HAS_JSONCPP)
add_executable(ide_initialization_example ide_initialization.cpp)
target_link_libraries(ide_initialization_example PRIVATE memilio ide_secir)
target_compile_options(ide_initialization_example PRIVATE ${MEMILIO_CXX_FLAGS_ENABLE_WARNING_ERRORS})
add_executable(ide_initialization_example ide_initialization.cpp)
target_link_libraries(ide_initialization_example PRIVATE memilio ide_secir)
target_compile_options(ide_initialization_example PRIVATE ${MEMILIO_CXX_FLAGS_ENABLE_WARNING_ERRORS})
endif()
6 changes: 3 additions & 3 deletions cpp/examples/abm_history_object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ int main()

// Assign locations to the people
for (auto& person : model.get_persons()) {
const auto pid = person.get_id();
const auto pid = person.get_index();
//assign shop and event
model.assign_location(pid, event);
model.assign_location(pid, shop);
Expand All @@ -176,14 +176,14 @@ int main()

struct LogTimePoint : mio::LogAlways {
using Type = double;
static Type log(const mio::abm::Simulation& sim)
static Type log(const mio::abm::Simulation<>& sim)
{
return sim.get_time().hours();
}
};
struct LogLocationIds : mio::LogOnce {
using Type = std::vector<std::tuple<mio::abm::LocationType, uint32_t>>;
static Type log(const mio::abm::Simulation& sim)
static Type log(const mio::abm::Simulation<>& sim)
{
Type location_ids{};
for (auto& location : sim.get_model().get_locations()) {
Expand Down
6 changes: 3 additions & 3 deletions cpp/examples/abm_minimal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ int main()
// For more than 1 family households we need families. These are parents and children and randoms (which are distributed like the data we have for these households).
auto child = mio::abm::HouseholdMember(num_age_groups); // A child is 50/50% 0-4 or 5-14.
child.set_age_weight(age_group_0_to_4, 1);
child.set_age_weight(age_group_0_to_4, 1);
child.set_age_weight(age_group_5_to_14, 1);

auto parent = mio::abm::HouseholdMember(num_age_groups); // A parent is 50/50% 15-34 or 35-59.
parent.set_age_weight(age_group_15_to_34, 1);
Expand Down Expand Up @@ -130,15 +130,15 @@ int main()

// Assign locations to the people
for (auto& person : model.get_persons()) {
const auto id = person.get_id();
const auto id = person.get_index();
//assign shop and event
model.assign_location(id, event);
model.assign_location(id, shop);
//assign hospital and ICU
model.assign_location(id, hospital);
model.assign_location(id, icu);
//assign work/school to people depending on their age
if (person.get_age() == age_group_0_to_4) {
if (person.get_age() == age_group_5_to_14) {
model.assign_location(id, school);
}
if (person.get_age() == age_group_15_to_34 || person.get_age() == age_group_35_to_59) {
Expand Down
268 changes: 268 additions & 0 deletions cpp/examples/graph_abm.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,268 @@
/*
* Copyright (C) 2020-2024 MEmilio
*
* Authors: Julia Bicker
*
* Contact: Martin J. Kuehn <[email protected]>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "abm/household.h"
#include "abm/model.h"
#include "abm/infection_state.h"
#include "abm/location_type.h"
#include "abm/time.h"
#include "abm/person_id.h"
#include "graph_abm/graph_abm_mobility.h"
#include "graph_abm/graph_abmodel.h"
#include "memilio/io/history.h"
#include "memilio/mobility/graph.h"
#include <cstddef>
#include <cstdint>
#include <map>
#include <tuple>
#include <utility>
#include <vector>

//Logger
struct Logger : mio::LogAlways {
/**
* A vector of tuples with the Location information i.e. each tuple contains the following information:
* - The LocationId (including the model id)
* - The total number of Persons at the location
* - A map containing the number of Persons per InfectionState at the location
*/
using Type = std::vector<std::tuple<int, mio::abm::LocationType, mio::abm::LocationId, size_t,
std::map<mio::abm::InfectionState, size_t>>>;
static Type log(const mio::abm::Simulation<mio::GraphABModel>& sim)
{
Type location_information{};
location_information.reserve(size_t(mio::abm::LocationType::Count));
auto t = sim.get_time();
for (auto&& loc : sim.get_model().get_locations()) {
std::map<mio::abm::InfectionState, size_t> persons_per_infection_state;
for (size_t i = 0; i < static_cast<size_t>(mio::abm::InfectionState::Count); ++i) {
auto inf_state = mio::abm::InfectionState(i);
persons_per_infection_state.insert(
{inf_state, sim.get_model().get_subpopulation(loc.get_id(), t, inf_state)});
}
location_information.push_back(std::make_tuple(loc.get_model_id(), loc.get_type(), loc.get_id(),
sim.get_model().get_number_persons(loc.get_id()),
persons_per_infection_state));
}
return location_information;
}
};

int main()
{
// This is an example with three age groups representing children, adults and seniors.
size_t num_age_groups = 3;
const auto age_group_children = mio::AgeGroup(0);
const auto age_group_adults = mio::AgeGroup(1);
const auto age_group_seniors = mio::AgeGroup(2);

auto model1 = mio::GraphABModel(num_age_groups, 0);

//Set infection parameters
model1.parameters.get<mio::abm::IncubationPeriod>() = 4.;
model1.parameters.get<mio::abm::InfectedNoSymptomsToSymptoms>() = 2.;
model1.parameters.get<mio::abm::InfectedNoSymptomsToRecovered>() = 4.;
model1.parameters.get<mio::abm::InfectedSymptomsToRecovered>() = 5.;
model1.parameters.get<mio::abm::InfectedSymptomsToSevere>() = 6.;
model1.parameters.get<mio::abm::SevereToRecovered>() = 8.;
model1.parameters.get<mio::abm::SevereToCritical>() = 7.;
model1.parameters.get<mio::abm::CriticalToRecovered>() = 10.;
model1.parameters.get<mio::abm::CriticalToDead>() = 11.;

//Age group 0 goes to school and age group 1 goes to work
model1.parameters.get<mio::abm::AgeGroupGotoSchool>()[age_group_children] = true;
model1.parameters.get<mio::abm::AgeGroupGotoWork>()[age_group_adults] = true;

//Household members can be child, parent or senior
auto child = mio::abm::HouseholdMember(num_age_groups);
child.set_age_weight(age_group_children, 1);
auto parent = mio::abm::HouseholdMember(num_age_groups);
parent.set_age_weight(age_group_adults, 1);
auto adult = mio::abm::HouseholdMember(num_age_groups);
adult.set_age_weight(age_group_adults, 1);
adult.set_age_weight(age_group_seniors, 1);

//Single-Person households
auto single_hh = mio::abm::Household();
single_hh.add_members(adult, 1);

//Two-Adult household
auto two_adult_hh = mio::abm::Household();
two_adult_hh.add_members(adult, 2);

//Single-Parent household
auto single_parent_hh = mio::abm::Household();
single_parent_hh.add_members(child, 1);
single_parent_hh.add_members(parent, 1);

//Family household
auto family_hh = mio::abm::Household();
family_hh.add_members(child, 1);
family_hh.add_members(parent, 2);

//Household groups for model 1
auto single_hh_group_m1 = mio::abm::HouseholdGroup();
single_hh_group_m1.add_households(single_hh, 5);
auto two_adult_hh_group_m1 = mio::abm::HouseholdGroup();
two_adult_hh_group_m1.add_households(two_adult_hh, 3);
auto single_parent_hh_group_m1 = mio::abm::HouseholdGroup();
single_parent_hh_group_m1.add_households(single_parent_hh, 5);
auto family_hh_group_m1 = mio::abm::HouseholdGroup();
family_hh_group_m1.add_households(family_hh, 10);
add_household_group_to_model(model1, single_hh_group_m1);
add_household_group_to_model(model1, two_adult_hh_group_m1);
add_household_group_to_model(model1, single_hh_group_m1);
add_household_group_to_model(model1, family_hh_group_m1);

auto model2 = mio::GraphABModel(num_age_groups, 1);

//Set infection parameters
model2.parameters.get<mio::abm::IncubationPeriod>() = 4.;
model2.parameters.get<mio::abm::InfectedNoSymptomsToSymptoms>() = 2.;
model2.parameters.get<mio::abm::InfectedNoSymptomsToRecovered>() = 4.;
model2.parameters.get<mio::abm::InfectedSymptomsToRecovered>() = 5.;
model2.parameters.get<mio::abm::InfectedSymptomsToSevere>() = 6.;
model2.parameters.get<mio::abm::SevereToRecovered>() = 8.;
model2.parameters.get<mio::abm::SevereToCritical>() = 7.;
model2.parameters.get<mio::abm::CriticalToRecovered>() = 10.;
model2.parameters.get<mio::abm::CriticalToDead>() = 11.;

//Age group 0 goes to school and age group 1 goes to work
model2.parameters.get<mio::abm::AgeGroupGotoSchool>()[age_group_children] = true;
model2.parameters.get<mio::abm::AgeGroupGotoWork>()[age_group_adults] = true;

//Household groups for model 2
auto single_hh_group_m2 = mio::abm::HouseholdGroup();
single_hh_group_m2.add_households(single_hh, 6);
auto two_adult_hh_group_m2 = mio::abm::HouseholdGroup();
two_adult_hh_group_m2.add_households(two_adult_hh, 2);
auto single_parent_hh_group_m2 = mio::abm::HouseholdGroup();
single_parent_hh_group_m2.add_households(single_parent_hh, 10);
auto family_hh_group_m2 = mio::abm::HouseholdGroup();
family_hh_group_m2.add_households(family_hh, 11);
add_household_group_to_model(model2, single_hh_group_m2);
add_household_group_to_model(model2, two_adult_hh_group_m2);
add_household_group_to_model(model2, single_hh_group_m2);
add_household_group_to_model(model2, family_hh_group_m2);

//Create locations for both models
//model 1
auto event_m1 = model1.add_location(mio::abm::LocationType::SocialEvent);
model1.get_location(event_m1).get_infection_parameters().set<mio::abm::MaximumContacts>(10);
auto hospital_m1 = model1.add_location(mio::abm::LocationType::Hospital);
model1.get_location(hospital_m1).get_infection_parameters().set<mio::abm::MaximumContacts>(10);
auto icu_m1 = model1.add_location(mio::abm::LocationType::ICU);
model1.get_location(icu_m1).get_infection_parameters().set<mio::abm::MaximumContacts>(5);
auto shop_m1 = model1.add_location(mio::abm::LocationType::BasicsShop);
model1.get_location(shop_m1).get_infection_parameters().set<mio::abm::MaximumContacts>(20);
auto school_m1 = model1.add_location(mio::abm::LocationType::School);
model1.get_location(school_m1).get_infection_parameters().set<mio::abm::MaximumContacts>(20);
auto work_m1 = model1.add_location(mio::abm::LocationType::Work);
model1.get_location(work_m1).get_infection_parameters().set<mio::abm::MaximumContacts>(10);
//model 2
auto event_m2 = model2.add_location(mio::abm::LocationType::SocialEvent);
model2.get_location(event_m2).get_infection_parameters().set<mio::abm::MaximumContacts>(10);
auto hospital_m2 = model2.add_location(mio::abm::LocationType::Hospital);
model2.get_location(hospital_m2).get_infection_parameters().set<mio::abm::MaximumContacts>(10);
auto icu_m2 = model2.add_location(mio::abm::LocationType::ICU);
model2.get_location(icu_m2).get_infection_parameters().set<mio::abm::MaximumContacts>(5);
auto shop_m2 = model2.add_location(mio::abm::LocationType::BasicsShop);
model2.get_location(shop_m2).get_infection_parameters().set<mio::abm::MaximumContacts>(20);
auto school_m2 = model2.add_location(mio::abm::LocationType::School);
model2.get_location(school_m2).get_infection_parameters().set<mio::abm::MaximumContacts>(20);
auto work_m2 = model2.add_location(mio::abm::LocationType::Work);
model2.get_location(work_m2).get_infection_parameters().set<mio::abm::MaximumContacts>(10);

auto start_date = mio::abm::TimePoint(0);
auto end_date = mio::abm::TimePoint(0) + mio::abm::days(30);

//Assign infection states and locations to persons from model 1
std::vector<double> infection_distribution_m1{0.5, 0.3, 0.05, 0.05, 0.05, 0.05, 0.0, 0.0};
for (auto& person : model1.get_persons()) {
mio::abm::InfectionState infection_state = mio::abm::InfectionState(
mio::DiscreteDistribution<size_t>::get_instance()(model1.get_rng(), infection_distribution_m1));
auto rng = mio::abm::PersonalRandomNumberGenerator(model1.get_rng(), person);
if (infection_state != mio::abm::InfectionState::Susceptible) {
person.add_new_infection(mio::abm::Infection(rng, mio::abm::VirusVariant::Wildtype, person.get_age(),
model1.parameters, start_date, infection_state));
}
person.set_assigned_location(mio::abm::LocationType::SocialEvent, event_m1, model1.get_id());
person.set_assigned_location(mio::abm::LocationType::BasicsShop, shop_m1, model1.get_id());
person.set_assigned_location(mio::abm::LocationType::Hospital, hospital_m1, model1.get_id());
person.set_assigned_location(mio::abm::LocationType::ICU, icu_m1, model1.get_id());
if (person.get_age() == age_group_children) {
person.set_assigned_location(mio::abm::LocationType::School, school_m1, model1.get_id());
}
if (person.get_age() == age_group_adults) {
//10% of adults in model 1 work in model 2
size_t work_model = mio::DiscreteDistribution<size_t>::get_instance()(mio::thread_local_rng(),
std::vector<double>{0.9, 0.1});
if (work_model == 1) { //person works in other model
person.set_assigned_location(mio::abm::LocationType::Work, work_m2, model2.get_id());
}
else { //person works in same model
person.set_assigned_location(mio::abm::LocationType::Work, work_m1, model1.get_id());
}
}
}

//Assign infection states and locations to persons from model 2
std::vector<double> infection_distribution_m2{0.7, 0.1, 0.05, 0.05, 0.1, 0.0, 0.0, 0.0};
for (auto& person : model2.get_persons()) {
mio::abm::InfectionState infection_state = mio::abm::InfectionState(
mio::DiscreteDistribution<size_t>::get_instance()(model2.get_rng(), infection_distribution_m2));
auto rng = mio::abm::PersonalRandomNumberGenerator(model2.get_rng(), person);
if (infection_state != mio::abm::InfectionState::Susceptible) {
person.add_new_infection(mio::abm::Infection(rng, mio::abm::VirusVariant::Wildtype, person.get_age(),
model2.parameters, start_date, infection_state));
}
person.set_assigned_location(mio::abm::LocationType::SocialEvent, event_m2, model2.get_id());
person.set_assigned_location(mio::abm::LocationType::BasicsShop, shop_m2, model2.get_id());
person.set_assigned_location(mio::abm::LocationType::Hospital, hospital_m2, model2.get_id());
person.set_assigned_location(mio::abm::LocationType::ICU, icu_m2, model2.get_id());
if (person.get_age() == age_group_children) {
person.set_assigned_location(mio::abm::LocationType::School, school_m2, model2.get_id());
}
if (person.get_age() == age_group_adults) {
//20% of adults in model 2 work in model 1
size_t work_model = mio::DiscreteDistribution<size_t>::get_instance()(mio::thread_local_rng(),
std::vector<double>{0.2, 0.8});
if (work_model == 1) { //person works in same model
person.set_assigned_location(mio::abm::LocationType::Work, work_m2, model2.get_id());
}
else { //person works in other model
person.set_assigned_location(mio::abm::LocationType::Work, work_m1, model1.get_id());
}
}
}

using HistoryType = mio::History<mio::DataWriterToMemory, Logger>;
mio::Graph<mio::ABMSimulationNode<HistoryType>, mio::ABMMobilityEdge<HistoryType>> graph;
graph.add_node(model1.get_id(), HistoryType{}, start_date, std::move(model1));
graph.add_node(model2.get_id(), HistoryType{}, start_date, std::move(model2));
graph.add_edge(model1.get_id(), model2.get_id());
graph.add_edge(model2.get_id(), model1.get_id());

auto exchange_time_span = mio::abm::hours(12);
auto sim = mio::make_abm_graph_sim<HistoryType>(start_date, exchange_time_span, std::move(graph));
sim.advance(end_date);

return 0;
}
Loading