Skip to content

501 Add Intervention Scheme for ABM #795

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 2 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
1 change: 1 addition & 0 deletions cpp/models/abm/abm.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,6 @@
#include "abm/age.h"
#include "abm/household.h"
#include "abm/lockdown_rules.h"
#include "abm/npi.h"

#endif
5 changes: 5 additions & 0 deletions cpp/models/abm/location.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,11 @@ void Location::cache_exposure_rates(TimePoint t, TimeSpan dt)
}
}

bool Location::may_enter(Person::RandomNumberGenerator& rng, const Person& person, TimePoint t)
{
return m_NPIs(rng, person, *this, t);
}

void Location::add_person(Person& p, std::vector<uint32_t> cells)
{
std::lock_guard<std::mutex> lk(m_mut);
Expand Down
9 changes: 8 additions & 1 deletion cpp/models/abm/location.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "abm/location_type.h"
#include "abm/infection_state.h"
#include "abm/vaccine.h"
#include "abm/npi.h"

#include "memilio/math/eigen.h"
#include "memilio/utils/custom_index_array.h"
Expand Down Expand Up @@ -168,6 +169,11 @@ class Location
void interact(Person::RandomNumberGenerator& rng, Person& person, TimePoint t, TimeSpan dt,
const GlobalInfectionParameters& global_params) const;

/**
* @brief Check if a Person is allowed to enter this Location.
*/
bool may_enter(Person::RandomNumberGenerator& rng, const Person& person, TimePoint t);

/**
* @brief Add a Person to the population at this Location.
* @param[in] person The Person arriving.
Expand Down Expand Up @@ -351,7 +357,7 @@ class Location
}

private:
std::mutex m_mut; ///< Mutex to protect the list of persons from concurrent modification.
std::mutex m_mut; ///< Mutex to protect the list of Person%s from concurrent modification.
LocationId m_id; ///< Id of the Location including type and index.
bool m_capacity_adapted_transmission_risk; /**< If true considers the LocationCapacity for the computation of the
transmission risk.*/
Expand All @@ -361,6 +367,7 @@ class Location
InfectionState::Count)}; ///< A TimeSeries of the #InfectionState%s for each TimePoint at the Location.
std::vector<Cell> m_cells{}; ///< A vector of all Cell%s that the Location is divided in.
MaskType m_required_mask; ///< Least secure type of Mask that is needed to enter the Location.
LocationNPIStrategy m_NPIs{AcceptBase{}}; ///< Set of NPIs that affect this location. Can be called.
bool m_npi_active; ///< If true requires e.g. Mask%s to enter the Location.
GeographicalLocation m_geographical_location; ///< Geographical location (longitude and latitude) of the Location.
};
Expand Down
153 changes: 153 additions & 0 deletions cpp/models/abm/npi.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
/*
* Copyright (C) 2020-2023 German Aerospace Center (DLR-SC)
*
* Authors: David Kerkman
*
* Contact: Martin J. Kuehn <Martin.Kuehn@DLR.de>
*
* 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/npi.h"
#include "abm/person.h"
#include "abm/location.h"

namespace mio
{
namespace abm
{

/**
* Base NPI, but equipped with a stringency which is often useful for all kind of NPIs.
* Alternatively, this can also be implemented in each NPI directly.
*/
struct AcceptBaseStringency : AcceptBase {
AcceptBaseStringency() = default;
AcceptBaseStringency(double strin)
: stringency(strin)
{
}
double stringency = 1.;
};

/**
* @brief NPI to require the usage of masks for entering the Location.
*/
struct MaskRequired : AcceptBaseStringency {

MaskRequired(MaskType mt)
: mask_type(mt)
{
}

MaskRequired(MaskType mt, double strin)
: AcceptBaseStringency(strin)
, mask_type(mt)
{
}

bool operator()(Person::RandomNumberGenerator& rng, const Person& p, const Location& loc, TimePoint /*t*/) override
{
return p.apply_mask_intervention(rng, loc);
}

MaskType mask_type;
};

/**
* @brief NPI to set the maximum capacity for entering for the Location. Use 0 for a complete shutdown.
*/
struct CapacityAbsolute : AcceptBaseStringency {

CapacityAbsolute(uint32_t cap)
: capacity(cap)
{
}

CapacityAbsolute(uint32_t cap, double strin)
: AcceptBaseStringency(strin)
, capacity(cap)
{
}

bool operator()(Person::RandomNumberGenerator& /*rng*/, const Person& /*p*/, const Location& loc,
TimePoint /*t*/) override
{
return loc.get_number_persons() < capacity;
}

uint32_t capacity;
};

/**
* @brief NPI to set the relative capacity change for entering the Location. Use 0 for a complete shutdown.
*/
struct CapacityRelative : AcceptBaseStringency {

CapacityRelative(double cap_fac)
: capacity_factor(cap_fac)
{
}

CapacityRelative(double cap_fac, double strin)
: AcceptBaseStringency(strin)
, capacity_factor(cap_fac)
{
}

bool operator()(Person::RandomNumberGenerator& /*rng*/, const Person& /*p*/, const Location& loc,
TimePoint /*t*/) override
{
return loc.get_number_persons() < capacity_factor * loc.get_capacity().persons;
}

double capacity_factor;
};

/**
* @brief NPI to set the required tests for entering the Location.
*/
struct TestRequired : AcceptBaseStringency {

TestRequired(TestingScheme& ts)
: testing_scheme(&ts)
{
}

TestRequired(TestingScheme& ts, double strin)
: AcceptBaseStringency(strin)
, testing_scheme(&ts)
{
}

bool operator()(Person::RandomNumberGenerator& rng, const Person& p, const Location& loc, TimePoint t) override
{
return testing_scheme->run_scheme(rng, p, loc, t);
}

TestingScheme* testing_scheme;
};

struct NPISet : AcceptBase {
LocationNPI mask{AcceptBase{}};
LocationNPI capacity{AcceptBase{}};
LocationNPI test{AcceptBase{}};

bool operator()(Person::RandomNumberGenerator& rng, const Person& p, const Location& loc, TimePoint t) override
{
return mask(rng, p, loc, t) && capacity(rng, p, loc, t) && test(rng, p, loc, t);
}
};

} // namespace abm
} // namespace mio
58 changes: 58 additions & 0 deletions cpp/models/abm/npi.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright (C) 2020-2023 German Aerospace Center (DLR-SC)
* & Helmholtz Centre for Infection Research (HZI)
*
* Authors: David Kerkmann
*
* Contact: Martin J. Kuehn <Martin.Kuehn@DLR.de>
*
* 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.
*/
#ifndef EPI_ABM_NPI_H
#define EPI_ABM_NPI_H

#include <functional>
#include "abm/mask_type.h"
#include "abm/time.h"
#include "abm/testing_strategy.h"
#include "memilio/utils/random_number_generator.h"

namespace mio
{
namespace abm
{

/**
* TODO: Template everything with variable arguments.
* TODO: Probably remove std::function for better efficiency and access to final NPI data members.
*/
class Location;
class Person;
using LocationNPIStrategy =
std::function<bool(Person::RandomNumberGenerator&, const Person&, const Location&, TimePoint)>;

/**
* @brief Base NPI to always allow entrance.
*/
struct AcceptBase {
virtual ~AcceptBase() = default;
virtual bool operator()(Person::RandomNumberGenerator&, const Person&, const Location&, TimePoint)
{
return true;
}
};

} // namespace abm
} // namespace mio

#endif //EPI_ABM_NPI_H