Skip to content

Commit bb4b177

Browse files
committed
Changes according to review
1 parent ee57ed7 commit bb4b177

File tree

6 files changed

+69
-70
lines changed

6 files changed

+69
-70
lines changed

cpp/models/abm/model.cpp

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ PersonId Model::add_person(Person&& person)
7272
if (m_is_local_population_cache_valid) {
7373
++m_local_population_cache[new_person.get_location().get()];
7474
for (CellIndex cell : new_person.get_cells()) {
75-
auto& local_population_per_age = m_local_population_per_age_cache[new_person.get_location().get()];
76-
++local_population_per_age[{cell, new_person.get_age()}];
75+
auto& local_population_by_age = m_local_population_by_age_cache[new_person.get_location().get()];
76+
++local_population_by_age[{cell, new_person.get_age()}];
7777
}
7878
}
7979
return new_person.get_id();
@@ -224,17 +224,17 @@ void Model::build_compute_local_population_cache() const
224224
const size_t num_locations = m_locations.size();
225225
const size_t num_persons = m_persons.size();
226226
m_local_population_cache.resize(num_locations);
227-
m_local_population_per_age_cache.resize(num_locations);
227+
m_local_population_by_age_cache.resize(num_locations);
228228

229229
PRAGMA_OMP(taskloop)
230230
for (size_t i = 0; i < num_locations; i++) {
231231
m_local_population_cache[i] = 0;
232-
m_local_population_per_age_cache[i].resize(
232+
m_local_population_by_age_cache[i].resize(
233233
{CellIndex(m_locations[i].get_cells().size()), AgeGroup(parameters.get_num_groups())});
234234
for (CellIndex cell = 0; cell < CellIndex(m_locations[i].get_cells().size()); ++cell) {
235235
for (AgeGroup group = AgeGroup(0); group < AgeGroup(parameters.get_num_groups()); ++group) {
236-
auto& local_population_per_age = m_local_population_per_age_cache[i];
237-
local_population_per_age[{cell, group}] = 0;
236+
auto& local_population_by_age = m_local_population_by_age_cache[i];
237+
local_population_by_age[{cell, group}] = 0;
238238
}
239239
}
240240
} // implicit taskloop barrier
@@ -244,9 +244,8 @@ void Model::build_compute_local_population_cache() const
244244
assert(m_persons[i].get_location_model_id() == m_id && "Person is not in this model but still active.");
245245
++m_local_population_cache[m_persons[i].get_location().get()];
246246
for (CellIndex cell : m_persons[i].get_cells()) {
247-
auto& local_population_per_age =
248-
m_local_population_per_age_cache[m_persons[i].get_location().get()];
249-
++local_population_per_age[{cell, m_persons[i].get_age()}];
247+
auto& local_population_by_age = m_local_population_by_age_cache[m_persons[i].get_location().get()];
248+
++local_population_by_age[{cell, m_persons[i].get_age()}];
250249
}
251250
}
252251
} // implicit taskloop barrier
@@ -315,11 +314,16 @@ void Model::compute_exposure_caches(TimePoint t, TimeSpan dt)
315314
} // implicit taskloop barrier
316315

317316
// 3) normalize contributions for each location
317+
318+
// make sure that the caches are computed
319+
if (!m_is_local_population_cache_valid) {
320+
build_compute_local_population_cache();
321+
m_is_local_population_cache_valid = true;
322+
}
318323
PRAGMA_OMP(taskloop)
319324
for (size_t location = 0; location < num_locations; ++location) {
320325
mio::abm::normalize_exposure_contribution(m_contact_exposure_rates_cache[location],
321-
m_local_population_per_age_cache[location],
322-
parameters.get_num_groups());
326+
m_local_population_by_age_cache[location]);
323327
} // implicit taskloop barrier
324328

325329
} // implicit single barrier

