#include <ConnectivityDispatcher.hpp> #include <Partitioner.hpp> #include <ItemOfItemType.hpp> #include <unordered_map> template <int Dimension> template <ItemType item_type> void ConnectivityDispatcher<Dimension>::_buildNewOwner() { 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); 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>(); const auto& cell_number = m_connectivity.cellNumber(); const auto& cell_new_owner = this->_dispatchedInfo<ItemType::cell>().m_new_owner; 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<item_to_cell.size(); ++j) { const CellId J = item_to_cell[j]; if (cell_number[J] < cell_number[Jmin]) { Jmin=J; } } item_new_owner[l] = cell_new_owner[Jmin]; }); #warning Add missing synchronize (fix it!) // synchronize(face_new_owner); this->_dispatchedInfo<item_type>().m_new_owner = item_new_owner; } } template <int Dimension> template <ItemType item_type> void ConnectivityDispatcher<Dimension>::_buildItemListToSend() { if constexpr (item_type == ItemType::cell) { 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) { send_to_rank.fill(false); const auto& cell_to_node = cell_to_node_matrix[j]; for (size_t R=0; R<cell_to_node.size(); ++R) { const NodeId& r = cell_to_node[R]; 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[cell_new_owner[k]] = true; } } for (size_t k=0; k<send_to_rank.size(); ++k) { if (send_to_rank[k]) { cell_vector_to_send_by_proc[k].push_back(j); } } } auto& cell_list_to_send_by_proc = this->_dispatchedInfo<ItemType::cell>().m_list_to_send_by_proc; cell_list_to_send_by_proc.resize(parallel::size()); for (size_t i=0; i<parallel::size(); ++i) { cell_list_to_send_by_proc[i] = convert_to_array(cell_vector_to_send_by_proc[i]); } } else { const auto& cell_list_to_send_by_proc = this->_dispatchedInfo<ItemType::cell>().m_list_to_send_by_proc; using ItemId = ItemIdT<item_type>; const auto& cell_to_sub_item_matrix = m_connectivity.template getItemToItemMatrix<ItemType::cell,item_type>(); auto& item_list_to_send_by_proc = this->_dispatchedInfo<item_type>().m_list_to_send_by_proc; item_list_to_send_by_proc.resize(parallel::size()); for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) { Array<bool> tag(m_connectivity.template numberOf<item_type>()); tag.fill(false); std::vector<ItemId> item_id_vector; 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_sub_item_list = cell_to_sub_item_matrix[cell_id]; for (size_t r=0; r<cell_sub_item_list.size(); ++r) { const ItemId& item_id = cell_sub_item_list[r]; if (not tag[item_id]) { item_id_vector.push_back(item_id); tag[item_id] = true; } } } item_list_to_send_by_proc[i_rank] = convert_to_array(item_id_vector); } } } 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] = item_list_to_send_by_proc[i].size(); } return nb_cell_to_send_by_proc; } template <int Dimension> template<typename DataType, ItemType item_type, typename ConnectivityPtr> void ConnectivityDispatcher<Dimension>:: _gatherFrom(const ItemValue<DataType, item_type, ConnectivityPtr>& data_to_gather, std::vector<std::remove_const_t<DataType>>& gathered_vector) { std::vector<Array<const DataType>> recv_item_data_by_proc = this->exchange(data_to_gather); const auto& recv_id_correspondance_by_proc = this->_dispatchedInfo<item_type>().m_recv_id_correspondance_by_proc; Assert(recv_id_correspondance_by_proc.size()==parallel::size()); gathered_vector.resize(this->_dispatchedInfo<item_type>().m_number_to_id_map.size()); for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) { Assert(recv_id_correspondance_by_proc[i_rank].size()==recv_item_data_by_proc[i_rank].size()); for (size_t r=0; r<recv_id_correspondance_by_proc[i_rank].size(); ++r) { const auto& item_id = recv_id_correspondance_by_proc[i_rank][r]; gathered_vector[item_id] = recv_item_data_by_proc[i_rank][r]; } } } template <int Dimension> void ConnectivityDispatcher<Dimension>:: _buildCellNumberIdMap() { const auto recv_cell_number_by_proc = this->exchange(m_connectivity.template number<ItemType::cell>()); auto& cell_number_id_map = this->_dispatchedInfo<ItemType::cell>().m_number_to_id_map; for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) { CellId cell_id=0; for (size_t i=0; i<recv_cell_number_by_proc[i_rank].size(); ++i) { const int cell_number = recv_cell_number_by_proc[i_rank][i]; auto [iterator, inserted] = cell_number_id_map.insert(std::make_pair(cell_number, cell_id)); if (inserted) ++cell_id; } } } template <int Dimension> template <typename ItemOfItemT> void ConnectivityDispatcher<Dimension>:: _buildSubItemNumberToIdMap(const std::vector<Array<const int>>& recv_cell_sub_item_number_by_proc) { static_assert(ItemOfItemT::item_type == ItemType::cell, "Dispatcher requires to be build using cell as master entities"); auto& sub_item_number_id_map = this->_dispatchedInfo<ItemOfItemT::sub_item_type>().m_number_to_id_map; for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) { int sub_item_id=0; for (size_t i=0; i<recv_cell_sub_item_number_by_proc[i_rank].size(); ++i) { int sub_item_number = recv_cell_sub_item_number_by_proc[i_rank][i]; auto [iterator, inserted] = sub_item_number_id_map.insert(std::make_pair(sub_item_number, sub_item_id)); if (inserted) sub_item_id++; } } } 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) { 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]); } } 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; } (); 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; } 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<FaceOfCell>(); std::vector<Array<const int>> recv_cell_face_numbering_by_proc = this->_getRecvItemSubItemNumberingByProc<FaceOfCell>(recv_number_of_face_per_cell_by_proc); this->_buildSubItemNumberToIdMap<FaceOfCell>(recv_cell_face_numbering_by_proc); const std::unordered_map<int, int>& face_number_id_map = this->_dispatchedInfo<ItemType::face>().m_number_to_id_map; this->_buildItemListToSend<ItemType::face>(); #warning this patterns repeats for each item type. Should be factorized Array<unsigned int> nb_face_to_send_by_proc(parallel::size()); for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) { nb_face_to_send_by_proc[i_rank] = m_dispatched_face_info.m_list_to_send_by_proc[i_rank].size(); } this->_dispatchedInfo<ItemType::face>().m_list_to_recv_size_by_proc = parallel::allToAll(nb_face_to_send_by_proc); this->_buildRecvItemIdCorrespondanceByProc<ItemType::face>(); this->_gatherFrom(m_connectivity.template number<ItemType::face>(), m_new_descriptor.face_number_vector); { 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); } } } { 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<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]); } } cell_face_is_reversed_to_send_by_proc[i_rank] = convert_to_array(face_is_reversed_by_cell_vector); } } std::vector<Array<bool>> recv_cell_face_is_reversed_by_proc(parallel::size()); for (size_t i_rank=0; i_rank < parallel::size(); ++i_rank) { recv_cell_face_is_reversed_by_proc[i_rank] = Array<bool>(sum(recv_number_of_face_per_cell_by_proc[i_rank])); } 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<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++]); } m_new_descriptor.cell_face_is_reversed_vector.emplace_back(face_is_reversed_vector); } } } this->_gatherFrom(this->_dispatchedInfo<ItemType::face>().m_new_owner, m_new_descriptor.face_owner_vector); std::vector<Array<const int>> recv_number_of_node_per_face_by_proc = _getRecvNumberOfSubItemPerItemByProc<NodeOfFace>(); std::vector<Array<const int>> recv_face_node_numbering_by_proc = this->_getRecvItemSubItemNumberingByProc<NodeOfFace>(recv_number_of_node_per_face_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_number_of_node_per_face_by_proc[i_rank].size(); ++i) { std::vector<unsigned int> node_vector; for (int k=0; k<recv_number_of_node_per_face_by_proc[i_rank][i]; ++k) { const auto& searched_node_id = node_number_id_map.find(recv_face_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.face_to_node_vector.emplace_back(node_vector); } } } // Getting references Array<const size_t> number_of_ref_face_list_per_proc = parallel::allGather(m_connectivity.numberOfRefFaceList()); const size_t number_of_face_list_sender = [&] () { size_t number_of_face_list_sender=0; for (size_t i_rank = 0; i_rank < parallel::size(); ++i_rank) { number_of_face_list_sender += (number_of_ref_face_list_per_proc[i_rank] > 0); } return number_of_face_list_sender; }(); if (number_of_face_list_sender > 0) { if (number_of_face_list_sender > 1) { perr() << __FILE__ << ':' << __LINE__ << ": " << rang::fgB::red <<"need to check that knowing procs know the same ref_face_lists!" << rang::fg::reset << '\n'; } if (number_of_face_list_sender < parallel::size()) { const size_t sender_rank = [&] () { size_t i_rank = 0; for (; i_rank < parallel::size(); ++i_rank) { if (number_of_ref_face_list_per_proc[i_rank] > 0) { break; } } return i_rank; }(); Assert(number_of_face_list_sender < parallel::size()); // sending references tags Array<RefId::TagNumberType> ref_tag_list{number_of_ref_face_list_per_proc[sender_rank]}; if (parallel::rank() == sender_rank){ for (size_t i_ref_face_list=0; i_ref_face_list<m_connectivity.numberOfRefFaceList(); ++i_ref_face_list) { auto ref_face_list = m_connectivity.refFaceList(i_ref_face_list); ref_tag_list[i_ref_face_list] = ref_face_list.refId().tagNumber(); } } parallel::broadcast(ref_tag_list, sender_rank); // sending references name size Array<size_t> ref_name_size_list{number_of_ref_face_list_per_proc[sender_rank]}; if (parallel::rank() == sender_rank){ for (size_t i_ref_face_list=0; i_ref_face_list<m_connectivity.numberOfRefFaceList(); ++i_ref_face_list) { auto ref_face_list = m_connectivity.refFaceList(i_ref_face_list); ref_name_size_list[i_ref_face_list] = ref_face_list.refId().tagName().size(); } } parallel::broadcast(ref_name_size_list, sender_rank); // sending references name size Array<RefId::TagNameType::value_type> ref_name_cat{sum(ref_name_size_list)}; if (parallel::rank() == sender_rank){ size_t i_char=0; for (size_t i_ref_face_list=0; i_ref_face_list<m_connectivity.numberOfRefFaceList(); ++i_ref_face_list) { auto ref_face_list = m_connectivity.refFaceList(i_ref_face_list); for (auto c : ref_face_list.refId().tagName()) { ref_name_cat[i_char++] = c; } } } parallel::broadcast(ref_name_cat, sender_rank); std::vector<RefId> ref_id_list = [&] () { std::vector<RefId> ref_id_list; ref_id_list.reserve(ref_name_size_list.size()); size_t begining=0; for (size_t i_ref=0; i_ref < ref_name_size_list.size(); ++i_ref) { const size_t size = ref_name_size_list[i_ref]; ref_id_list.emplace_back(ref_tag_list[i_ref], std::string{&(ref_name_cat[begining]), size}); begining += size; } return ref_id_list; } (); using block_type = int32_t; constexpr size_t block_size = sizeof(block_type); const size_t nb_block = ref_id_list.size()/block_size + (ref_id_list.size()%block_size != 0); for (size_t i_block=0; i_block<nb_block; ++i_block) { FaceValue<block_type> face_references(m_connectivity); face_references.fill(0); if (m_connectivity.numberOfRefFaceList() > 0) { const size_t max_i_ref = std::min(ref_id_list.size(), block_size*(i_block+1)); for (size_t i_ref=block_size*i_block, i=0; i_ref<max_i_ref; ++i_ref, ++i) { block_type ref_bit{1<<i}; auto ref_face_list = m_connectivity.refFaceList(i_ref); const auto& face_list = ref_face_list.faceList(); for (size_t i_face=0; i_face<face_list.size(); ++i_face) { const FaceId& face_id = face_list[i_face]; face_references[face_id] |= ref_bit; } } } const auto& send_face_id_by_proc = m_dispatched_face_info.m_list_to_send_by_proc; std::vector<Array<const block_type>> send_face_refs_by_proc(parallel::size()); for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) { Array<block_type> send_face_refs(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_refs[l] = face_references[face_id]; }); send_face_refs_by_proc[i_rank] = send_face_refs; } std::vector<Array<block_type>> recv_face_refs_by_proc(parallel::size()); for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) { recv_face_refs_by_proc[i_rank] = Array<block_type>(m_dispatched_face_info.m_list_to_recv_size_by_proc[i_rank]); } parallel::exchange(send_face_refs_by_proc, recv_face_refs_by_proc); const auto& recv_face_id_correspondance_by_proc = m_dispatched_face_info.m_recv_id_correspondance_by_proc; std::vector<block_type> face_refs(m_new_descriptor.face_number_vector.size()); for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) { for (size_t r=0; r<recv_face_refs_by_proc[i_rank].size(); ++r) { const FaceId& face_id = recv_face_id_correspondance_by_proc[i_rank][r]; face_refs[face_id] = recv_face_refs_by_proc[i_rank][r]; } } const size_t max_i_ref = std::min(ref_id_list.size(), block_size*(i_block+1)); for (size_t i_ref=block_size*i_block, i=0; i_ref<max_i_ref; ++i_ref, ++i) { block_type ref_bit{1<<i}; std::vector<FaceId> face_id_vector; for (uint32_t i_face=0; i_face<face_refs.size(); ++i_face) { const FaceId face_id{i_face}; if (face_refs[face_id] & ref_bit) { face_id_vector.push_back(face_id); } } Array<const FaceId> face_id_array = convert_to_array(face_id_vector); m_new_descriptor.addRefFaceList(RefFaceList(ref_id_list[i_ref], face_id_array)); } pout() << __FILE__ << ':' << __LINE__ << ": remains to build lists\n"; } } } } } template <int Dimension> ConnectivityDispatcher<Dimension>::ConnectivityDispatcher(const ConnectivityType& connectivity) : m_connectivity(connectivity) { this->_buildNewOwner<ItemType::cell>(); this->_buildNewOwner<ItemType::face>(); // this->_buildNewOwner<ItemType::edge>(); this->_buildNewOwner<ItemType::node>(); this->_buildItemListToSend<ItemType::cell>(); this->_dispatchedInfo<ItemType::cell>().m_list_to_recv_size_by_proc = parallel::allToAll(this->_buildNbCellToSend()); this->_buildCellNumberIdMap(); const std::vector<Array<const int>> recv_number_of_node_per_cell_by_proc = this->_getRecvNumberOfSubItemPerItemByProc<NodeOfCell>(); const std::vector<Array<const int>> recv_cell_node_numbering_by_proc = this->_getRecvItemSubItemNumberingByProc<NodeOfCell>(recv_number_of_node_per_cell_by_proc); this->_buildRecvItemIdCorrespondanceByProc<ItemType::cell>(); this->_gatherFrom(m_connectivity.template number<ItemType::cell>(), m_new_descriptor.cell_number_vector); this->_buildSubItemNumberToIdMap<NodeOfCell>(recv_cell_node_numbering_by_proc); this->_buildItemListToSend<ItemType::node>(); 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_dispatched_node_info.m_list_to_send_by_proc[i_rank].size(); } this->_dispatchedInfo<ItemType::node>().m_list_to_recv_size_by_proc = parallel::allToAll(nb_node_to_send_by_proc); this->_buildRecvItemIdCorrespondanceByProc<ItemType::node>(); // Fill new descriptor this->_gatherFrom(m_connectivity.cellType(), m_new_descriptor.cell_type_vector); this->_gatherFrom(this->_dispatchedInfo<ItemType::cell>().m_new_owner, m_new_descriptor.cell_owner_vector); this->_gatherFrom(m_connectivity.template number<ItemType::node>(), m_new_descriptor.node_number_vector); this->_gatherFrom(this->_dispatchedInfo<ItemType::node>().m_new_owner, m_new_descriptor.node_owner_vector); { // build cells connectivity 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); } } } this->_dispatchFaces(); m_dispatched_connectivity = ConnectivityType::build(m_new_descriptor); } template ConnectivityDispatcher<1>::ConnectivityDispatcher(const ConnectivityType&); template ConnectivityDispatcher<2>::ConnectivityDispatcher(const ConnectivityType&); template ConnectivityDispatcher<3>::ConnectivityDispatcher(const ConnectivityType&);