LCOV - code coverage report
Current view: top level - models/graph_abm - graph_abm_mobility.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 34 34 100.0 %
Date: 2025-02-17 13:46:44 Functions: 7 14 50.0 %

          Line data    Source code
       1             : /*
       2             : * Copyright (C) 2020-2024 MEmilio
       3             : *
       4             : * Authors: Julia Bicker
       5             : *
       6             : * Contact: Martin J. Kuehn <Martin.Kuehn@DLR.de>
       7             : *
       8             : * Licensed under the Apache License, Version 2.0 (the "License");
       9             : * you may not use this file except in compliance with the License.
      10             : * You may obtain a copy of the License at
      11             : *
      12             : *     http://www.apache.org/licenses/LICENSE-2.0
      13             : *
      14             : * Unless required by applicable law or agreed to in writing, software
      15             : * distributed under the License is distributed on an "AS IS" BASIS,
      16             : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      17             : * See the License for the specific language governing permissions and
      18             : * limitations under the License.
      19             : */
      20             : 
      21             : #ifndef MIO_ABM_GRAPH_MOBILITY_H
      22             : #define MIO_ABM_GRAPH_MOBILITY_H
      23             : 
      24             : #include "abm/simulation.h"
      25             : #include "abm/time.h"
      26             : #include "abm/location_type.h"
      27             : #include "abm/parameters.h"
      28             : #include "abm/person.h"
      29             : #include "abm/person_id.h"
      30             : #include "abm/model_functions.h"
      31             : #include "graph_abm/graph_abmodel.h"
      32             : #include "memilio/mobility/graph_simulation.h"
      33             : #include "memilio/mobility/graph.h"
      34             : #include "memilio/utils/compiler_diagnostics.h"
      35             : #include <algorithm>
      36             : #include <cstddef>
      37             : #include <iostream>
      38             : #include <utility>
      39             : #include <vector>
      40             : 
      41             : namespace mio
      42             : {
      43             : /**
      44             : * @brief Represents the ABM simulation in one node of the ABM graph model.
      45             : */
      46             : template <class... History>
      47             : class ABMSimulationNode
      48             : {
      49             : 
      50             : public:
      51             :     using Sim = abm::Simulation<GraphABModel>;
      52             : 
      53             :     template <class... Args, typename = std::enable_if_t<std::is_constructible<Sim, Args...>::value, void>>
      54           6 :     ABMSimulationNode(std::tuple<History...>&& history, Args&&... args)
      55           6 :         : m_simulation(std::forward<Args>(args)...)
      56           6 :         , m_history(history)
      57             :     {
      58           6 :     }
      59             : 
      60             :     /**
      61             :     *@brief Get abm simulation in this node.
      62             :     */
      63          62 :     Sim& get_simulation()
      64             :     {
      65          62 :         return m_simulation;
      66             :     }
      67             :     const Sim& get_simulation() const
      68             :     {
      69             :         return m_simulation;
      70             :     }
      71             : 
      72             :     /**
      73             :      * @brief Get history object(s) in this node.
      74             :      */
      75             :     std::tuple<History...>& get_history()
      76             :     {
      77             :         return m_history;
      78             :     }
      79             :     const std::tuple<History...>& get_history() const
      80             :     {
      81             :         return m_history;
      82             :     }
      83             : 
      84             :     /**
      85             :     * @brief advances the simulation in this node by t+dt and logs information in History object(s)
      86             :     * @tparam History history object type(s)
      87             :     * @param[in] t Current time point
      88             :     * @param[in] dt Time span that shoulb be advanced
      89             :     * @param[in, out] history History object(s) storing simulation information
      90             :     */
      91          24 :     void advance(mio::abm::TimePoint t, mio::abm::TimeSpan dt)
      92             :     {
      93          24 :         m_simulation.advance(t + dt, std::get<0>(m_history));
      94          24 :     }
      95             : 
      96             : private:
      97             :     Sim m_simulation; ///< ABM Simulation of the node
      98             :     std::tuple<History...> m_history;
      99             : };
     100             : 
     101             : /**
     102             :  * Represents the mobility between two nodes.
     103             :  */
     104             : template <class... History>
     105             : class ABMMobilityEdge
     106             : {
     107             : 
     108             : public:
     109             :     /**
     110             :      * @brief Exchanges persons via the edge. 
     111             :      * Commuters are given by the person buffer of node_from.
     112             :      * @param[in] node_from Commuters home node
     113             :      * @param[in] node_to Node commuters (temporarily) move to
     114             :      * @param[in] t Echange time point
     115             :      */
     116          22 :     void apply_mobility(ABMSimulationNode<History...>& node_from, ABMSimulationNode<History...>& node_to,
     117             :                         abm::TimePoint /*t*/)
     118             :     {
     119          22 :         auto& model_from        = node_from.get_simulation().get_model();
     120          22 :         auto& model_to          = node_to.get_simulation().get_model();
     121          22 :         auto& persons_to_change = model_from.get_person_buffer();
     122             :         //sort vector such that we start removing the persons from the bottom
     123          22 :         std::sort(persons_to_change.begin(), persons_to_change.end());
     124             :         //iterate over all persons that change from node_from
     125          26 :         for (int i = int(persons_to_change.size()) - 1; i >= 0; --i) {
     126           4 :             auto& person     = model_from.get_persons()[persons_to_change[i]];
     127           4 :             auto target_type = person.get_location_type();
     128             :             //check if Person uses this edge
     129           4 :             if (person.get_assigned_location_model_id(target_type) == model_to.get_id()) {
     130           3 :                 auto target_id = person.get_assigned_location(target_type);
     131             :                 //set correct location for person
     132           3 :                 person.set_location(target_type, target_id, model_to.get_id());
     133             :                 //add person to model_to
     134           3 :                 model_to.add_person(std::move(person));
     135             :                 //remove person from model_from
     136           3 :                 model_from.remove_person(persons_to_change[i]);
     137             :                 //correct indices in persons buffer from node_from
     138             :                 //here it is required that the vector is sorted
     139           5 :                 for (size_t j = i + 1; j < persons_to_change.size(); ++j) {
     140           2 :                     persons_to_change[j]--;
     141             :                 }
     142             :                 //delete current index from list
     143           3 :                 persons_to_change.erase(persons_to_change.begin() + i);
     144             :             }
     145             :         }
     146          22 :     }
     147             : };
     148             : 
     149             : /**
     150             :  * @brief Edge functor for abm graph simulation. 
     151             :  * @see ABMMobilityEdge::apply_mobility
     152             :  * The attribute dt is required by the GraphSimulation class and therefore an input argument of the function.
     153             :  * However it is not used in ABMMobilityEdge::apply_mobility.
     154             :  * @param[in] t Time point the functor is applied.
     155             :  * @param[in] edge ABMMobilityEdge for which the functor is applied.
     156             :  * @param[in] node_from Edge start node.
     157             :  * @param[in] node_to Edge end node.
     158             :  */
     159             : template <class... History>
     160          20 : void apply_mobility(abm::TimePoint t, abm::TimeSpan /*dt*/, ABMMobilityEdge<History...>& edge,
     161             :                     ABMSimulationNode<History...>& node_from, ABMSimulationNode<History...>& node_to)
     162             : {
     163          20 :     edge.apply_mobility(node_from, node_to, t);
     164          20 : }
     165             : 
     166             : /**
     167             :  * @brief Node functor for abm graph simulation.
     168             :  * @see ABMSimulationNode::advance
     169             :  * @param[in] t Time point the functor is applied.
     170             :  * @param[in] dt Time interval the node is advanced.
     171             :  * @param[in] node ABMSimulationNode to which the functor is applied.
     172             :  */
     173             : template <class... History>
     174          20 : void advance_model(abm::TimePoint t, abm::TimeSpan dt, ABMSimulationNode<History...>& node)
     175             : {
     176          20 :     node.advance(t, dt);
     177          20 : }
     178             : 
     179             : /**
     180             :  * @brief Creates an abm graph simulation.
     181             :  * Every dt time step for each edge the persons that want to change to a location in another node 
     182             :  * are removed from the model in their former location's node and added to the model of the new location.
     183             :  * @param[in] t0 Start time point of the simulation.
     184             :  * @param[in] dt Step between mobility on edges.
     185             :  * @param[in] graph Graph for simulation.
     186             :  */
     187             : template <class... History>
     188             : GraphSimulation<Graph<ABMSimulationNode<History...>, ABMMobilityEdge<History...>>, abm::TimePoint, abm::TimeSpan,
     189             :                 void (*)(mio::abm::TimePoint, mio::abm::TimeSpan, mio::ABMMobilityEdge<History...>&,
     190             :                          mio::ABMSimulationNode<History...>&, mio::ABMSimulationNode<History...>&),
     191             :                 void (*)(mio::abm::TimePoint, mio::abm::TimeSpan, mio::ABMSimulationNode<History...>&)>
     192           1 : make_abm_graph_sim(abm::TimePoint t0, abm::TimeSpan dt,
     193             :                    Graph<ABMSimulationNode<History...>, ABMMobilityEdge<History...>>&& graph)
     194             : {
     195           1 :     return make_graph_sim(t0, dt, std::move(graph), &advance_model<History...>, &apply_mobility<History...>);
     196             : }
     197             : 
     198             : } // namespace mio
     199             : 
     200             : #endif // MIO_ABM_GRAPH_MOBILITY_H

Generated by: LCOV version 1.14