cpp/models/abm/model.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ class Model
9494
Model(const Model& other, int id = 0)
9595
: parameters(other.parameters)
9696
, m_local_population_cache()
97-
, m_local_population_per_age_cache()
97+
, m_local_population_by_age_cache()
9898
, m_air_exposure_rates_cache()
9999
, m_contact_exposure_rates_cache()
100100
, m_is_local_population_cache_valid(false)
@@ -415,8 +415,8 @@ class Model
415415
build_compute_local_population_cache();
416416
m_is_local_population_cache_valid = true;
417417
}
418-
auto& m_local_population_per_age = m_local_population_per_age_cache[location.get()];
419-
return m_local_population_per_age[{cell_idx, age}];
418+
auto& m_local_population_by_age = m_local_population_by_age_cache[location.get()];
419+
return m_local_population_by_age[{cell_idx, age}];
420420
}
421421

422422
// Change the Location of a Person. this requires that Location is part of this Model.
@@ -564,12 +564,12 @@ class Model
564564
--m_local_population_cache[origin.get()];
565565
++m_local_population_cache[destination.get()];
566566
for (CellIndex cell : old_cells) {
567-
auto& local_population_per_age = m_local_population_per_age_cache[origin.get()];
568-
--local_population_per_age[{cell, person.get_age()}];
567+
auto& local_population_by_age = m_local_population_by_age_cache[origin.get()];
568+
--local_population_by_age[{cell, person.get_age()}];
569569
}
570570
for (CellIndex cell : cells) {
571-
auto& local_population_per_age = m_local_population_per_age_cache[destination.get()];
572-
++local_population_per_age[{cell, person.get_age()}];
571+
auto& local_population_by_age = m_local_population_by_age_cache[destination.get()];
572+
++local_population_by_age[{cell, person.get_age()}];
573573
}
574574
}
575575
}
@@ -621,7 +621,7 @@ class Model
621621
auto personal_rng = PersonalRandomNumberGenerator(person);
622622
auto location = person.get_location();
623623
mio::abm::interact(personal_rng, person, get_location(location),
624-
m_local_population_per_age_cache[location.get()], m_air_exposure_rates_cache[location.get()],
624+
m_local_population_by_age_cache[location.get()], m_air_exposure_rates_cache[location.get()],
625625
m_contact_exposure_rates_cache[location.get()], t, dt, parameters);
626626
}
627627

@@ -653,8 +653,8 @@ class Model
653653

654654
mutable Eigen::Matrix<std::atomic_int_fast32_t, Eigen::Dynamic, 1>
655655
m_local_population_cache; ///< Current number of Persons in a given location.
656-
mutable Eigen::Matrix<CustomIndexArray<std::atomic_int_fast32_t, CellIndex, AgeGroup>, Eigen::Dynamic, 1>
657-
m_local_population_per_age_cache; ///<Current number of Persons per AgeGroup in a given location.
656+
mutable Eigen::Matrix<PopulationByAge, Eigen::Dynamic, 1>
657+
m_local_population_by_age_cache; ///<Current number of Persons per AgeGroup in a given location.
658658
Eigen::Matrix<AirExposureRates, Eigen::Dynamic, 1>
659659
m_air_exposure_rates_cache; ///< Cache for local exposure through droplets in #transmissions/day.
660660
Eigen::Matrix<ContactExposureRates, Eigen::Dynamic, 1>

cpp/models/abm/model_functions.cpp

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,17 @@ namespace abm
3434

