diff --git a/src/mesh/Connectivity.cpp b/src/mesh/Connectivity.cpp index 3f453aed9f58cd88b1cdb4345b0cc95e5f4c9888..71f1d1c2d787ad1069fe57687125b3599c917567 100644 --- a/src/mesh/Connectivity.cpp +++ b/src/mesh/Connectivity.cpp @@ -102,6 +102,8 @@ Connectivity(const ConnectivityDescriptor& descriptor) face_owner = convert_to_array(descriptor.face_owner_vector); m_face_owner = face_owner; } + + m_ref_face_list = descriptor.refFaceList(); } } diff --git a/src/mesh/Connectivity.hpp b/src/mesh/Connectivity.hpp index d38c0e1630ae54485974713d08f054922deb08fb..b2c7bfec713c1f1cbbbfe85f6ce2fbe35584917f 100644 --- a/src/mesh/Connectivity.hpp +++ b/src/mesh/Connectivity.hpp @@ -39,6 +39,7 @@ class ConnectivityDescriptor { private: + std::vector<RefFaceList> m_ref_face_list; public: std::vector<std::vector<unsigned int>> cell_by_node_vector; @@ -60,6 +61,16 @@ class ConnectivityDescriptor std::vector<int> face_owner_vector; std::vector<int> node_owner_vector; + const std::vector<RefFaceList>& refFaceList() const + { + return m_ref_face_list; + } + + void addRefFaceList(const RefFaceList& ref_face_list) + { + m_ref_face_list.push_back(ref_face_list); + } + ConnectivityDescriptor& operator=(const ConnectivityDescriptor&) = delete; ConnectivityDescriptor& operator=(ConnectivityDescriptor&&) = delete; @@ -396,6 +407,7 @@ class Connectivity final return _lazzyBuildItemNumberInTheirChild(m_node_local_numbers_in_their_faces); } + [[deprecated("Use connectivity descriptor")]] void addRefFaceList(const RefFaceList& ref_face_list) { m_ref_face_list.push_back(ref_face_list); diff --git a/src/mesh/GmshReader.cpp b/src/mesh/GmshReader.cpp index 2484795d1d333b9fa82f37a39f47b0af24e57541..bc7c9cdb37c5d5c464c15a2e868721c8d369e3b9 100644 --- a/src/mesh/GmshReader.cpp +++ b/src/mesh/GmshReader.cpp @@ -950,6 +950,161 @@ void GmshReader::_dispatch() } } + // Getting references + Array<const size_t> number_of_ref_face_list_per_proc + = parallel::allGather(mesh.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<mesh.connectivity().numberOfRefFaceList(); + ++i_ref_face_list) { + auto ref_face_list = mesh.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<mesh.connectivity().numberOfRefFaceList(); + ++i_ref_face_list) { + auto ref_face_list = mesh.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<mesh.connectivity().numberOfRefFaceList(); + ++i_ref_face_list) { + auto ref_face_list = mesh.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(mesh.connectivity()); + face_references.fill(0); + + if (mesh.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 = mesh.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; + } + } + } + + 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>(nb_face_to_recv_by_proc[i_rank]); + } + parallel::exchange(send_face_refs_by_proc, recv_face_refs_by_proc); + + std::vector<block_type> face_refs(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_owner_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 (size_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); + + new_descriptor.addRefFaceList(RefFaceList(ref_id_list[i_ref], face_id_array)); + } + + pout() << __FILE__ << ':' << __LINE__ << ": remains to build lists\n"; + } + } + } + } using ConnectivityType = Connectivity<Dimension>; @@ -982,94 +1137,6 @@ void GmshReader::_dispatch() << rang::fg::reset << '\n'; } - Array<const size_t> number_of_ref_face_list_per_proc - = parallel::allGather(mesh.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<mesh.connectivity().numberOfRefFaceList(); - ++i_ref_face_list) { - auto ref_face_list = mesh.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<mesh.connectivity().numberOfRefFaceList(); - ++i_ref_face_list) { - auto ref_face_list = mesh.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<mesh.connectivity().numberOfRefFaceList(); - ++i_ref_face_list) { - auto ref_face_list = mesh.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; - } (); - - } - } - // Finally build the mesh NodeValue<Rd> new_xr(*p_connectivity); for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) { diff --git a/src/mesh/MeshNodeBoundary.hpp b/src/mesh/MeshNodeBoundary.hpp index a52a91c99d61c028fdc9f634c896d0ce06aa15dd..3d470179ffd541130593e1a308ee7a0907f2738b 100644 --- a/src/mesh/MeshNodeBoundary.hpp +++ b/src/mesh/MeshNodeBoundary.hpp @@ -14,6 +14,8 @@ #include <IConnectivity.hpp> #include <iostream> +#include <Messenger.hpp> + template <size_t dimension> class MeshNodeBoundary { @@ -212,6 +214,21 @@ _getNormal(const MeshType& mesh) } } + Array<R2> xmin_array = parallel::allGather(xmin); + Array<R2> xmax_array = parallel::allGather(xmax); + for (size_t i=0; i<xmin_array.size(); ++i) { + const R2& x = xmin_array[i]; + if ((x[0]<xmin[0]) or ((x[0] == xmin[0]) and (x[1] < xmin[1]))) { + xmin = x; + } + } + for (size_t i=0; i<xmax_array.size(); ++i) { + const R2& x = xmax_array[i]; + if ((x[0]>xmax[0]) or ((x[0] == xmax[0]) and (x[1] > xmax[1]))) { + xmax = x; + } + } + if (xmin == xmax) { perr() << "xmin==xmax (" << xmin << "==" << xmax << ") unable to compute normal"; std::exit(1); @@ -360,23 +377,35 @@ _getOutgoingNormal(const MeshType& mesh) const R2 normal = this->_getNormal(mesh); - const NodeValue<const R2>& xr = mesh.xr(); - const auto& cell_to_node_matrix - = mesh.connectivity().cellToNodeMatrix(); + double max_height = 0; - const auto& node_to_cell_matrix - = mesh.connectivity().nodeToCellMatrix(); + if (m_node_list.size()>0) { + const NodeValue<const R2>& xr = mesh.xr(); + const auto& cell_to_node_matrix + = mesh.connectivity().cellToNodeMatrix(); + + const auto& node_to_cell_matrix + = mesh.connectivity().nodeToCellMatrix(); + + const NodeId r0 = m_node_list[0]; + const CellId j0 = node_to_cell_matrix[r0][0]; + const auto& j0_nodes = cell_to_node_matrix[j0]; + for (size_t r=0; r<j0_nodes.size(); ++r) { + const double height = (xr[j0_nodes[r]]-xr[r0], normal); + if (std::abs(height) > std::abs(max_height)) { + max_height = height; + } + } + } - const NodeId r0 = m_node_list[0]; - const CellId j0 = node_to_cell_matrix[r0][0]; - const auto& j0_nodes = cell_to_node_matrix[j0]; - double max_height = 0; - for (size_t r=0; r<j0_nodes.size(); ++r) { - const double height = (xr[j0_nodes[r]]-xr[r0], normal); + Array<double> max_height_array = parallel::allGather(max_height); + for (size_t i=0; i<max_height_array.size(); ++i) { + const double height = max_height_array[i]; if (std::abs(height) > std::abs(max_height)) { max_height = height; } } + if (max_height > 0) { return -normal; } else { diff --git a/src/mesh/RefFaceList.hpp b/src/mesh/RefFaceList.hpp index ab66943936c091735c404b287d587a15d81a1a9f..cbc7d3b997983c0bdc03d9513684cde8bd669873 100644 --- a/src/mesh/RefFaceList.hpp +++ b/src/mesh/RefFaceList.hpp @@ -7,8 +7,8 @@ class RefFaceList { private: - const RefId m_ref_id; - const Array<const FaceId> m_face_id_list; + RefId m_ref_id; + Array<const FaceId> m_face_id_list; public: const RefId& refId() const