diff --git a/cpp/models/abm/mobility_data.h b/cpp/models/abm/mobility_data.h index 83272cd732..2be1cf4843 100644 --- a/cpp/models/abm/mobility_data.h +++ b/cpp/models/abm/mobility_data.h @@ -33,13 +33,13 @@ namespace abm */ enum class TransportMode : uint32_t { + Unknown = 0, Bike, CarDriver, CarPassenger, PublicTransport, Walking, Other, - Unknown, Count //last!! }; diff --git a/cpp/models/abm/model.cpp b/cpp/models/abm/model.cpp index 2b19d8af1a..1cbf56a4c5 100755 --- a/cpp/models/abm/model.cpp +++ b/cpp/models/abm/model.cpp @@ -171,13 +171,12 @@ void Model::perform_mobility(TimePoint t, TimeSpan dt) } // check if a person makes a trip - bool weekend = t.is_weekend(); - size_t num_trips = m_trip_list.num_trips(weekend); + size_t num_trips = m_trip_list.num_trips(); for (; m_trip_list.get_current_index() < num_trips && - m_trip_list.get_next_trip_time(weekend).seconds() < (t + dt).time_since_midnight().seconds(); + m_trip_list.get_next_trip_time().seconds() < (t + dt).time_since_midnight().seconds(); m_trip_list.increase_index()) { - auto& trip = m_trip_list.get_next_trip(weekend); + auto& trip = m_trip_list.get_next_trip(); auto& person = get_person(trip.person_id); auto personal_rng = PersonalRandomNumberGenerator(person); // skip the trip if the person is in quarantine or is dead diff --git a/cpp/models/abm/trip_list.cpp b/cpp/models/abm/trip_list.cpp index 73dcc7d111..278a623f30 100644 --- a/cpp/models/abm/trip_list.cpp +++ b/cpp/models/abm/trip_list.cpp @@ -26,43 +26,34 @@ namespace mio namespace abm { -TripList::TripList() - : m_trips_weekday({}) - , m_trips_weekend({}) - , m_current_index(0) +const Trip& TripList::get_next_trip() const { + return m_trips[m_current_index]; } -const Trip& TripList::get_next_trip(bool weekend) const +TimePoint TripList::get_next_trip_time() const { - return weekend ? m_trips_weekend[m_current_index] : m_trips_weekday[m_current_index]; + return m_trips[m_current_index].trip_time; } -TimePoint TripList::get_next_trip_time(bool weekend) const -{ - return weekend ? m_trips_weekend[m_current_index].time : m_trips_weekday[m_current_index].time; -} - -void TripList::use_weekday_trips_on_weekend() -{ - m_trips_weekend = m_trips_weekday; -} - -void TripList::add_trip(Trip trip, bool weekend) +void TripList::add_trips(std::vector trip) { //Trips are sorted by time. //Also include the person id in the comparison so different persons can make trips at the same time. //The same person can only make one trip at the same time. - if (!weekend) { - insert_sorted_replace(m_trips_weekday, trip, [](auto& trip1, auto& trip2) { - return std::tie(trip1.time, trip1.person_id) < std::tie(trip2.time, trip2.person_id); - }); - } - else { - insert_sorted_replace(m_trips_weekend, trip, [](auto& trip1, auto& trip2) { - return std::tie(trip1.time, trip1.person_id) < std::tie(trip2.time, trip2.person_id); - }); - } + + // Sort the incoming trips first + std::sort(trip.begin(), trip.end(), [](auto& trip1, auto& trip2) { + return std::tie(trip1.trip_time, trip1.person_id) < std::tie(trip2.trip_time, trip2.person_id); + }); + + std::vector merged_trips; + merged_trips.reserve(m_trips.size() + trip.size()); + std::merge(m_trips.begin(), m_trips.end(), trip.begin(), trip.end(), std::back_inserter(merged_trips), + [](auto& trip1, auto& trip2) { + return std::tie(trip1.trip_time, trip1.person_id) < std::tie(trip2.trip_time, trip2.person_id); + }); + m_trips = std::move(merged_trips); } } // namespace abm diff --git a/cpp/models/abm/trip_list.h b/cpp/models/abm/trip_list.h index a95eafeb1d..9c239957ec 100644 --- a/cpp/models/abm/trip_list.h +++ b/cpp/models/abm/trip_list.h @@ -40,67 +40,35 @@ namespace abm * @brief A trip describes a change of Location from one Location to another Location. */ struct Trip { - //TODO: Origin is currently not used for the trips. Should we delete it then? PersonId person_id; /**< Person that makes the trip and corresponds to the index into the structure m_persons from Model, where all Person%s are saved.*/ - TimePoint time; ///< Daytime at which a Person changes the Location. + TimePoint trip_time; ///< Daytime at which a Person changes the Location. LocationId destination; ///< Location where the Person changes to. int destination_model_id; ///< Model id of destination Location. - LocationId origin; ///< Location where the Person starts the Trip. - int origin_model_id; ///< Model id of origin Location. + TransportMode trip_mode; ///< Mode of transportation. See TransportMode for all possible modes of transportation. std::vector cells; /**< If destination consists of different Cell%s, this gives the index of the Cell%s the Person changes to.*/ - TransportMode - trip_mode; ///< Mode of transportation. 1:Bike, 2:Car (Driver), 3:Car (Co-Driver)), 4:Public Transport, 5:Walking, 6:Other/Unknown - LocationType destination_type; ///< Type of destination Location. /** * @brief Construct a new Trip. * @param[in] id ID of the Person that makes the Trip. - * @param[in] time_new Time at which a Person changes the Location this currently cant be set for s specific day just a timepoint in a day. + * @param[in] trip_time Time at which a Person changes the Location this currently cant be set for s specific day just a timepoint in a day. * @param[in] destination Location where the Person changes to. * @param[in] destination_model_id Model the Person changes to. * @param[in] origin Location where the person starts the Trip. * @param[in] origin_model_id Model the Person starts the Trip. * @param[in] input_cells The index of the Cell%s the Person changes to. */ - Trip(PersonId id, TimePoint time_new, LocationId dest, int dest_model_id, LocationId orig, int orig_model_id, - TransportMode mode_of_transport, LocationType type_of_activity, const std::vector& input_cells = {}) + Trip(PersonId id, const TimePoint time, const LocationId dest, const int dest_model_id = 0, + const TransportMode mode_of_transport = mio::abm::TransportMode::Unknown, + const std::vector& input_cells = {}) : person_id(id) - , time(mio::abm::TimePoint(time_new.time_since_midnight().seconds())) + , trip_time(mio::abm::TimePoint(time.time_since_midnight().seconds())) , destination(dest) , destination_model_id(dest_model_id) - , origin(orig) - , origin_model_id(orig_model_id) - , cells(input_cells) , trip_mode(mode_of_transport) - , destination_type(type_of_activity) - { - } - - Trip(PersonId id, TimePoint time_new, LocationId dest, LocationId orig, TransportMode mode_of_transport, - LocationType type_of_activity, const std::vector& input_cells = {}) - : person_id(id) - , time(mio::abm::TimePoint(time_new.time_since_midnight().seconds())) - , destination(dest) - , destination_model_id(0) - , origin(orig) - , origin_model_id(0) , cells(input_cells) - , trip_mode(mode_of_transport) - , destination_type(type_of_activity) - { - } - Trip(PersonId id, TimePoint time_new, LocationId dest, LocationId orig, LocationType type_of_activity, - const std::vector& input_cells = {}) - : Trip(id, time_new, dest, orig, mio::abm::TransportMode::Unknown, type_of_activity, input_cells) - { - } - - Trip(PersonId id, TimePoint time_new, LocationId dest, LocationType type_of_activity, - const std::vector& input_cells = {}) - : Trip(id, time_new, dest, dest, mio::abm::TransportMode::Unknown, type_of_activity, input_cells) { } @@ -109,17 +77,18 @@ struct Trip { */ bool operator==(const Trip& other) const { - return (person_id == other.person_id) && (time == other.time) && (destination == other.destination) && - (origin == other.origin); + return (person_id == other.person_id) && (trip_time == other.trip_time) && (destination == other.destination) && + (destination_model_id == other.destination_model_id) && (trip_mode == other.trip_mode); } auto default_serialize() { return Members("Trip") .add("person_id", person_id) - .add("time", time) + .add("trip_time", trip_time) .add("destination", destination) - .add("origin", origin); + .add("model_id", destination_model_id) + .add("trip_mode", trip_mode); } }; @@ -132,31 +101,26 @@ class TripList /** * @brief Construct empty TripList. */ - TripList(); + TripList() = default; /** * @brief Get the next Trip. * @param weekend Whether the Trip%s during the week or on the weekend are used. */ - const Trip& get_next_trip(bool weekend) const; + const Trip& get_next_trip() const; /** - * @brief Get the time at which the next Trip will happen. + * @brief Get the trip_time at which the next Trip will happen. * @param weekend Whether the Trip%s during the week or on the weekend are used. */ - TimePoint get_next_trip_time(bool weekend) const; + TimePoint get_next_trip_time() const; /** - * @brief Add a Trip to the trip list. - * @param[in] trip The Trip to be added. + * @brief Adds Trips to the trip list. + * @param[in] trips The Trips to be added. * @param[in] weekend If the Trip is made on a weekend day. */ - void add_trip(Trip trip, bool weekend = false); - - /** - * @brief Use the same TripList for weekend and weekday. - */ - void use_weekday_trips_on_weekend(); + void add_trips(std::vector trip); /** * @brief Increment the current index to select the next Trip. @@ -178,9 +142,9 @@ class TripList * @brief Get the length of the TripList. * @param weekend Whether the Trip%s during the week or on the weekend are used. */ - size_t num_trips(bool weekend = false) const + size_t num_trips() const { - return weekend ? m_trips_weekend.size() : m_trips_weekday.size(); + return m_trips.size(); } /** @@ -194,16 +158,12 @@ class TripList /// This method is used by the default serialization feature. auto default_serialize() { - return Members("TestingScheme") - .add("trips_weekday", m_trips_weekday) - .add("trips_weekend", m_trips_weekend) - .add("index", m_current_index); + return Members("TestingScheme").add("trips", m_trips).add("index", m_current_index); } private: - std::vector m_trips_weekday; ///< The list of Trip%s a Person makes on a weekday. - std::vector m_trips_weekend; ///< The list of Trip%s a Person makes on a weekend day. - uint32_t m_current_index; ///< The index of the Trip a Person makes next. + std::vector m_trips; ///< The list of Trip%s a Person makes on a weekday. + uint32_t m_current_index = 0; ///< The index of the Trip a Person makes next. }; } // namespace abm @@ -213,7 +173,7 @@ template <> struct DefaultFactory { static abm::Trip create() { - return abm::Trip{abm::PersonId{}, abm::TimePoint{}, abm::LocationId{}, abm::LocationType{}}; + return abm::Trip{abm::PersonId{}, abm::TimePoint{}, abm::LocationId{}}; } }; diff --git a/cpp/models/graph_abm/graph_abm_mobility.h b/cpp/models/graph_abm/graph_abm_mobility.h index 686db87994..2cdc52261e 100644 --- a/cpp/models/graph_abm/graph_abm_mobility.h +++ b/cpp/models/graph_abm/graph_abm_mobility.h @@ -125,8 +125,12 @@ class ABMMobilityEdge for (int i = int(persons_to_change.size()) - 1; i >= 0; --i) { auto& person = model_from.get_persons()[persons_to_change[i]]; auto target_type = person.get_location_type(); + if (target_type == abm::LocationType::Count) { + target_type = model_to.get_location(person.get_location()).get_type(); + } //check if Person uses this edge if (person.get_assigned_location_model_id(target_type) == model_to.get_id()) { + auto target_id = person.get_assigned_location(target_type); //set correct location for person person.set_location(target_type, target_id, model_to.get_id()); diff --git a/cpp/models/graph_abm/graph_abmodel.h b/cpp/models/graph_abm/graph_abmodel.h index 05490bcbe6..9cbe071bd7 100644 --- a/cpp/models/graph_abm/graph_abmodel.h +++ b/cpp/models/graph_abm/graph_abmodel.h @@ -152,13 +152,12 @@ class GraphABModel : public abm::Model } // check if a person makes a trip - bool weekend = t.is_weekend(); - size_t num_trips = Base::m_trip_list.num_trips(weekend); + size_t num_trips = Base::m_trip_list.num_trips(); for (; Base::m_trip_list.get_current_index() < num_trips && - Base::m_trip_list.get_next_trip_time(weekend).seconds() < (t + dt).time_since_midnight().seconds(); + Base::m_trip_list.get_next_trip_time().seconds() < (t + dt).time_since_midnight().seconds(); Base::m_trip_list.increase_index()) { - auto& trip = Base::m_trip_list.get_next_trip(weekend); + auto& trip = Base::m_trip_list.get_next_trip(); auto& person = get_person(trip.person_id); auto person_index = Base::get_person_index(trip.person_id); auto personal_rng = PersonalRandomNumberGenerator(person); @@ -192,8 +191,7 @@ class GraphABModel : public abm::Model } else { //person moves to other world Base::m_activeness_statuses[person_index] = false; - person.set_location(trip.destination_type, abm::LocationId::invalid_id(), - std::numeric_limits::max()); + person.set_location(abm::LocationType::Count, trip.destination, std::numeric_limits::max()); m_person_buffer.push_back(person_index); m_are_exposure_caches_valid = false; m_is_local_population_cache_valid = false; diff --git a/cpp/simulations/abm_braunschweig.cpp b/cpp/simulations/abm_braunschweig.cpp index f1758ada16..5f1e1d1394 100644 --- a/cpp/simulations/abm_braunschweig.cpp +++ b/cpp/simulations/abm_braunschweig.cpp @@ -341,6 +341,7 @@ void create_model_from_data(mio::abm::Model& model, const std::string& filename, std::getline(fin, line); // Skip header row // Add the persons and trips + std::vector trips; while (std::getline(fin, line)) { row.clear(); @@ -357,8 +358,6 @@ void create_model_from_data(mio::abm::Model& model, const std::string& filename, uint32_t target_location_id = std::abs(row[index["loc_id_end"]]); uint32_t start_location_id = std::abs(row[index["loc_id_start"]]); uint32_t trip_start = row[index["start_time"]]; - uint32_t transport_mode = row[index["travel_mode"]]; - uint32_t acticity_end = row[index["activity_end"]]; // Add the trip to the trip list person and location must exist at this point auto target_location = locations.find(target_location_id)->second; @@ -388,12 +387,10 @@ void create_model_from_data(mio::abm::Model& model, const std::string& filename, // For trips where the start location is not known use Home instead start_location = model.get_person(pid_itr->second).get_assigned_location(mio::abm::LocationType::Home); } - model.get_trip_list().add_trip( - mio::abm::Trip(static_cast(pid_itr->first), - mio::abm::TimePoint(0) + mio::abm::minutes(trip_start), target_location, start_location, - mio::abm::TransportMode(transport_mode), mio::abm::LocationType(acticity_end))); + trips.push_back( + mio::abm::Trip(pid_itr->second, mio::abm::TimePoint(0) + mio::abm::minutes(trip_start), target_location)); } - model.get_trip_list().use_weekday_trips_on_weekend(); + model.get_trip_list().add_trips(trips); } void set_parameters(mio::abm::Parameters params) @@ -915,7 +912,7 @@ void write_log_to_file_trip_data(const T& history) int start_index = mobility_data_index - 1; using Type = std::tuple; + mio::abm::TransportMode, mio::abm::ActivityType, mio::abm::InfectionState>; while (!std::binary_search(std::begin(mobility_data[start_index]), std::end(mobility_data[start_index]), mobility_data[mobility_data_index][trip_index], [](const Type& v1, const Type& v2) { diff --git a/cpp/tests/test_abm_model.cpp b/cpp/tests/test_abm_model.cpp index dbf398632a..267963ce2e 100644 --- a/cpp/tests/test_abm_model.cpp +++ b/cpp/tests/test_abm_model.cpp @@ -350,18 +350,14 @@ TEST_F(TestModel, evolveMobilityTrips) // Set trips for persons between assigned locations. mio::abm::TripList& data = model.get_trip_list(); - mio::abm::Trip trip1(p1.get_id(), mio::abm::TimePoint(0) + mio::abm::hours(9), work_id, home_id, - mio::abm::LocationType::Work); - mio::abm::Trip trip2(p2.get_id(), mio::abm::TimePoint(0) + mio::abm::hours(9), event_id, home_id, - mio::abm::LocationType::SocialEvent); - mio::abm::Trip trip3(p5.get_id(), mio::abm::TimePoint(0) + mio::abm::hours(9), event_id, home_id, - mio::abm::LocationType::SocialEvent); - data.add_trip(trip1); - data.add_trip(trip2); - data.add_trip(trip3); - - // Set trips to use weekday trips on weekends. - data.use_weekday_trips_on_weekend(); + mio::abm::Trip trip1(p1.get_id(), mio::abm::TimePoint(0) + mio::abm::hours(9), work_id); + mio::abm::Trip trip2(p2.get_id(), mio::abm::TimePoint(0) + mio::abm::hours(9), event_id); + mio::abm::Trip trip3(p5.get_id(), mio::abm::TimePoint(0) + mio::abm::hours(9), event_id); + + auto trips_part1 = std::vector{trip2, trip3}; + auto trips_part2 = std::vector{trip1}; + data.add_trips(trips_part1); + data.add_trips(trips_part2); //to see if merge works // Mock the random distribution to control random behavior. ScopedMockDistribution>>> mock_uniform_dist2; @@ -405,54 +401,6 @@ TEST_F(TestModel, evolveMobilityTrips) EXPECT_EQ(model.get_number_persons(work_id), 1); EXPECT_EQ(model.get_number_persons(home_id), 1); EXPECT_EQ(model.get_number_persons(hospital_id), 1); - - // Move all persons back to their home location to prepare for weekend trips. - model.change_location(p1.get_id(), home_id); - model.change_location(p3.get_id(), home_id); - model.change_location(p2.get_id(), home_id); - model.change_location(p5.get_id(), home_id); - - // Update the time to the weekend and reset the trip index. - t = mio::abm::TimePoint(0) + mio::abm::days(6) + mio::abm::hours(8); - model.get_trip_list().reset_index(); - - // Evolve the model again to verify the weekend behavior. - model.evolve(t, dt); - - EXPECT_EQ(p1.get_location(), work_id); - EXPECT_EQ(p2.get_location(), event_id); - EXPECT_EQ(p3.get_location(), home_id); - EXPECT_EQ(p4.get_location(), home_id); - EXPECT_EQ(p5.get_location(), event_id); - EXPECT_EQ(model.get_number_persons(event_id), 2); - EXPECT_EQ(model.get_number_persons(work_id), 1); - EXPECT_EQ(model.get_number_persons(home_id), 2); - - // Add additional weekend trips for further verification. - bool weekend = true; - mio::abm::Trip tripweekend1(p1.get_id(), mio::abm::TimePoint(0) + mio::abm::days(6) + mio::abm::hours(10), event_id, - work_id, mio::abm::LocationType::SocialEvent); - mio::abm::Trip tripweekend2(p2.get_id(), mio::abm::TimePoint(0) + mio::abm::days(6) + mio::abm::hours(10), home_id, - event_id, mio::abm::LocationType::Home); - mio::abm::Trip tripweekend3(p5.get_id(), mio::abm::TimePoint(0) + mio::abm::days(6) + mio::abm::hours(10), work_id, - event_id, mio::abm::LocationType::Work); - data.add_trip(tripweekend1, weekend); - data.add_trip(tripweekend2, weekend); - data.add_trip(tripweekend3, weekend); - - // Advance time and evolve the model to check location transitions during the weekend. - t += mio::abm::hours(1); - - model.evolve(t, dt); - - EXPECT_EQ(p1.get_location(), event_id); - EXPECT_EQ(p2.get_location(), home_id); - EXPECT_EQ(p3.get_location(), home_id); - EXPECT_EQ(p4.get_location(), home_id); - EXPECT_EQ(p5.get_location(), work_id); - EXPECT_EQ(model.get_number_persons(event_id), 1); - EXPECT_EQ(model.get_number_persons(work_id), 1); - EXPECT_EQ(model.get_number_persons(home_id), 3); } #ifndef MEMILIO_ENABLE_OPENMP // TODO: Test can fail with parallel execution of mobility, as the capacity is not taken into account correctly at the moment (c. f. issue #640) @@ -558,15 +506,10 @@ TEST_F(TestModel, checkMobilityOfDeadPerson) // Add trip to see if a dead person can change location outside of cemetery by scheduled trips mio::abm::TripList& trip_list = model.get_trip_list(); - mio::abm::Trip trip1(p_dead.get_id(), mio::abm::TimePoint(0) + mio::abm::hours(2), work_id, home_id, - mio::abm::LocationType::Work); - mio::abm::Trip trip2(p_dead.get_id(), mio::abm::TimePoint(0) + mio::abm::hours(3), home_id, icu_id, - mio::abm::LocationType::Home); - mio::abm::Trip trip3(p_severe.get_id(), mio::abm::TimePoint(0) + mio::abm::hours(3), home_id, icu_id, - mio::abm::LocationType::Home); - trip_list.add_trip(trip1); - trip_list.add_trip(trip2); - trip_list.add_trip(trip3); + mio::abm::Trip trip1(p_dead.get_id(), mio::abm::TimePoint(0) + mio::abm::hours(2), home_id); + mio::abm::Trip trip2(p_dead.get_id(), mio::abm::TimePoint(0) + mio::abm::hours(3), icu_id); + mio::abm::Trip trip3(p_severe.get_id(), mio::abm::TimePoint(0) + mio::abm::hours(3), icu_id); + trip_list.add_trips({trip1, trip2, trip3}); // Check the dead person got burried and the severely infected person starts in Hospital model.evolve(t, dt); @@ -1008,16 +951,12 @@ TEST_F(TestModel, mobilityTripWithAppliedNPIs) // Using trip list mio::abm::TripList& trip_list = model.get_trip_list(); - mio::abm::Trip trip1(p_compliant_go_to_work.get_id(), t, work_id, home_id, mio::abm::LocationType::Work); - mio::abm::Trip trip2(p_compliant_go_to_school.get_id(), t, school_id, home_id, mio::abm::LocationType::School); - mio::abm::Trip trip3(p_no_mask.get_id(), t, work_id, home_id, mio::abm::LocationType::Work); - mio::abm::Trip trip4(p_no_test.get_id(), t, work_id, home_id, mio::abm::LocationType::Work); - mio::abm::Trip trip5(p_no_isolation.get_id(), t, work_id, home_id, mio::abm::LocationType::Work); - trip_list.add_trip(trip1); - trip_list.add_trip(trip2); - trip_list.add_trip(trip3); - trip_list.add_trip(trip4); - trip_list.add_trip(trip5); + mio::abm::Trip trip1(p_compliant_go_to_work.get_id(), t, work_id); + mio::abm::Trip trip2(p_compliant_go_to_school.get_id(), t, school_id); + mio::abm::Trip trip3(p_no_mask.get_id(), t, work_id); + mio::abm::Trip trip4(p_no_test.get_id(), t, work_id); + mio::abm::Trip trip5(p_no_isolation.get_id(), t, work_id); + trip_list.add_trips({trip1, trip2, trip3, trip4, trip5}); model.use_mobility_rules(false); model.evolve(t, dt); diff --git a/cpp/tests/test_abm_serialization.cpp b/cpp/tests/test_abm_serialization.cpp index 386cfe276f..e4bd5b7513 100644 --- a/cpp/tests/test_abm_serialization.cpp +++ b/cpp/tests/test_abm_serialization.cpp @@ -78,10 +78,11 @@ TEST(TestAbmSerialization, Trip) unsigned i = 1; // counter s.t. members have different values Json::Value reference_json; - reference_json["person_id"] = Json::UInt(i++); - reference_json["time"]["seconds"] = Json::Int(i++); - reference_json["destination"] = Json::UInt(i++); - reference_json["origin"] = Json::UInt(i++); + reference_json["person_id"] = Json::UInt(i++); + reference_json["trip_time"]["seconds"] = Json::Int(i++); + reference_json["destination"] = Json::UInt(i++); + reference_json["model_id"] = Json::Int(i++); + reference_json["trip_mode"] = Json::UInt(i++); test_json_serialization(reference_json); } @@ -267,8 +268,7 @@ TEST(TestAbmSerialization, Model) reference_json["rng"]["seeds"] = json_uint_array({i++, i++, i++, i++, i++, i++}); reference_json["testing_strategy"]["schemes"] = Json::Value(Json::arrayValue); reference_json["trip_list"]["index"] = Json::UInt(i++); - reference_json["trip_list"]["trips_weekday"] = Json::Value(Json::arrayValue); - reference_json["trip_list"]["trips_weekend"] = Json::Value(Json::arrayValue); + reference_json["trip_list"]["trips"] = Json::Value(Json::arrayValue); reference_json["use_mobility_rules"] = Json::Value(false); test_json_serialization(reference_json); diff --git a/cpp/tests/test_abm_simulation.cpp b/cpp/tests/test_abm_simulation.cpp index abe8f72982..53c372fe7c 100644 --- a/cpp/tests/test_abm_simulation.cpp +++ b/cpp/tests/test_abm_simulation.cpp @@ -100,28 +100,18 @@ TEST(TestSimulation, advanceWithCommonHistory) mio::abm::TripList& trip_list = model.get_trip_list(); // We add trips for person two to test the history and if it is working correctly - mio::abm::Trip trip1(static_cast(person2.get()), mio::abm::TimePoint(0) + mio::abm::hours(2), work_id, - home_id, mio::abm::LocationType::Work); - mio::abm::Trip trip2(static_cast(person2.get()), mio::abm::TimePoint(0) + mio::abm::hours(3), icu_id, - home_id, mio::abm::LocationType::ICU); - mio::abm::Trip trip3(static_cast(person2.get()), mio::abm::TimePoint(0) + mio::abm::hours(4), hospital_id, - home_id, mio::abm::LocationType::Hospital); - mio::abm::Trip trip4(static_cast(person2.get()), mio::abm::TimePoint(0) + mio::abm::hours(5), social_id, - home_id, mio::abm::LocationType::SocialEvent); - mio::abm::Trip trip5(static_cast(person2.get()), mio::abm::TimePoint(0) + mio::abm::hours(6), basics_id, - home_id, mio::abm::LocationType::BasicsShop); - mio::abm::Trip trip6(static_cast(person2.get()), mio::abm::TimePoint(0) + mio::abm::hours(7), public_id, - home_id, mio::abm::LocationType::PublicTransport); - mio::abm::Trip trip7(static_cast(person2.get()), mio::abm::TimePoint(0) + mio::abm::hours(8), home_id, - home_id, mio::abm::LocationType::Home); - - trip_list.add_trip(trip1); - trip_list.add_trip(trip2); - trip_list.add_trip(trip3); - trip_list.add_trip(trip4); - trip_list.add_trip(trip5); - trip_list.add_trip(trip6); - trip_list.add_trip(trip7); + mio::abm::Trip trip1(static_cast(person2.get()), mio::abm::TimePoint(0) + mio::abm::hours(2), home_id); + mio::abm::Trip trip2(static_cast(person2.get()), mio::abm::TimePoint(0) + mio::abm::hours(3), home_id); + mio::abm::Trip trip3(static_cast(person2.get()), mio::abm::TimePoint(0) + mio::abm::hours(4), home_id); + mio::abm::Trip trip4(static_cast(person2.get()), mio::abm::TimePoint(0) + mio::abm::hours(5), home_id); + mio::abm::Trip trip5(static_cast(person2.get()), mio::abm::TimePoint(0) + mio::abm::hours(6), home_id); + mio::abm::Trip trip6(static_cast(person2.get()), mio::abm::TimePoint(0) + mio::abm::hours(7), home_id); + mio::abm::Trip trip7(static_cast(person2.get()), mio::abm::TimePoint(0) + mio::abm::hours(8), home_id); + + // Add to one vector + auto trips = std::vector{trip1, trip2, trip3, trip4, trip5, trip6, trip7}; + + trip_list.add_trips(trips); mio::History diff --git a/cpp/tests/test_graph_abm.cpp b/cpp/tests/test_graph_abm.cpp index 187c3c68f4..4f15a94c77 100644 --- a/cpp/tests/test_graph_abm.cpp +++ b/cpp/tests/test_graph_abm.cpp @@ -125,13 +125,13 @@ TEST(TestGraphAbm, test_apply_mobility) p4.set_assigned_location(event_2.get_type(), event_2.get_id(), event_2.get_model_id()); mio::abm::TripList& trips = model1.get_trip_list(); - mio::abm::Trip trip1(p3.get_id(), mio::abm::TimePoint(0) + mio::abm::hours(8), event_id_1, model1.get_id(), home_id, - model1.get_id(), mio::abm::TransportMode::Unknown, mio::abm::LocationType::SocialEvent); - mio::abm::Trip trip2(p4.get_id(), mio::abm::TimePoint(0) + mio::abm::hours(8), event_id_2, model2.get_id(), home_id, - model1.get_id(), mio::abm::TransportMode::Unknown, mio::abm::LocationType::SocialEvent); + mio::abm::Trip trip1(p3.get_id(), mio::abm::TimePoint(0) + mio::abm::hours(8), event_id_1, model1.get_id(), + mio::abm::TransportMode::Unknown, {}); + mio::abm::Trip trip2(p4.get_id(), mio::abm::TimePoint(0) + mio::abm::hours(8), event_id_2, model2.get_id(), + mio::abm::TransportMode::Unknown, {}); - trips.add_trip(trip1); - trips.add_trip(trip2); + auto tripsvec = std::vector{trip1, trip2}; + trips.add_trips(tripsvec); auto t = mio::abm::TimePoint(0); auto dt = mio::abm::hours(12); @@ -218,10 +218,10 @@ TEST(TestGraphABM, mask_compliance) //add trips for p2 mio::abm::TripList& trips = model.get_trip_list(); - mio::abm::Trip trip1(p2.get_id(), mio::abm::TimePoint(0) + mio::abm::hours(8), school_id, model.get_id(), home_id, - model.get_id(), mio::abm::TransportMode::Unknown, mio::abm::LocationType::School); + mio::abm::Trip trip1(p2.get_id(), mio::abm::TimePoint(0) + mio::abm::hours(8), school_id, model.get_id(), + mio::abm::TransportMode::Unknown, {}); - trips.add_trip(trip1); + trips.add_trips({trip1}); auto t0 = mio::abm::TimePoint(0); auto dt = mio::abm::hours(12); diff --git a/pycode/memilio-simulation/memilio/simulation/bindings/models/abm.cpp b/pycode/memilio-simulation/memilio/simulation/bindings/models/abm.cpp index 48a2cfa19a..08dfee7202 100644 --- a/pycode/memilio-simulation/memilio/simulation/bindings/models/abm.cpp +++ b/pycode/memilio-simulation/memilio/simulation/bindings/models/abm.cpp @@ -186,22 +186,17 @@ PYBIND11_MODULE(_simulation_abm, m) pymio::bind_Range().get_persons())>(m, "_ModelPersonsRange"); pymio::bind_class(m, "Trip") - .def(py::init>(), - py::arg("person_id"), py::arg("time"), py::arg("destination"), py::arg("origin"), - py::arg("type_of_activity"), py::arg("cells") = std::vector()) + .def(py::init(), py::arg("person_id"), + py::arg("time"), py::arg("destination")) .def_readwrite("person_id", &mio::abm::Trip::person_id) - .def_readwrite("time", &mio::abm::Trip::time) - .def_readwrite("destination", &mio::abm::Trip::destination) - .def_readwrite("origin", &mio::abm::Trip::origin) - .def_readwrite("destination_type", &mio::abm::Trip::destination_type) - .def_readwrite("cells", &mio::abm::Trip::cells); + .def_readwrite("trip_time", &mio::abm::Trip::trip_time) + .def_readwrite("destination", &mio::abm::Trip::destination); pymio::bind_class(m, "TripList") .def(py::init<>()) - .def("add_trip", &mio::abm::TripList::add_trip, py::arg("trip"), py::arg("weekend") = false) - .def("next_trip", &mio::abm::TripList::get_next_trip, py::arg("weekend") = false) - .def("num_trips", &mio::abm::TripList::num_trips, py::arg("weekend") = false); + .def("add_trips", &mio::abm::TripList::add_trips, py::arg("trips") = std::vector()) + .def("next_trip", &mio::abm::TripList::get_next_trip) + .def("num_trips", &mio::abm::TripList::num_trips); pymio::bind_class(m, "Model") .def(py::init()) diff --git a/pycode/memilio-simulation/memilio/simulation_test/test_abm.py b/pycode/memilio-simulation/memilio/simulation_test/test_abm.py index 2e3df1bd04..4244e0bc6b 100644 --- a/pycode/memilio-simulation/memilio/simulation_test/test_abm.py +++ b/pycode/memilio-simulation/memilio/simulation_test/test_abm.py @@ -106,10 +106,9 @@ def test_simulation(self): # trips trip_list = abm.TripList() - trip_list.add_trip(abm.Trip(0, abm.TimePoint( - 0) + abm.hours(8), social_event_id, home_id, abm.LocationType.SocialEvent)) - trip_list.add_trip(abm.Trip(1, abm.TimePoint(0) + - abm.hours(8), work_id, home_id, abm.LocationType.Work)) + trip_list.add_trips( + [abm.Trip(abm.PersonId(0), abm.TimePoint(0) + abm.hours(8), social_event_id), abm.Trip(abm.PersonId(1), abm.TimePoint(0) + abm.hours(8), work_id)]) + model.trip_list = trip_list model.use_mobility_rules = False self.assertEqual(model.trip_list.num_trips(), 2)