3535
ScalarType daily_transmissions_by_contacts(const ContactExposureRates& rates, const CellIndex cell_index,
3636
const VirusVariant virus, const AgeGroup age_receiver,
37-
size_t num_persons_in_age_receiverer_group,
38-
const LocalInfectionParameters& params)
37+
size_t age_receiver_group_size, const LocalInfectionParameters& params)
3938
{
4039
assert(age_receiver < rates.size<AgeGroup>());
4140
ScalarType prob = 0;
4241
for (AgeGroup age_transmitter(0); age_transmitter < rates.size<AgeGroup>(); ++age_transmitter) {
4342
if (age_receiver == age_transmitter &&
44-
num_persons_in_age_receiverer_group > 1) // adjust for the person not meeting themself
43+
age_receiver_group_size > 1) // adjust for the person not meeting themself
4544
{
4645
prob += rates[{cell_index, virus, age_transmitter}] *
47-
params.get<ContactRates>()[{age_receiver, age_transmitter}] * num_persons_in_age_receiverer_group /
48-
(num_persons_in_age_receiverer_group - 1) *
49-
params.get<ContactRates>()[{age_receiver, age_transmitter}];
46+
params.get<ContactRates>()[{age_receiver, age_transmitter}] * age_receiver_group_size /
47+
(age_receiver_group_size - 1);
5048
}
5149
else {
5250
prob += rates[{cell_index, virus, age_transmitter}] *
@@ -63,9 +61,9 @@ ScalarType daily_transmissions_by_air(const AirExposureRates& rates, const CellI
6361
}
6462

6563
void interact(PersonalRandomNumberGenerator& personal_rng, Person& person, const Location& location,
66-
const CustomIndexArray<std::atomic_int_fast32_t, CellIndex, AgeGroup>& local_population_per_age,
67-
const AirExposureRates& local_air_exposure, const ContactExposureRates& local_contact_exposure,
68-
const TimePoint t, const TimeSpan dt, const Parameters& global_parameters)
64+
const PopulationByAge& local_population_by_age, const AirExposureRates& local_air_exposure,
65+
const ContactExposureRates& local_contact_exposure, const TimePoint t, const TimeSpan dt,
66+
const Parameters& global_parameters)
6967
{
7068
// make sure all dimensions are set correctly and all indices are valid
7169
assert(location.get_cells().size() == local_air_exposure.size<CellIndex>().get());
@@ -87,11 +85,11 @@ void interact(PersonalRandomNumberGenerator& personal_rng, Person& person, const
8785
for (CellIndex cell_index : person.get_cells()) {
8886
std::pair<VirusVariant, ScalarType> local_indiv_trans_prob[static_cast<uint32_t>(VirusVariant::Count)];
8987
for (uint32_t v = 0; v != static_cast<uint32_t>(VirusVariant::Count); ++v) {
90-
VirusVariant virus = static_cast<VirusVariant>(v);
91-
size_t local_population_per_age_receiver = local_population_per_age[{cell_index, age_receiver}];
88+
VirusVariant virus = static_cast<VirusVariant>(v);
89+
size_t local_population_by_age_receiver = local_population_by_age[{cell_index, age_receiver}];
9290
ScalarType local_indiv_trans_prob_v =
9391
(daily_transmissions_by_contacts(local_contact_exposure, cell_index, virus, age_receiver,
94-
local_population_per_age_receiver, local_parameters) +
92+
local_population_by_age_receiver, local_parameters) +
9593
daily_transmissions_by_air(local_air_exposure, cell_index, virus, global_parameters)) *
9694
(1 - mask_protection) * (1 - person.get_protection_factor(t, virus, global_parameters));
9795

@@ -142,19 +140,18 @@ void add_exposure_contribution(AirExposureRates& local_air_exposure, ContactExpo
142140
}
143141
}
144142

145-
void normalize_exposure_contribution(
146-
ContactExposureRates& local_contact_exposure,
147-
const CustomIndexArray<std::atomic_int_fast32_t, CellIndex, AgeGroup>& local_population_per_age,
148-
size_t num_agegroups)
143+
void normalize_exposure_contribution(ContactExposureRates& local_contact_exposure,
144+
const PopulationByAge& local_population_by_age)
149145
{
150-
for (CellIndex cell = 0; cell < local_contact_exposure.size<CellIndex>(); ++cell) {
151-
for (auto&& virus : enum_members<VirusVariant>()) {
152-
for (auto age_group = AgeGroup(0); age_group < AgeGroup(num_agegroups); age_group++) {
153-
if (local_population_per_age[{cell, age_group}] > 0) {
154-
local_contact_exposure[{cell, virus, age_group}] =
155-
local_contact_exposure[{cell, virus, age_group}] / local_population_per_age[{cell, age_group}];
156-
}
157-
}
146+
// make sure all dimensions are set correctly and all indices are valid
147+
assert(local_population_by_age.size<AgeGroup>() == local_contact_exposure.size<AgeGroup>());
148+
assert(local_population_by_age.size<CellIndex>() == local_contact_exposure.size<CellIndex>());
149+
assert(local_contact_exposure.size<VirusVariant>() == VirusVariant::Count);
150+
151+
for (auto index : make_index_range(local_contact_exposure.size())) {
152+
auto age_index = reduce_index<Index<CellIndex, AgeGroup>>(index);
153+
if (local_population_by_age[age_index] > 0) {
154+
local_contact_exposure[index] = local_contact_exposure[index] / local_population_by_age[age_index];
158155
}
159156
}
160157
}

cpp/models/abm/model_functions.h

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,13 @@ namespace abm
3737
* @param[in] cell_index Cell index of the Cell.
3838
* @param[in] virus VirusVariant of interest.
3939
* @param[in] age_receiver AgeGroup of the receiving Person.
40-
* @param[in] num_persons_in_age_receiverer_group Number of persons in the AgeGroup of the receiving Person.
40+
* @param[in] age_receiver_group_size Number of persons in the AgeGroup of the receiving Person.
4141
* @param[in] params The local infection parameters.
4242
* @return Average amount of Infection%s with the virus from the AgeGroup of the transmitter per day.
4343
*/
4444
ScalarType daily_transmissions_by_contacts(const ContactExposureRates& rates, const CellIndex cell_index,
4545
const VirusVariant virus, const AgeGroup age_receiver,
46-
size_t num_persons_in_age_receiverer_group,
47-
const LocalInfectionParameters& params);
46+
size_t age_receiver_group_size, const LocalInfectionParameters& params);
4847

4948
/**
5049
* @brief Compute the number of daily transmissions for aerosol transmission of a virus in a cell.
@@ -71,33 +70,32 @@ void add_exposure_contribution(AirExposureRates& local_air_exposure, ContactExpo
7170
const Person& person, const Location& location, const Parameters& params,
7271
const TimePoint t, const TimeSpan dt);
7372

73+
using PopulationByAge = CustomIndexArray<std::atomic_int_fast32_t, CellIndex, AgeGroup>;
74+
7475
/**
75-
* @brief Normalize contact exposure rate by number of people in age groups
76-
* @param[in, out] local_contact_exposure Exposure by rates contacts for the local population.
77-
* @param[in] local_population_per_age Local population per AgeGroup.
78-
* @param[in] num_agegroup The number of AgeGroups in the model.
76+
* @brief Normalize contact exposure rate to average exposure per contact per time (from total exposure per time).
77+
* @param[in, out] local_contact_exposure Exposure rates through contacts for the local population.
78+
* @param[in] local_population_by_age Local population by AgeGroup%s.
7979
*/
80-
void normalize_exposure_contribution(
81-
ContactExposureRates& local_contact_exposure,
82-
const CustomIndexArray<std::atomic_int_fast32_t, CellIndex, AgeGroup>& local_population_per_age,
83-
size_t num_agegroups);
80+
void normalize_exposure_contribution(ContactExposureRates& local_contact_exposure,
81+
const PopulationByAge& local_population_by_age);
8482

8583
/**
8684
* @brief Let a Person interact with the population at its current Location, possibly getting infected.
8785
* @param[in, out] rng PersonalRandomNumberGenerator for this Person.
8886
* @param[in, out] person The person to interact with the local population.
8987
* @param[in] location The person's current location.
90-
* @param[in] local_population_per_age Local population per AgeGroup at the location.
88+
* @param[in] local_population_by_age Local population by AgeGroup%s at the given location.
9189
* @param[in] local_air_exposure Precomputed exposure rates by aerosols for the local population.
9290
* @param[in] local_contact_exposure Precomputed exposure by rates contacts for the local population.
9391
* @param[in] t Current Simulation time.
9492
* @param[in] dt Length of the current Simulation time step.
9593
* @param[in] global_parameters Parameters of the Model.
9694
*/
9795
void interact(PersonalRandomNumberGenerator& personal_rng, Person& person, const Location& location,
98-
const CustomIndexArray<std::atomic_int_fast32_t, CellIndex, AgeGroup>& local_population_per_age,
99-
const AirExposureRates& local_air_exposure, const ContactExposureRates& local_contact_exposure,
100-
const TimePoint t, const TimeSpan dt, const Parameters& global_parameters);
96+
const PopulationByAge& local_population_by_age, const AirExposureRates& local_air_exposure,
97+
const ContactExposureRates& local_contact_exposure, const TimePoint t, const TimeSpan dt,
98+
const Parameters& global_parameters);
10199
/**
102100
* @brief Change a persons location to another location.
103101
* If the person already is at the destination, neither mode nor cells are set.

cpp/tests/abm_helpers.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,19 +65,19 @@ void interact_testing(mio::abm::PersonalRandomNumberGenerator& personal_rng, mio
6565
for (const mio::abm::Person& p : local_population) {
6666
add_exposure_contribution(local_air_exposure, local_contact_exposure, p, location, global_parameters, t, dt);
6767
}
68-
// count local population per age group and cell
69-
mio::CustomIndexArray<std::atomic_int_fast32_t, mio::abm::CellIndex, mio::AgeGroup> local_population_per_age;
70-
local_population_per_age.resize(
68+
// count local population by age group and cell
69+
mio::abm::PopulationByAge local_population_by_age;
70+
local_population_by_age.resize(
7171
{mio::abm::CellIndex(location.get_cells().size()), mio::AgeGroup(global_parameters.get_num_groups())});
72-
std::for_each(local_population_per_age.begin(), local_population_per_age.end(), [](auto& r) {
72+
std::for_each(local_population_by_age.begin(), local_population_by_age.end(), [](auto& r) {
7373
r = 0; // initialize with 0
7474
});
7575
for (const mio::abm::Person& p : local_population) {
7676
for (mio::abm::CellIndex cell_index : p.get_cells()) {
77-
local_population_per_age[{cell_index, p.get_age()}]++;
77+
local_population_by_age[{cell_index, p.get_age()}]++;
7878
}
7979
}
8080
// run interaction
81-
mio::abm::interact(personal_rng, person, location, local_population_per_age, local_air_exposure,
81+
mio::abm::interact(personal_rng, person, location, local_population_by_age, local_air_exposure,
8282
local_contact_exposure, t, dt, global_parameters);
8383
}

cpp/tests/test_abm_model.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -216,12 +216,12 @@ TEST_F(TestModel, exposureContributionNormalization)
216216
contact_exposure_rates.resize({mio::abm::CellIndex{1}, mio::abm::VirusVariant{1}, mio::AgeGroup{1}});
217217
contact_exposure_rates[{mio::abm::CellIndex{0}, mio::abm::VirusVariant::Wildtype, mio::AgeGroup{0}}] = 10.0;
218218

219-
mio::CustomIndexArray<std::atomic_int_fast32_t, mio::abm::CellIndex, mio::AgeGroup> local_population_per_age;
220-
local_population_per_age.resize({mio::abm::CellIndex{1}, mio::AgeGroup{1}});
221-
local_population_per_age[{mio::abm::CellIndex{0}, mio::AgeGroup{0}}] =
219+
mio::abm::PopulationByAge local_population_by_age;
220+
local_population_by_age.resize({mio::abm::CellIndex{1}, mio::AgeGroup{1}});
221+
local_population_by_age[{mio::abm::CellIndex{0}, mio::AgeGroup{0}}] =
222222
2; // Set population for cell 0 and age group 0 to 2
223223

224-
mio::abm::normalize_exposure_contribution(contact_exposure_rates, local_population_per_age, 1);
224+
mio::abm::normalize_exposure_contribution(contact_exposure_rates, local_population_by_age);
225225

226226
auto& rate = contact_exposure_rates[{mio::abm::CellIndex{0}, mio::abm::VirusVariant::Wildtype, mio::AgeGroup{0}}];
227227
EXPECT_EQ(rate, 5.0);

0 commit comments

Comments
 (0)