From b7082fe981a3a8f47d84ee836bc0d7e094b65792 Mon Sep 17 00:00:00 2001 From: Stephane Del Pino <stephane.delpino44@gmail.com> Date: Fri, 15 Mar 2019 19:19:18 +0100 Subject: [PATCH] Continue clean-up in mesh dispatcher --- src/mesh/ConnectivityDispatcher.cpp | 583 ++++++++++++++-------------- src/mesh/ConnectivityDispatcher.hpp | 165 ++++---- src/mesh/SubItemOfItemType.hpp | 32 ++ 3 files changed, 425 insertions(+), 355 deletions(-) create mode 100644 src/mesh/SubItemOfItemType.hpp diff --git a/src/mesh/ConnectivityDispatcher.cpp b/src/mesh/ConnectivityDispatcher.cpp index dcabf13c6..f88f596f1 100644 --- a/src/mesh/ConnectivityDispatcher.cpp +++ b/src/mesh/ConnectivityDispatcher.cpp @@ -1,82 +1,63 @@ #include <ConnectivityDispatcher.hpp> #include <Partitioner.hpp> +#include <SubItemOfItemType.hpp> + #include <unordered_map> template <int Dimension> -CellValue<int> -ConnectivityDispatcher<Dimension>::_getCellNewOwner() +template <ItemType item_type> +void +ConnectivityDispatcher<Dimension>::_buildNewOwner() { - CSRGraph connectivity_graph = m_connectivity.cellToCellGraph(); - Partitioner P; + if constexpr (item_type == ItemType::cell) { + CSRGraph connectivity_graph = m_connectivity.cellToCellGraph(); + Partitioner P; - CellValue<int> cell_new_owner(m_connectivity); - cell_new_owner = P.partition(connectivity_graph); - return cell_new_owner; -} + CellValue<int> cell_new_owner(m_connectivity); + cell_new_owner = P.partition(connectivity_graph); -template <int Dimension> -FaceValue<int> -ConnectivityDispatcher<Dimension>::_getFaceNewOwner() -{ - const auto& face_to_cell_matrix - = m_connectivity.faceToCellMatrix(); - const auto& cell_number = m_connectivity.cellNumber(); - - FaceValue<int> face_new_owner(m_connectivity); - parallel_for(m_connectivity.numberOfFaces(), PASTIS_LAMBDA(const FaceId& l) { - const auto& face_to_cell = face_to_cell_matrix[l]; - CellId Jmin = face_to_cell[0]; - - for (size_t j=1; j<face_to_cell.size(); ++j) { - const CellId J = face_to_cell[j]; - if (cell_number[J] < cell_number[Jmin]) { - Jmin=J; - } - } - face_new_owner[l] = m_cell_new_owner[Jmin]; - }); + this->_dispatchedInfo<ItemType::cell>().m_new_owner = cell_new_owner; + } else { + const auto& item_to_cell_matrix + = m_connectivity.template getItemToItemMatrix<item_type,ItemType::cell>(); -#warning Add missing synchronize (fix it!) - // synchronize(face_new_owner); - return face_new_owner; -} + const auto& cell_number = m_connectivity.cellNumber(); -template <int Dimension> -NodeValue<int> -ConnectivityDispatcher<Dimension>::_getNodeNewOwner() -{ - const auto& node_to_cell_matrix = m_connectivity.nodeToCellMatrix(); - const auto& cell_number = m_connectivity.cellNumber(); + const auto& cell_new_owner = this->_dispatchedInfo<ItemType::cell>().m_new_owner; - NodeValue<int> node_new_owner(m_connectivity); - parallel_for(m_connectivity.numberOfNodes(), PASTIS_LAMBDA(const NodeId& r) { - const auto& node_to_cell = node_to_cell_matrix[r]; - CellId Jmin = node_to_cell[0]; + using ItemId = ItemIdT<item_type>; + ItemValue<int, item_type> item_new_owner(m_connectivity); + parallel_for(item_new_owner.size(), PASTIS_LAMBDA(const ItemId& l) { + const auto& item_to_cell = item_to_cell_matrix[l]; + CellId Jmin = item_to_cell[0]; - for (size_t j=1; j<node_to_cell.size(); ++j) { - const CellId J = node_to_cell[j]; - if (cell_number[J] < cell_number[Jmin]) { - Jmin=J; + for (size_t j=1; j<item_to_cell.size(); ++j) { + const CellId J = item_to_cell[j]; + if (cell_number[J] < cell_number[Jmin]) { + Jmin=J; + } } - } - node_new_owner[r] = m_cell_new_owner[Jmin]; - }); + item_new_owner[l] = cell_new_owner[Jmin]; + }); #warning Add missing synchronize (fix it!) - // synchronize(node_new_owner); - return node_new_owner; + // synchronize(face_new_owner); + this->_dispatchedInfo<item_type>().m_new_owner = item_new_owner; + } } template <int Dimension> std::vector<Array<const CellId>> -ConnectivityDispatcher<Dimension>::_buildCellListToSend() const +ConnectivityDispatcher<Dimension>::_buildCellListToSend() { const auto& node_to_cell_matrix = m_connectivity.nodeToCellMatrix(); const auto& cell_to_node_matrix = m_connectivity.cellToNodeMatrix(); + const auto& cell_new_owner = this->_dispatchedInfo<ItemType::cell>().m_new_owner; + std::vector<std::vector<CellId>> cell_vector_to_send_by_proc(parallel::size()); Array<bool> send_to_rank(parallel::size()); for (CellId j=0; j<m_connectivity.numberOfCells(); ++j) { @@ -88,7 +69,7 @@ ConnectivityDispatcher<Dimension>::_buildCellListToSend() const const auto& node_to_cell = node_to_cell_matrix[r]; for (size_t K=0; K<node_to_cell.size(); ++K) { const CellId& k = node_to_cell[K]; - send_to_rank[m_cell_new_owner[k]] = true; + send_to_rank[cell_new_owner[k]] = true; } } @@ -111,16 +92,18 @@ ConnectivityDispatcher<Dimension>::_buildCellListToSend() const template <int Dimension> std::vector<Array<const NodeId>> ConnectivityDispatcher<Dimension>:: -_buildNodeListToSend() const +_buildNodeListToSend() { + const auto& cell_list_to_send_by_proc = this->_dispatchedInfo<ItemType::cell>().m_list_to_send_by_proc; + const auto& cell_to_node_matrix = m_connectivity.cellToNodeMatrix(); std::vector<Array<const NodeId>> node_list_to_send_by_proc(parallel::size()); for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) { Array<bool> tag(m_connectivity.numberOfNodes()); tag.fill(false); std::vector<NodeId> node_id_vector; - for (size_t j=0; j<m_cell_list_to_send_by_proc[i_rank].size(); ++j) { - const CellId& cell_id = m_cell_list_to_send_by_proc[i_rank][j]; + for (size_t j=0; j<cell_list_to_send_by_proc[i_rank].size(); ++j) { + const CellId& cell_id = cell_list_to_send_by_proc[i_rank][j]; const auto& cell_node_list = cell_to_node_matrix[cell_id]; for (size_t r=0; r<cell_node_list.size(); ++r) { const NodeId& node_id = cell_node_list[r]; @@ -139,65 +122,202 @@ template <int Dimension> Array<const unsigned int> ConnectivityDispatcher<Dimension>::_buildNbCellToSend() { + const auto& item_list_to_send_by_proc = this->_dispatchedInfo<ItemType::cell>().m_list_to_send_by_proc; Array<unsigned int> nb_cell_to_send_by_proc(parallel::size()); for (size_t i=0; i<parallel::size(); ++i) { - nb_cell_to_send_by_proc[i] = m_cell_list_to_send_by_proc[i].size(); + nb_cell_to_send_by_proc[i] = item_list_to_send_by_proc[i].size(); } return nb_cell_to_send_by_proc; } template <int Dimension> +template <typename CellValueType, + typename DataType> void -ConnectivityDispatcher<Dimension>::_dispatchFaces() +ConnectivityDispatcher<Dimension>::_gatherFrom(const CellValueType& data_to_gather, + std::vector<DataType>& gathered_vector) { - if constexpr (Dimension>1) { - std::vector<Array<const int>> recv_number_of_face_per_cell_by_proc = - [&] () { - CellValue<int> number_of_face_per_cell(m_connectivity); - const auto& cell_to_face_matrix = m_connectivity.cellToFaceMatrix(); - parallel_for(m_connectivity.numberOfCells(), PASTIS_LAMBDA(const CellId& j){ - number_of_face_per_cell[j] = cell_to_face_matrix[j].size(); - }); + static_assert(std::is_same_v<std::remove_const_t<typename CellValueType::data_type>, DataType>); - return this->exchange(number_of_face_per_cell); - } (); + std::vector<Array<const DataType>> recv_cell_data_by_proc = this->exchange(data_to_gather); - std::vector<Array<int>> recv_cell_face_number_by_proc(parallel::size()); - { - const auto& cell_to_face_matrix = m_connectivity.cellToFaceMatrix(); - const FaceValue<const int>& face_number = m_connectivity.faceNumber(); + auto& cell_number_id_map = this->_dispatchedInfo<ItemType::cell>().m_number_to_id_map; + gathered_vector.resize(cell_number_id_map.size()); + for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) { + for (size_t i=0; i<m_recv_cell_number_by_proc[i_rank].size(); ++i) { + int cell_number = m_recv_cell_number_by_proc[i_rank][i]; + const auto& searched_cell_id = cell_number_id_map.find(cell_number); + Assert(searched_cell_id != cell_number_id_map.end()); + gathered_vector[searched_cell_id->second] = recv_cell_data_by_proc[i_rank][i]; + } + } +} - std::vector<Array<int>> cell_face_number_to_send_by_proc(parallel::size()); - { +template <int Dimension> +std::unordered_map<int, int> +ConnectivityDispatcher<Dimension>::_buildCellNumberIdMap() +{ + std::unordered_map<int, int> cell_number_id_map; + for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) { + int cpt=0; + for (size_t i=0; i<m_recv_cell_number_by_proc[i_rank].size(); ++i) { + int cell_number = m_recv_cell_number_by_proc[i_rank][i]; + auto [iterator, inserted] = cell_number_id_map.insert(std::make_pair(cell_number, cpt)); + if (inserted) cpt++; + } + } + return cell_number_id_map; +} + +template <int Dimension> +template <typename SubItemOfItemT> +std::vector<Array<const int>> +ConnectivityDispatcher<Dimension>::_getRecvNumberOfSubItemPerItemByProc() +{ + const auto& item_to_sub_item_matrix + = m_connectivity.template getItemToItemMatrix<SubItemOfItemT::item_type, + SubItemOfItemT::sub_item_type>(); + + ItemValue<int, SubItemOfItemT::item_type> number_of_sub_item_per_item(m_connectivity); + + using ItemId = ItemIdT<SubItemOfItemT::item_type>; + parallel_for(number_of_sub_item_per_item.size(), PASTIS_LAMBDA(const ItemId& j){ + number_of_sub_item_per_item[j] = item_to_sub_item_matrix[j].size(); + }); + return this->exchange(number_of_sub_item_per_item); +} + +template <int Dimension> +template <typename SubItemOfItemT> +std::vector<Array<const int>> +ConnectivityDispatcher<Dimension>:: +_getRecvItemSubItemNumberingByProc(const std::vector<Array<const int>>& recv_number_of_sub_item_per_item_by_proc) +{ + std::vector<Array<const int>> item_sub_item_numbering_to_send_by_proc = + [&] () { + const auto& item_to_sub_item_matrix + = m_connectivity.template getItemToItemMatrix<SubItemOfItemT::item_type, + SubItemOfItemT::sub_item_type>(); + + const ItemValue<const int, SubItemOfItemT::sub_item_type>& sub_item_number = + m_connectivity.template number<SubItemOfItemT::sub_item_type>(); + + using ItemId = ItemIdT<SubItemOfItemT::item_type>; + using SubItemId = ItemIdT<SubItemOfItemT::sub_item_type>; + + std::vector<Array<const int>> item_sub_item_numbering_to_send_by_proc(parallel::size()); for (size_t i_rank=0; i_rank < parallel::size(); ++i_rank) { - std::vector<int> face_number_by_cell_vector; - for (size_t j=0; j<m_cell_list_to_send_by_proc[i_rank].size(); ++j) { - const CellId& cell_id = m_cell_list_to_send_by_proc[i_rank][j]; - const auto& cell_face_list = cell_to_face_matrix[cell_id]; - for (size_t r=0; r<cell_face_list.size(); ++r) { - const FaceId& face_id = cell_face_list[r]; - face_number_by_cell_vector.push_back(face_number[face_id]); + const auto& item_list_to_send_by_proc + = this->_dispatchedInfo<SubItemOfItemT::item_type>().m_list_to_send_by_proc; + + std::vector<int> sub_item_numbering_by_item_vector; + for (size_t j=0; j<item_list_to_send_by_proc[i_rank].size(); ++j) { + const ItemId& item_id = item_list_to_send_by_proc[i_rank][j]; + const auto& sub_item_list = item_to_sub_item_matrix[item_id]; + for (size_t r=0; r<sub_item_list.size(); ++r) { + const SubItemId& sub_item_id = sub_item_list[r]; + sub_item_numbering_by_item_vector.push_back(sub_item_number[sub_item_id]); } } - cell_face_number_to_send_by_proc[i_rank] = convert_to_array(face_number_by_cell_vector); + item_sub_item_numbering_to_send_by_proc[i_rank] = convert_to_array(sub_item_numbering_by_item_vector); } - } + return item_sub_item_numbering_to_send_by_proc; + } (); - for (size_t i_rank=0; i_rank < parallel::size(); ++i_rank) { - recv_cell_face_number_by_proc[i_rank] - = Array<int>(sum(recv_number_of_face_per_cell_by_proc[i_rank])); - } + std::vector<Array<int>> recv_item_sub_item_numbering_by_proc(parallel::size()); + for (size_t i_rank=0; i_rank < parallel::size(); ++i_rank) { + recv_item_sub_item_numbering_by_proc[i_rank] + = Array<int>(sum(recv_number_of_sub_item_per_item_by_proc[i_rank])); + } + parallel::exchange(item_sub_item_numbering_to_send_by_proc, recv_item_sub_item_numbering_by_proc); + + std::vector<Array<const int>> const_recv_item_sub_item_numbering_by_proc(parallel::size()); + for (size_t i_rank=0; i_rank < parallel::size(); ++i_rank) { + const_recv_item_sub_item_numbering_by_proc[i_rank] = recv_item_sub_item_numbering_by_proc[i_rank]; + } + return const_recv_item_sub_item_numbering_by_proc; +} - parallel::exchange(cell_face_number_to_send_by_proc, recv_cell_face_number_by_proc); +template <int Dimension> +std::unordered_map<int, int> +ConnectivityDispatcher<Dimension>:: +_buildNodeNumberIdMap(const std::vector<Array<const int>>& recv_cell_node_number_by_proc) +{ + std::unordered_map<int, int> node_number_id_map; + for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) { + int node_id=0; + for (size_t i=0; i<recv_cell_node_number_by_proc[i_rank].size(); ++i) { + int node_number = recv_cell_node_number_by_proc[i_rank][i]; + auto [iterator, inserted] = node_number_id_map.insert(std::make_pair(node_number, node_id)); + if (inserted) node_id++; } + } + return node_number_id_map; +} + + +template <int Dimension> +template <ItemType item_type> +void +ConnectivityDispatcher<Dimension>:: +_buildRecvItemIdCorrespondanceByProc() +{ + const auto& item_list_to_send_by_proc = this->_dispatchedInfo<item_type>().m_list_to_send_by_proc; + using ItemId = ItemIdT<item_type>; + + std::vector<Array<const ItemId>> recv_item_id_correspondance_by_proc(parallel::size()); + const ItemValue<const int,item_type>& item_number = + m_connectivity.template number<item_type>(); + + std::vector<Array<const int>> send_item_number_by_proc(parallel::size()); + for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) { + Array<int> send_item_number(item_list_to_send_by_proc[i_rank].size()); + const Array<const ItemId> send_item_id = item_list_to_send_by_proc[i_rank]; + parallel_for(send_item_number.size(), PASTIS_LAMBDA(const size_t& j){ + send_item_number[j] = item_number[send_item_id[j]]; + }); + send_item_number_by_proc[i_rank] = send_item_number; + } + + const auto& item_list_to_recv_size_by_proc = this->_dispatchedInfo<item_type>().m_list_to_recv_size_by_proc; + std::vector<Array<int>> recv_item_number_by_proc(parallel::size()); + for (size_t i_rank=0; i_rank < parallel::size(); ++i_rank) { + recv_item_number_by_proc[i_rank] = Array<int>(item_list_to_recv_size_by_proc[i_rank]); + } + parallel::exchange(send_item_number_by_proc, recv_item_number_by_proc); + + const auto& item_number_to_id_map = this->_dispatchedInfo<item_type>().m_number_to_id_map; + for (size_t i_rank=0; i_rank<item_list_to_recv_size_by_proc.size(); ++i_rank) { + Array<ItemId> item_id_correspondance(item_list_to_recv_size_by_proc[i_rank]); + for (size_t l=0; l<item_list_to_recv_size_by_proc[i_rank]; ++l) { + const int& item_number = recv_item_number_by_proc[i_rank][l]; + const auto& searched_item_id = item_number_to_id_map.find(item_number); + Assert(searched_item_id != item_number_to_id_map.end()); + item_id_correspondance[l] = searched_item_id->second; + } + recv_item_id_correspondance_by_proc[i_rank] = item_id_correspondance; + } + this->_dispatchedInfo<item_type>().m_recv_id_correspondance_by_proc = recv_item_id_correspondance_by_proc; +} + +template <int Dimension> +void +ConnectivityDispatcher<Dimension>::_dispatchFaces() +{ + if constexpr (Dimension>1) { + std::vector<Array<const int>> recv_number_of_face_per_cell_by_proc = + _getRecvNumberOfSubItemPerItemByProc<SubFaceOfCell>(); + + std::vector<Array<const int>> recv_cell_face_numbering_by_proc + = this->_getRecvItemSubItemNumberingByProc<SubFaceOfCell>(recv_number_of_face_per_cell_by_proc); const std::unordered_map<int, int> face_number_id_map = [&] () { std::unordered_map<int, int> face_number_id_map; for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) { int cpt=0; - for (size_t i=0; i<recv_cell_face_number_by_proc[i_rank].size(); ++i) { - int face_number = recv_cell_face_number_by_proc[i_rank][i]; + for (size_t i=0; i<recv_cell_face_numbering_by_proc[i_rank].size(); ++i) { + int face_number = recv_cell_face_numbering_by_proc[i_rank][i]; auto [iterator, inserted] = face_number_id_map.insert(std::make_pair(face_number, cpt)); if (inserted) cpt++; } @@ -211,27 +331,34 @@ ConnectivityDispatcher<Dimension>::_dispatchFaces() m_new_descriptor.face_number_vector[id] = number; } - for (size_t i_rank=0; i_rank < parallel::size(); ++i_rank) { - int l=0; - for (size_t i=0; i<m_nb_cell_to_recv_by_proc[i_rank]; ++i) { - std::vector<unsigned int> face_vector; - for (int k=0; k<recv_number_of_face_per_cell_by_proc[i_rank][i]; ++k) { - const auto& searched_face_id = face_number_id_map.find(recv_cell_face_number_by_proc[i_rank][l++]); - Assert(searched_face_id != face_number_id_map.end()); - face_vector.push_back(searched_face_id->second); + { + const auto& cell_list_to_recv_size_by_proc = + this->_dispatchedInfo<ItemType::cell>().m_list_to_recv_size_by_proc; + + for (size_t i_rank=0; i_rank < parallel::size(); ++i_rank) { + int l=0; + for (size_t i=0; i<cell_list_to_recv_size_by_proc[i_rank]; ++i) { + std::vector<unsigned int> face_vector; + for (int k=0; k<recv_number_of_face_per_cell_by_proc[i_rank][i]; ++k) { + const auto& searched_face_id = face_number_id_map.find(recv_cell_face_numbering_by_proc[i_rank][l++]); + Assert(searched_face_id != face_number_id_map.end()); + face_vector.push_back(searched_face_id->second); + } + m_new_descriptor.cell_to_face_vector.emplace_back(face_vector); } - m_new_descriptor.cell_to_face_vector.emplace_back(face_vector); } } { std::vector<Array<bool>> cell_face_is_reversed_to_send_by_proc(parallel::size()); { + const auto& cell_list_to_send_by_proc = this->_dispatchedInfo<ItemType::cell>().m_list_to_send_by_proc; + const auto& cell_face_is_reversed = m_connectivity.cellFaceIsReversed(); for (size_t i_rank=0; i_rank < parallel::size(); ++i_rank) { std::vector<bool> face_is_reversed_by_cell_vector; - for (size_t j=0; j<m_cell_list_to_send_by_proc[i_rank].size(); ++j) { - const CellId& cell_id = m_cell_list_to_send_by_proc[i_rank][j]; + for (size_t j=0; j<cell_list_to_send_by_proc[i_rank].size(); ++j) { + const CellId& cell_id = cell_list_to_send_by_proc[i_rank][j]; const auto& face_is_reversed = cell_face_is_reversed.itemValues(cell_id); for (size_t L=0; L<face_is_reversed.size(); ++L) { face_is_reversed_by_cell_vector.push_back(face_is_reversed[L]); @@ -249,9 +376,12 @@ ConnectivityDispatcher<Dimension>::_dispatchFaces() parallel::exchange(cell_face_is_reversed_to_send_by_proc, recv_cell_face_is_reversed_by_proc); + const auto& cell_list_to_recv_size_by_proc = + this->_dispatchedInfo<ItemType::cell>().m_list_to_recv_size_by_proc; + for (size_t i_rank=0; i_rank < parallel::size(); ++i_rank) { int l=0; - for (size_t i=0; i<m_nb_cell_to_recv_by_proc[i_rank]; ++i) { + for (size_t i=0; i<cell_list_to_recv_size_by_proc[i_rank]; ++i) { std::vector<bool> face_is_reversed_vector; for (int k=0; k<recv_number_of_face_per_cell_by_proc[i_rank][i]; ++k) { face_is_reversed_vector.push_back(recv_cell_face_is_reversed_by_proc[i_rank][l++]); @@ -264,13 +394,14 @@ ConnectivityDispatcher<Dimension>::_dispatchFaces() std::vector<Array<const FaceId>> send_face_id_by_proc(parallel::size()); { const auto& cell_to_face_matrix = m_connectivity.cellToFaceMatrix(); + const auto& cell_list_to_send_by_proc = this->_dispatchedInfo<ItemType::cell>().m_list_to_send_by_proc; for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) { Array<bool> tag(m_connectivity.numberOfFaces()); tag.fill(false); std::vector<FaceId> face_id_vector; - for (size_t j=0; j<m_cell_list_to_send_by_proc[i_rank].size(); ++j) { - const CellId& cell_id = m_cell_list_to_send_by_proc[i_rank][j]; + for (size_t j=0; j<cell_list_to_send_by_proc[i_rank].size(); ++j) { + const CellId& cell_id = cell_list_to_send_by_proc[i_rank][j]; const auto& cell_face_list = cell_to_face_matrix[cell_id]; for (size_t l=0; l<cell_face_list.size(); ++l) { const FaceId& face_id = cell_face_list[l]; @@ -329,13 +460,14 @@ ConnectivityDispatcher<Dimension>::_dispatchFaces() { + const auto& face_new_owner = this->_dispatchedInfo<ItemType::face>().m_new_owner; std::vector<Array<const int>> send_face_owner_by_proc(parallel::size()); for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) { Array<int> send_face_owner(nb_face_to_send_by_proc[i_rank]); const Array<const FaceId> send_face_id = send_face_id_by_proc[i_rank]; parallel_for(send_face_id.size(), PASTIS_LAMBDA(const size_t& l) { const FaceId& face_id = send_face_id[l]; - send_face_owner[l] = m_face_new_owner[face_id]; + send_face_owner[l] = face_new_owner[face_id]; }); send_face_owner_by_proc[i_rank] = send_face_owner; } @@ -407,13 +539,14 @@ ConnectivityDispatcher<Dimension>::_dispatchFaces() parallel::exchange(face_node_number_to_send_by_proc, recv_face_node_number_by_proc); + const auto& node_number_id_map = this->_dispatchedInfo<ItemType::node>().m_number_to_id_map; for (size_t i_rank=0; i_rank < parallel::size(); ++i_rank) { int l=0; for (size_t i=0; i<recv_face_number_by_proc[i_rank].size(); ++i) { std::vector<unsigned int> node_vector; for (int k=0; k<recv_face_number_of_node_by_proc[i_rank][i]; ++k) { - const auto& searched_node_id = m_node_number_id_map.find(recv_face_node_number_by_proc[i_rank][l++]); - Assert(searched_node_id != m_node_number_id_map.end()); + const auto& searched_node_id = node_number_id_map.find(recv_face_node_number_by_proc[i_rank][l++]); + Assert(searched_node_id != node_number_id_map.end()); node_vector.push_back(searched_node_id->second); } m_new_descriptor.face_to_node_vector.emplace_back(node_vector); @@ -580,207 +713,81 @@ ConnectivityDispatcher<Dimension>::_dispatchFaces() template <int Dimension> -template <typename CellValueType, - typename DataType> -void -ConnectivityDispatcher<Dimension>::_gatherFrom(const CellValueType& data_to_gather, - std::vector<DataType>& gathered_vector) -{ - static_assert(std::is_same_v<std::remove_const_t<typename CellValueType::data_type>, DataType>); - - std::vector<Array<const DataType>> recv_cell_data_by_proc = this->exchange(data_to_gather); - - gathered_vector.resize(m_cell_number_id_map.size()); - for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) { - for (size_t i=0; i<m_recv_cell_number_by_proc[i_rank].size(); ++i) { - int cell_number = m_recv_cell_number_by_proc[i_rank][i]; - const auto& searched_cell_id = m_cell_number_id_map.find(cell_number); - Assert(searched_cell_id != m_cell_number_id_map.end()); - gathered_vector[searched_cell_id->second] = recv_cell_data_by_proc[i_rank][i]; - } - } -} - -template <int Dimension> -std::unordered_map<int, int> -ConnectivityDispatcher<Dimension>::_buildCellNumberIdMap() -{ - std::unordered_map<int, int> cell_number_id_map; - for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) { - int cpt=0; - for (size_t i=0; i<m_recv_cell_number_by_proc[i_rank].size(); ++i) { - int cell_number = m_recv_cell_number_by_proc[i_rank][i]; - auto [iterator, inserted] = cell_number_id_map.insert(std::make_pair(cell_number, cpt)); - if (inserted) cpt++; - } - } - return cell_number_id_map; -} - -template <int Dimension> -std::vector<Array<const int>> -ConnectivityDispatcher<Dimension>::_getRecvNumberOfNodePerCellByProc() const -{ - const auto& cell_to_node_matrix = m_connectivity.cellToNodeMatrix(); - CellValue<int> number_of_node_per_cell(m_connectivity); - parallel_for(m_connectivity.numberOfCells(), PASTIS_LAMBDA(const CellId& j){ - number_of_node_per_cell[j] = cell_to_node_matrix[j].size(); - }); - return this->exchange(number_of_node_per_cell); -} - -template <int Dimension> -std::vector<Array<const int>> -ConnectivityDispatcher<Dimension>:: -_getRecvCellNodeNumberByProc(const std::vector<Array<const int>>& recv_number_of_node_per_cell_by_proc) const -{ - std::vector<Array<const int>> cell_node_number_to_send_by_proc = - [&] () { - const auto& cell_to_node_matrix = m_connectivity.cellToNodeMatrix(); - const NodeValue<const int>& node_number = m_connectivity.nodeNumber(); - std::vector<Array<const int>> cell_node_number_to_send_by_proc(parallel::size()); - for (size_t i_rank=0; i_rank < parallel::size(); ++i_rank) { - std::vector<int> node_number_by_cell_vector; - for (size_t j=0; j<m_cell_list_to_send_by_proc[i_rank].size(); ++j) { - const CellId& cell_id = m_cell_list_to_send_by_proc[i_rank][j]; - const auto& cell_node_list = cell_to_node_matrix[cell_id]; - for (size_t r=0; r<cell_node_list.size(); ++r) { - const NodeId& node_id = cell_node_list[r]; - node_number_by_cell_vector.push_back(node_number[node_id]); - } - } - cell_node_number_to_send_by_proc[i_rank] = convert_to_array(node_number_by_cell_vector); - } - return cell_node_number_to_send_by_proc; - } (); - - std::vector<Array<int>> recv_cell_node_number_by_proc(parallel::size()); - for (size_t i_rank=0; i_rank < parallel::size(); ++i_rank) { - recv_cell_node_number_by_proc[i_rank] - = Array<int>(sum(recv_number_of_node_per_cell_by_proc[i_rank])); - } - parallel::exchange(cell_node_number_to_send_by_proc, recv_cell_node_number_by_proc); - - std::vector<Array<const int>> const_recv_cell_node_number_by_proc(parallel::size()); - for (size_t i_rank=0; i_rank < parallel::size(); ++i_rank) { - const_recv_cell_node_number_by_proc[i_rank] = recv_cell_node_number_by_proc[i_rank]; - } - return const_recv_cell_node_number_by_proc; -} - -template <int Dimension> -std::unordered_map<int, int> -ConnectivityDispatcher<Dimension>:: -_buildNodeNumberIdMap(const std::vector<Array<const int>>& recv_cell_node_number_by_proc) +ConnectivityDispatcher<Dimension>::ConnectivityDispatcher(const ConnectivityType& connectivity) + : m_connectivity(connectivity) { - std::unordered_map<int, int> node_number_id_map; - for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) { - int node_id=0; - for (size_t i=0; i<recv_cell_node_number_by_proc[i_rank].size(); ++i) { - int node_number = recv_cell_node_number_by_proc[i_rank][i]; - auto [iterator, inserted] = node_number_id_map.insert(std::make_pair(node_number, node_id)); - if (inserted) node_id++; - } - } - return node_number_id_map; -} + this->_buildNewOwner<ItemType::cell>(); + this->_buildNewOwner<ItemType::face>(); + // this->_buildNewOwner<ItemType::edge>(); + this->_buildNewOwner<ItemType::node>(); -template <int Dimension> -std::vector<Array<const NodeId>> -ConnectivityDispatcher<Dimension>:: -_buildRecvNodeIdCorrespondanceByProc() const -{ - std::vector<Array<const NodeId>> recv_node_id_correspondance_by_proc(parallel::size()); - const NodeValue<const int>& node_number = m_connectivity.nodeNumber(); - std::vector<Array<const int>> send_node_number_by_proc(parallel::size()); - for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) { - Array<int> send_node_number(m_node_list_to_send_by_proc[i_rank].size()); - const Array<const NodeId> send_node_id = m_node_list_to_send_by_proc[i_rank]; - parallel_for(send_node_number.size(), PASTIS_LAMBDA(const size_t& j){ - send_node_number[j] = node_number[send_node_id[j]]; - }); - send_node_number_by_proc[i_rank] = send_node_number; - } + m_dispatched_cell_info.m_list_to_send_by_proc = this->_buildCellListToSend(); + this->_dispatchedInfo<ItemType::cell>().m_list_to_recv_size_by_proc + = parallel::allToAll(this->_buildNbCellToSend()); - std::vector<Array<int>> recv_node_number_by_proc(parallel::size()); - for (size_t i_rank=0; i_rank < parallel::size(); ++i_rank) { - recv_node_number_by_proc[i_rank] = Array<int>(m_nb_node_to_recv_by_proc[i_rank]); - } - parallel::exchange(send_node_number_by_proc, recv_node_number_by_proc); - - for (size_t i_rank=0; i_rank<m_nb_node_to_recv_by_proc.size(); ++i_rank) { - Array<NodeId> node_id_correspondace(m_nb_node_to_recv_by_proc[i_rank]); - for (size_t l=0; l<m_nb_node_to_recv_by_proc[i_rank]; ++l) { - const int& node_number = recv_node_number_by_proc[i_rank][l]; - const auto& searched_node_id = m_node_number_id_map.find(node_number); - Assert(searched_node_id != m_node_number_id_map.end()); - node_id_correspondace[l] = searched_node_id->second; - } - recv_node_id_correspondance_by_proc[i_rank] = node_id_correspondace; - } - return recv_node_id_correspondance_by_proc; -} + m_recv_cell_number_by_proc = this->exchange(m_connectivity.cellNumber()); + this->_dispatchedInfo<ItemType::cell>().m_number_to_id_map + = this->_buildCellNumberIdMap(); -template <int Dimension> -ConnectivityDispatcher<Dimension>::ConnectivityDispatcher(const ConnectivityType& connectivity) - : m_connectivity(connectivity), - m_cell_new_owner(this->_getCellNewOwner()), - m_face_new_owner(this->_getFaceNewOwner()), - m_node_new_owner(this->_getNodeNewOwner()), - m_cell_list_to_send_by_proc(this->_buildCellListToSend()), - m_nb_cell_to_recv_by_proc(parallel::allToAll(this->_buildNbCellToSend())), - m_recv_cell_number_by_proc(this->exchange(m_connectivity.cellNumber())), - m_cell_number_id_map(this->_buildCellNumberIdMap()) -{ const std::vector<Array<const int>> recv_number_of_node_per_cell_by_proc - = this->_getRecvNumberOfNodePerCellByProc(); + = this->_getRecvNumberOfSubItemPerItemByProc<SubNodeOfCell>(); - const std::vector<Array<const int>> recv_cell_node_number_by_proc = - this->_getRecvCellNodeNumberByProc(recv_number_of_node_per_cell_by_proc); + const std::vector<Array<const int>> recv_cell_node_numbering_by_proc + = this->_getRecvItemSubItemNumberingByProc<SubNodeOfCell>(recv_number_of_node_per_cell_by_proc); - this->_buildNodeNumberIdMap(recv_cell_node_number_by_proc); - m_node_number_id_map = _buildNodeNumberIdMap(recv_cell_node_number_by_proc); + this->_buildNodeNumberIdMap(recv_cell_node_numbering_by_proc); + this->_dispatchedInfo<ItemType::node>().m_number_to_id_map + = this->_buildNodeNumberIdMap(recv_cell_node_numbering_by_proc); - m_new_descriptor.cell_number_vector.resize(m_cell_number_id_map.size()); - for (const auto& [number, id] : m_cell_number_id_map) { - m_new_descriptor.cell_number_vector[id] = number; + { + const auto& cell_number_id_map = this->_dispatchedInfo<ItemType::cell>().m_number_to_id_map; + m_new_descriptor.cell_number_vector.resize(cell_number_id_map.size()); + for (const auto& [number, id] : cell_number_id_map) { + m_new_descriptor.cell_number_vector[id] = number; + } } - m_node_list_to_send_by_proc = this->_buildNodeListToSend(); + m_dispatched_node_info.m_list_to_send_by_proc = this->_buildNodeListToSend(); Array<unsigned int> nb_node_to_send_by_proc(parallel::size()); for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) { - nb_node_to_send_by_proc[i_rank] = m_node_list_to_send_by_proc[i_rank].size(); + nb_node_to_send_by_proc[i_rank] = m_dispatched_node_info.m_list_to_send_by_proc[i_rank].size(); } - m_nb_node_to_recv_by_proc = parallel::allToAll(nb_node_to_send_by_proc); + this->_dispatchedInfo<ItemType::node>().m_list_to_recv_size_by_proc + = parallel::allToAll(nb_node_to_send_by_proc); - m_recv_node_id_correspondance_by_proc = this->_buildRecvNodeIdCorrespondanceByProc(); + this->_buildRecvItemIdCorrespondanceByProc<ItemType::node>(); // Fill new descriptor this->_gatherFrom(m_connectivity.cellType(), m_new_descriptor.cell_type_vector); - this->_gatherFrom(m_cell_new_owner, m_new_descriptor.cell_owner_vector); + this->_gatherFrom(this->_dispatchedInfo<ItemType::cell>().m_new_owner, m_new_descriptor.cell_owner_vector); - m_new_descriptor.node_number_vector.resize(m_node_number_id_map.size()); - for (const auto& [number, id] : m_node_number_id_map) { - m_new_descriptor.node_number_vector[id] = number; + { + const auto& node_number_id_map = this->_dispatchedInfo<ItemType::node>().m_number_to_id_map; + m_new_descriptor.node_number_vector.resize(node_number_id_map.size()); + for (const auto& [number, id] : node_number_id_map) { + m_new_descriptor.node_number_vector[id] = number; + } } { + const auto& node_new_owner = this->_dispatchedInfo<ItemType::node>().m_new_owner; std::vector<Array<const int>> send_node_owner_by_proc(parallel::size()); for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) { Array<int> send_node_owner(nb_node_to_send_by_proc[i_rank]); - const Array<const NodeId> send_node_id = m_node_list_to_send_by_proc[i_rank]; + const Array<const NodeId> send_node_id = m_dispatched_node_info.m_list_to_send_by_proc[i_rank]; parallel_for(send_node_id.size(), PASTIS_LAMBDA(const size_t& r) { const NodeId& node_id = send_node_id[r]; - send_node_owner[r] = m_node_new_owner[node_id]; + send_node_owner[r] = node_new_owner[node_id]; }); send_node_owner_by_proc[i_rank] = send_node_owner; } + const auto& node_list_to_recv_size_by_proc = this->_dispatchedInfo<ItemType::node>().m_list_to_recv_size_by_proc; #warning use a _gatherFrom-like function std::vector<Array<int>> recv_node_owner_by_proc(parallel::size()); for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) { - recv_node_owner_by_proc[i_rank] = Array<int>(m_nb_node_to_recv_by_proc[i_rank]); + recv_node_owner_by_proc[i_rank] = Array<int>(node_list_to_recv_size_by_proc[i_rank]); } parallel::exchange(send_node_owner_by_proc, recv_node_owner_by_proc); @@ -793,20 +800,24 @@ ConnectivityDispatcher<Dimension>::ConnectivityDispatcher(const ConnectivityType } } - for (size_t i_rank=0; i_rank < parallel::size(); ++i_rank) { - int l=0; - for (size_t i=0; i<m_nb_cell_to_recv_by_proc[i_rank]; ++i) { - std::vector<unsigned int> node_vector; - for (int k=0; k<recv_number_of_node_per_cell_by_proc[i_rank][i]; ++k) { - const auto& searched_node_id = m_node_number_id_map.find(recv_cell_node_number_by_proc[i_rank][l++]); - Assert(searched_node_id != m_node_number_id_map.end()); - node_vector.push_back(searched_node_id->second); + { + const auto& cell_list_to_recv_size_by_proc = + this->_dispatchedInfo<ItemType::cell>().m_list_to_recv_size_by_proc; + + const auto& node_number_id_map = this->_dispatchedInfo<ItemType::node>().m_number_to_id_map; + for (size_t i_rank=0; i_rank < parallel::size(); ++i_rank) { + int l=0; + for (size_t i=0; i<cell_list_to_recv_size_by_proc[i_rank]; ++i) { + std::vector<unsigned int> node_vector; + for (int k=0; k<recv_number_of_node_per_cell_by_proc[i_rank][i]; ++k) { + const auto& searched_node_id = node_number_id_map.find(recv_cell_node_numbering_by_proc[i_rank][l++]); + Assert(searched_node_id != node_number_id_map.end()); + node_vector.push_back(searched_node_id->second); + } + m_new_descriptor.cell_by_node_vector.emplace_back(node_vector); } - m_new_descriptor.cell_by_node_vector.emplace_back(node_vector); } } - - this->_dispatchFaces(); m_dispatched_connectivity = ConnectivityType::build(m_new_descriptor); diff --git a/src/mesh/ConnectivityDispatcher.hpp b/src/mesh/ConnectivityDispatcher.hpp index 00d10bdad..c68e3f857 100644 --- a/src/mesh/ConnectivityDispatcher.hpp +++ b/src/mesh/ConnectivityDispatcher.hpp @@ -15,41 +15,70 @@ class ConnectivityDispatcher private: const ConnectivityType& m_connectivity; - ConnectivityDescriptor m_new_descriptor; - std::shared_ptr<ConnectivityType> m_dispatched_connectivity; - const CellValue<const int> m_cell_new_owner; - const FaceValue<const int> m_face_new_owner; - const NodeValue<const int> m_node_new_owner; - - const std::vector<Array<const CellId>> m_cell_list_to_send_by_proc; -#warning use a const sementic too - std::vector<Array<const NodeId>> m_node_list_to_send_by_proc; - - const Array<const unsigned int> m_nb_cell_to_recv_by_proc; - const std::vector<Array<const int>> m_recv_cell_number_by_proc; - const std::unordered_map<int, int> m_cell_number_id_map; - - Array<const unsigned int> m_nb_node_to_recv_by_proc; + template <ItemType item_type> + struct DispatchedItemInfo + { + using ItemId = ItemIdT<item_type>; + ItemValue<const int, item_type> m_new_owner; + std::vector<Array<const ItemId>> m_list_to_send_by_proc; +#warning is m_list_to_recv_size_by_proc really necessary? + 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; + } + } - std::unordered_map<int, int> m_node_number_id_map; + 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; + } + } - std::vector<Array<const NodeId>> m_recv_node_id_correspondance_by_proc; + std::vector<Array<const int>> m_recv_cell_number_by_proc; + std::vector<Array<const NodeId>>& m_recv_node_id_correspondance_by_proc = + m_dispatched_node_info.m_recv_id_correspondance_by_proc; - CellValue<int> _getCellNewOwner(); - FaceValue<int> _getFaceNewOwner(); - NodeValue<int> _getNodeNewOwner(); + template <ItemType item_type> + void _buildNewOwner(); - std::vector<Array<const CellId>> _buildCellListToSend() const; + std::vector<Array<const CellId>> _buildCellListToSend(); - std::vector<Array<const NodeId>> _buildNodeListToSend() const; + std::vector<Array<const NodeId>> _buildNodeListToSend(); Array<const unsigned int> _buildNbCellToSend(); - std::unordered_map<int, int> - _buildCellNumberIdMap(); + std::unordered_map<int, int> _buildCellNumberIdMap(); std::unordered_map<int, int> _buildNodeNumberIdMap(const std::vector<Array<const int>>& recv_cell_node_number_by_proc); @@ -61,14 +90,16 @@ class ConnectivityDispatcher void _gatherFrom(const CellValueType& data_to_gather, std::vector<DataType>& gathered_vector); + template <typename SubItemOfItemT> std::vector<Array<const int>> - _getRecvNumberOfNodePerCellByProc() const; + _getRecvNumberOfSubItemPerItemByProc(); + template <typename SubItemOfItemT> std::vector<Array<const int>> - _getRecvCellNodeNumberByProc(const std::vector<Array<const int>>& recv_number_of_node_per_cell_by_proc) const; + _getRecvItemSubItemNumberingByProc(const std::vector<Array<const int>>& recv_number_of_sub_item_per_item_by_proc); - std::vector<Array<const NodeId>> - _buildRecvNodeIdCorrespondanceByProc() const; + template <ItemType item_type> + void _buildRecvItemIdCorrespondanceByProc(); public: std::shared_ptr<const ConnectivityType> @@ -77,32 +108,17 @@ class ConnectivityDispatcher return m_dispatched_connectivity; } - PASTIS_INLINE - const CellValue<const int>& cellNewOwner() const - { - return m_cell_new_owner; - } - - PASTIS_INLINE - const FaceValue<const int>& faceNewOwner() const - { - return m_face_new_owner; - } - - PASTIS_INLINE - const NodeValue<const int>& nodeNewOwner() const - { - return m_node_new_owner; - } - template<typename DataType, typename ConnectivityPtr> std::vector<Array<const DataType>> exchange(ItemValue<DataType, ItemType::cell, ConnectivityPtr> cell_value) const { using MutableDataType = std::remove_const_t<DataType>; std::vector<Array<const DataType>> cell_value_to_send_by_proc(parallel::size()); + + const auto& item_list_to_send_by_proc = this->_dispatchedInfo<ItemType::cell>().m_list_to_send_by_proc; + for (size_t i=0; i<parallel::size(); ++i) { - const Array<const CellId>& cell_list = m_cell_list_to_send_by_proc[i]; + const Array<const CellId>& cell_list = item_list_to_send_by_proc[i]; Array<MutableDataType> cell_value_list(cell_list.size()); parallel_for (cell_list.size(), PASTIS_LAMBDA(const CellId& cell_id) { cell_value_list[cell_id] = cell_value[cell_list[cell_id]]; @@ -111,10 +127,12 @@ class ConnectivityDispatcher } std::vector<Array<MutableDataType>> recv_cell_value_by_proc(parallel::size()); - for (size_t i=0; i<parallel::size(); ++i) { - recv_cell_value_by_proc[i] = Array<MutableDataType>(m_nb_cell_to_recv_by_proc[i]); + { + const auto& list_to_recv_size_by_proc = this->_dispatchedInfo<ItemType::cell>().m_list_to_recv_size_by_proc; + for (size_t i=0; i<parallel::size(); ++i) { + recv_cell_value_by_proc[i] = Array<MutableDataType>(list_to_recv_size_by_proc[i]); + } } - parallel::exchange(cell_value_to_send_by_proc, recv_cell_value_by_proc); std::vector<Array<const DataType>> const_recv_cell_value_by_proc(parallel::size()); @@ -125,39 +143,48 @@ class ConnectivityDispatcher return const_recv_cell_value_by_proc; } -#warning Should write this function generically w.r. to the item type - template<typename DataType, typename ConnectivityPtr> - ItemValue<std::remove_const_t<DataType>, ItemType::node, ConnectivityPtr> - dispatch(ItemValue<DataType, ItemType::node, ConnectivityPtr> node_value) const + 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>> node_value_to_send_by_proc(parallel::size()); + std::vector<Array<DataType>> item_value_to_send_by_proc(parallel::size()); for (size_t i=0; i<parallel::size(); ++i) { - const Array<const NodeId>& node_list = m_node_list_to_send_by_proc[i]; - Array<MutableDataType> node_value_list(node_list.size()); - parallel_for (node_list.size(), PASTIS_LAMBDA(const NodeId& node_id) { - node_value_list[node_id] = node_value[node_list[node_id]]; + 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]]; }); - node_value_to_send_by_proc[i] = node_value_list; + item_value_to_send_by_proc[i] = item_value_list; } - std::vector<Array<MutableDataType>> recv_node_value_by_proc(parallel::size()); + 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_node_value_by_proc[i] = Array<MutableDataType>(m_nb_node_to_recv_by_proc[i]); + recv_item_value_by_proc[i] = Array<MutableDataType>(item_list_to_recv_size_by_proc[i]); } - parallel::exchange(node_value_to_send_by_proc, recv_node_value_by_proc); + parallel::exchange(item_value_to_send_by_proc, recv_item_value_by_proc); - NodeValue<MutableDataType> new_node_value(*m_dispatched_connectivity); + 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) { - for (size_t r=0; r<recv_node_value_by_proc[i_rank].size(); ++r) { - const NodeId& node_id = m_recv_node_id_correspondance_by_proc[i_rank][r]; - new_node_value[node_id] = recv_node_value_by_proc[i_rank][r]; - } + 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_node_value; + return new_item_value; } ConnectivityDispatcher(const ConnectivityType& mesh); diff --git a/src/mesh/SubItemOfItemType.hpp b/src/mesh/SubItemOfItemType.hpp new file mode 100644 index 000000000..dbf382559 --- /dev/null +++ b/src/mesh/SubItemOfItemType.hpp @@ -0,0 +1,32 @@ +#ifndef SUB_ITEM_OF_ITEM_TYPE_HPP +#define SUB_ITEM_OF_ITEM_TYPE_HPP + +#include <ItemType.hpp> + +template <ItemType sub_item_t, + ItemType item_t> +struct SubItemOfItemType +{ + static_assert(sub_item_t != item_t, "item and its sub-item cannot be of same type"); + + constexpr static ItemType sub_item_type = sub_item_t; + constexpr static ItemType item_type = item_t; +}; + +using SubFaceOfCell = SubItemOfItemType<ItemType::face, ItemType::cell>; +using SubEdgeOfCell = SubItemOfItemType<ItemType::edge, ItemType::cell>; +using SubNodeOfCell = SubItemOfItemType<ItemType::node, ItemType::cell>; + +using SubCellofFace = SubItemOfItemType<ItemType::cell, ItemType::face>; +using SubEdgeOfFace = SubItemOfItemType<ItemType::edge, ItemType::face>; +using SubNodeOfFace = SubItemOfItemType<ItemType::node, ItemType::face>; + +using SubCellofEdge = SubItemOfItemType<ItemType::cell, ItemType::edge>; +using SubFaceOfEdge = SubItemOfItemType<ItemType::face, ItemType::edge>; +using SubNodeOfEdge = SubItemOfItemType<ItemType::node, ItemType::edge>; + +using SubCellofNode = SubItemOfItemType<ItemType::cell, ItemType::node>; +using SubFaceOfNode = SubItemOfItemType<ItemType::face, ItemType::node>; +using SubEdgeOfNode = SubItemOfItemType<ItemType::edge, ItemType::node>; + +#endif // SUB_ITEM_OF_ITEM_TYPE_HPP -- GitLab