Skip to content
Snippets Groups Projects
Select Git revision
  • b608903df813f3cc0252259cb57e977dea94f4b5
  • develop default protected
  • feature/gmsh-reader
  • origin/stage/bouguettaia
  • feature/kinetic-schemes
  • feature/reconstruction
  • feature/local-dt-fsi
  • feature/composite-scheme-sources
  • feature/composite-scheme-other-fluxes
  • feature/serraille
  • feature/variational-hydro
  • feature/composite-scheme
  • hyperplastic
  • feature/polynomials
  • feature/gks
  • feature/implicit-solver-o2
  • feature/coupling_module
  • feature/implicit-solver
  • feature/merge-local-dt-fsi
  • master protected
  • feature/escobar-smoother
  • v0.5.0 protected
  • v0.4.1 protected
  • v0.4.0 protected
  • v0.3.0 protected
  • v0.2.0 protected
  • v0.1.0 protected
  • Kidder
  • v0.0.4 protected
  • v0.0.3 protected
  • v0.0.2 protected
  • v0 protected
  • v0.0.1 protected
33 results

ConnectivityDispatcher.hpp

Blame
  • ConnectivityDispatcher.hpp 11.38 KiB
    #ifndef CONNECTIVITY_DISPATCHER_HPP
    #define CONNECTIVITY_DISPATCHER_HPP
    
    #include <Mesh.hpp>
    #include <ItemValue.hpp>
    #include <ItemValueUtils.hpp>
    
    #include <unordered_map>
    #include <ConnectivityDescriptor.hpp>
    
    template <int Dimension>
    class ConnectivityDispatcher
    {
     public:
      using ConnectivityType = Connectivity<Dimension>;
    
     private:
      const ConnectivityType& m_connectivity;
      ConnectivityDescriptor m_new_descriptor;
      std::shared_ptr<ConnectivityType> m_dispatched_connectivity;
    
      template <ItemType item_type>
      struct DispatchedItemInfo
      {
        using ItemId = ItemIdT<item_type>;
        ItemValue<const int, item_type> m_new_owner;
        Array<const unsigned int> m_list_to_send_size_by_proc;
        std::vector<Array<const ItemId>> m_list_to_send_by_proc;
        Array<const unsigned int> m_list_to_recv_size_by_proc;
        std::unordered_map<int, int> m_number_to_id_map;
        std::vector<Array<const ItemId>> m_recv_id_correspondance_by_proc;
      };
    
      DispatchedItemInfo<ItemType::cell> m_dispatched_cell_info;
      DispatchedItemInfo<ItemType::face> m_dispatched_face_info;
      DispatchedItemInfo<ItemType::edge> m_dispatched_edge_info;
      DispatchedItemInfo<ItemType::node> m_dispatched_node_info;
    
      template <ItemType item_type>
      PASTIS_INLINE
      DispatchedItemInfo<item_type>& _dispatchedInfo()
      {
        if constexpr (item_type == ItemType::cell) {
          return m_dispatched_cell_info;
        } else if constexpr (item_type == ItemType::face) {
          return m_dispatched_face_info;
        } else if constexpr (item_type == ItemType::edge) {
          return m_dispatched_edge_info;
        } else {
          return m_dispatched_node_info;
        }
      }
    
      template <ItemType item_type>
      PASTIS_INLINE
      const DispatchedItemInfo<item_type>& _dispatchedInfo() const
      {
        if constexpr (item_type == ItemType::cell) {
          return m_dispatched_cell_info;
        } else if constexpr (item_type == ItemType::face) {
          return m_dispatched_face_info;
        } else if constexpr (item_type == ItemType::edge) {
          return m_dispatched_edge_info;
        } else {
          return m_dispatched_node_info;
        }
      }
    
      template <typename ItemToItem>
      struct DispatchedItemOfItemInfo
      {
        std::vector<Array<const int>> m_number_of_sub_item_per_item_to_recv_by_proc;
        std::vector<Array<const int>> m_sub_item_numbers_to_recv_by_proc;
      };
    
      DispatchedItemOfItemInfo<NodeOfCell> m_dispatched_node_of_cell_info;
      DispatchedItemOfItemInfo<EdgeOfCell> m_dispatched_edge_of_cell_info;
      DispatchedItemOfItemInfo<FaceOfCell> m_dispatched_face_of_cell_info;
    
      DispatchedItemOfItemInfo<NodeOfEdge> m_dispatched_node_of_edge_info;
      DispatchedItemOfItemInfo<FaceOfEdge> m_dispatched_face_of_edge_info;
      DispatchedItemOfItemInfo<CellOfEdge> m_dispatched_cell_of_edge_info;
    
      DispatchedItemOfItemInfo<NodeOfFace> m_dispatched_node_of_face_info;
      DispatchedItemOfItemInfo<EdgeOfFace> m_dispatched_edge_of_face_info;
      DispatchedItemOfItemInfo<CellOfFace> m_dispatched_cell_of_face_info;
    
      DispatchedItemOfItemInfo<EdgeOfNode> m_dispatched_edge_of_node_info;
      DispatchedItemOfItemInfo<FaceOfNode> m_dispatched_face_of_node_info;
      DispatchedItemOfItemInfo<CellOfNode> m_dispatched_cell_of_node_info;
    
      template <typename ItemOfItem>
      PASTIS_INLINE
      DispatchedItemOfItemInfo<ItemOfItem>& _dispatchedInfo()
      {
        if constexpr (std::is_same_v<NodeOfCell, ItemOfItem>) {
          return m_dispatched_node_of_cell_info;
        } else if constexpr (std::is_same_v<EdgeOfCell, ItemOfItem>) {
          return m_dispatched_edge_of_cell_info;
        } else if constexpr (std::is_same_v<FaceOfCell, ItemOfItem>) {
          return m_dispatched_face_of_cell_info;
        } else if constexpr (std::is_same_v<NodeOfEdge, ItemOfItem>) {
          return m_dispatched_node_of_edge_info;
        } else if constexpr (std::is_same_v<FaceOfEdge, ItemOfItem>) {
          return m_dispatched_face_of_edge_info;
        } else if constexpr (std::is_same_v<CellOfEdge, ItemOfItem>) {
          return m_dispatched_cell_of_edge_info;
        } else if constexpr (std::is_same_v<NodeOfFace, ItemOfItem>) {
          return m_dispatched_node_of_face_info;
        } else if constexpr (std::is_same_v<EdgeOfFace, ItemOfItem>) {
          return m_dispatched_edge_of_face_info;
        } else if constexpr (std::is_same_v<CellOfFace, ItemOfItem>) {
          return m_dispatched_cell_of_face_info;
        } else if constexpr (std::is_same_v<EdgeOfNode, ItemOfItem>) {
          return m_dispatched_edge_of_node_info;
        } else if constexpr (std::is_same_v<FaceOfNode, ItemOfItem>) {
          return m_dispatched_face_of_node_info;
        } else if constexpr (std::is_same_v<CellOfNode, ItemOfItem>) {
          return m_dispatched_cell_of_node_info;
        } else {
          static_assert(is_false_v<ItemOfItem>, "Unexpected ItemOfItem type");
        }
      }
    
      template <typename ItemOfItem>
      PASTIS_INLINE
      const DispatchedItemOfItemInfo<ItemOfItem>& _dispatchedInfo() const
      {
        if constexpr (std::is_same_v<NodeOfCell, ItemOfItem>) {
          return m_dispatched_node_of_cell_info;
        } else if constexpr (std::is_same_v<EdgeOfCell, ItemOfItem>) {
          return m_dispatched_edge_of_cell_info;
        } else if constexpr (std::is_same_v<FaceOfCell, ItemOfItem>) {
          return m_dispatched_face_of_cell_info;
        } else if constexpr (std::is_same_v<NodeOfEdge, ItemOfItem>) {
          return m_dispatched_node_of_edge_info;
        } else if constexpr (std::is_same_v<FaceOfEdge, ItemOfItem>) {
          return m_dispatched_face_of_edge_info;
        } else if constexpr (std::is_same_v<CellOfEdge, ItemOfItem>) {
          return m_dispatched_cell_of_edge_info;
        } else if constexpr (std::is_same_v<NodeOfFace, ItemOfItem>) {
          return m_dispatched_node_of_face_info;
        } else if constexpr (std::is_same_v<EdgeOfFace, ItemOfItem>) {
          return m_dispatched_edge_of_face_info;
        } else if constexpr (std::is_same_v<CellOfFace, ItemOfItem>) {
          return m_dispatched_cell_of_face_info;
        } else if constexpr (std::is_same_v<EdgeOfNode, ItemOfItem>) {
          return m_dispatched_edge_of_node_info;
        } else if constexpr (std::is_same_v<FaceOfNode, ItemOfItem>) {
          return m_dispatched_face_of_node_info;
        } else if constexpr (std::is_same_v<CellOfNode, ItemOfItem>) {
          return m_dispatched_cell_of_node_info;
        } else {
          static_assert(is_false_v<ItemOfItem>, "Unexpected ItemOfItem type");
        }
      }
    
      template <ItemType item_type>
      void _buildNewOwner();
    
      template <ItemType item_type>
      void _buildItemListToSend();
    
      void _buildCellNumberIdMap();
    
      template <typename ItemOfItemT>
      void _buildSubItemNumberToIdMap();
    
      template <ItemType item_type>
      void _buildItemToExchangeLists();
    
      template <ItemType item_type>
      void _buildNumberOfItemToExchange();
    
      template <typename ItemOfItemT>
      void _buildItemToSubItemDescriptor();
    
      void _dispatchEdges();
      void _dispatchFaces();
    
      template<typename DataType, ItemType item_type, typename ConnectivityPtr>
      void _gatherFrom(const ItemValue<DataType, item_type, ConnectivityPtr>& data_to_gather,
                       std::vector<std::remove_const_t<DataType>>& gathered_vector);
    
      template<typename DataType, typename ItemOfItem, typename ConnectivityPtr>
      void _gatherFrom(const SubItemValuePerItem<DataType, ItemOfItem, ConnectivityPtr>& data_to_gather,
                       std::vector<Array<std::remove_const_t<DataType>>>& gathered_vector);
    
      template <typename SubItemOfItemT>
      void _buildNumberOfSubItemPerItemToRecvByProc();
    
      template <typename SubItemOfItemT>
      void _buildSubItemNumbersToRecvByProc();
    
      template <ItemType item_type>
      void _buildRecvItemIdCorrespondanceByProc();
    
      template <ItemType item_type>
      void _buildItemReferenceList();
    
     public:
      std::shared_ptr<const ConnectivityType>
      dispatchedConnectivity() const
      {
        return m_dispatched_connectivity;
      }
    
      template<typename DataType, ItemType item_type, typename ConnectivityPtr>
      std::vector<Array<const DataType>>
      exchange(ItemValue<DataType, item_type, ConnectivityPtr> item_value) const
      {
        using ItemId = ItemIdT<item_type>;
        using MutableDataType = std::remove_const_t<DataType>;
        std::vector<Array<const DataType>> item_value_to_send_by_proc(parallel::size());
    
        const auto& item_list_to_send_by_proc = this->_dispatchedInfo<item_type>().m_list_to_send_by_proc;
    
        for (size_t i=0; i<parallel::size(); ++i) {
          const Array<const ItemId>& item_list = item_list_to_send_by_proc[i];
          Array<MutableDataType> item_value_list(item_list.size());
          parallel_for (item_list.size(), PASTIS_LAMBDA(const ItemId& item_id) {
              item_value_list[item_id] = item_value[item_list[item_id]];
            });
          item_value_to_send_by_proc[i] = item_value_list;
        }
    
        std::vector<Array<MutableDataType>> recv_item_value_by_proc(parallel::size());
        {
          const auto& list_to_recv_size_by_proc = this->_dispatchedInfo<item_type>().m_list_to_recv_size_by_proc;
          for (size_t i=0; i<parallel::size(); ++i) {
            recv_item_value_by_proc[i] = Array<MutableDataType>(list_to_recv_size_by_proc[i]);
          }
        }
        parallel::exchange(item_value_to_send_by_proc, recv_item_value_by_proc);
    
        std::vector<Array<const DataType>> const_recv_item_value_by_proc(parallel::size());
        for (size_t i=0; i<parallel::size(); ++i) {
          const_recv_item_value_by_proc[i] = recv_item_value_by_proc[i];
        }
    
        return const_recv_item_value_by_proc;
      }
    
      template<typename DataType, ItemType item_type, typename ConnectivityPtr>
      ItemValue<std::remove_const_t<DataType>, item_type, ConnectivityPtr>
      dispatch(ItemValue<DataType, item_type, ConnectivityPtr> item_value) const
      {
        using ItemId = ItemIdT<item_type>;
    
        Assert(m_dispatched_connectivity.use_count()> 0,
               "cannot dispatch quantity before connectivity");
    
        const auto& item_list_to_send_by_proc = this->_dispatchedInfo<item_type>().m_list_to_send_by_proc;
    
        using MutableDataType = std::remove_const_t<DataType>;
        std::vector<Array<DataType>> item_value_to_send_by_proc(parallel::size());
        for (size_t i=0; i<parallel::size(); ++i) {
          const Array<const ItemId>& item_list = item_list_to_send_by_proc[i];
          Array<MutableDataType> item_value_list(item_list.size());
          parallel_for (item_list.size(), PASTIS_LAMBDA(const ItemId& item_id) {
              item_value_list[item_id] = item_value[item_list[item_id]];
            });
          item_value_to_send_by_proc[i] = item_value_list;
        }
    
        const auto& item_list_to_recv_size_by_proc = this->_dispatchedInfo<item_type>().m_list_to_recv_size_by_proc;
        std::vector<Array<MutableDataType>> recv_item_value_by_proc(parallel::size());
        for (size_t i=0; i<parallel::size(); ++i) {
          recv_item_value_by_proc[i] = Array<MutableDataType>(item_list_to_recv_size_by_proc[i]);
        }
    
        parallel::exchange(item_value_to_send_by_proc, recv_item_value_by_proc);
    
        const auto& recv_item_id_correspondance_by_proc =
            this->_dispatchedInfo<item_type>().m_recv_id_correspondance_by_proc;
        ItemValue<MutableDataType, item_type> new_item_value(*m_dispatched_connectivity);
        for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) {
          const auto& recv_item_id_correspondance = recv_item_id_correspondance_by_proc[i_rank];
          const auto& recv_item_value = recv_item_value_by_proc[i_rank];
          parallel_for(recv_item_value.size(), PASTIS_LAMBDA(size_t r) {
              const ItemId& item_id = recv_item_id_correspondance[r];
              new_item_value[item_id] = recv_item_value[r];
            });
        }
        return new_item_value;
      }
    
      ConnectivityDispatcher(const ConnectivityType& mesh);
      ConnectivityDispatcher(const ConnectivityDispatcher&) = delete;
      ~ConnectivityDispatcher() = default;
    };
    
    
    #endif // CONNECTIVITY_DISPATCHER_HPP