diff --git a/src/mesh/Connectivity.cpp b/src/mesh/Connectivity.cpp index 7c7f7c72669a95bd096c697c8aa1929f134dbcda..4ec8145a85513bb68d452f1ffcb28679932ea5dc 100644 --- a/src/mesh/Connectivity.cpp +++ b/src/mesh/Connectivity.cpp @@ -72,29 +72,21 @@ Connectivity(const ConnectivityDescriptor& descriptor) = m_item_to_item_matrix[itemTId(ItemType::face)][itemTId(ItemType::node)]; face_to_node_matrix = descriptor.face_to_node_vector; - if constexpr (Dimension==2) { - auto& face_to_cell_matrix - = m_item_to_item_matrix[itemTId(ItemType::face)][itemTId(ItemType::cell)]; - face_to_cell_matrix = descriptor.face_to_cell_vector; - - } else if constexpr (Dimension==3) { - auto& cell_to_face_matrix - = m_item_to_item_matrix[itemTId(ItemType::cell)][itemTId(ItemType::face)]; - cell_to_face_matrix = descriptor.cell_to_face_vector; - - { - FaceValuePerCell<bool> cell_face_is_reversed(*this); - for (CellId j=0; j<descriptor.cell_face_is_reversed_vector.size(); ++j) { - const auto& face_cells_vector = descriptor.cell_face_is_reversed_vector[j]; - for (unsigned short lj=0; lj<face_cells_vector.size(); ++lj) { - cell_face_is_reversed(j,lj) = face_cells_vector[lj]; - } - } + auto& cell_to_face_matrix + = m_item_to_item_matrix[itemTId(ItemType::cell)][itemTId(ItemType::face)]; + cell_to_face_matrix = descriptor.cell_to_face_vector; - m_cell_face_is_reversed = cell_face_is_reversed; + { + FaceValuePerCell<bool> cell_face_is_reversed(*this); + for (CellId j=0; j<descriptor.cell_face_is_reversed_vector.size(); ++j) { + const auto& face_cells_vector = descriptor.cell_face_is_reversed_vector[j]; + for (unsigned short lj=0; lj<face_cells_vector.size(); ++lj) { + cell_face_is_reversed(j,lj) = face_cells_vector[lj]; + } } - } + m_cell_face_is_reversed = cell_face_is_reversed; + } { FaceValue<int> face_number(*this); face_number = convert_to_array(descriptor.face_number_vector); diff --git a/src/mesh/GmshReader.cpp b/src/mesh/GmshReader.cpp index fda25db04737cab3e10d6047870e6ebc377d11c2..68e4dd3c467594eae95897b27cfac74ea99cc5da 100644 --- a/src/mesh/GmshReader.cpp +++ b/src/mesh/GmshReader.cpp @@ -132,17 +132,6 @@ ErrorHandler(const std::string& filename, template <size_t Dimension> class ConnectivityFace; -template<> -class ConnectivityFace<1> -{ - public: - friend struct Hash; - struct Hash - { - size_t operator()(const ConnectivityFace& f) const; - }; -}; - template<> class ConnectivityFace<2> { @@ -158,13 +147,24 @@ class ConnectivityFace<2> } }; + private: + const std::vector<int>& m_node_number_vector; + unsigned int m_node0_id; unsigned int m_node1_id; - friend std::ostream& operator<<(std::ostream& os, const ConnectivityFace& f) + bool m_reversed; + + public: + + std::vector<unsigned int> nodeIdList() const { - os << f.m_node0_id << ' ' << f.m_node1_id << ' '; - return os; + return {m_node0_id, m_node1_id}; + } + + bool reversed() const + { + return m_reversed; } PASTIS_INLINE @@ -177,9 +177,9 @@ class ConnectivityFace<2> PASTIS_INLINE bool operator<(const ConnectivityFace& f) const { - return ((m_node0_id<f.m_node0_id) or - ((m_node0_id == f.m_node0_id) and - (m_node1_id<f.m_node1_id))); + return ((m_node_number_vector[m_node0_id] < m_node_number_vector[f.m_node0_id]) or + ((m_node_number_vector[m_node0_id] == m_node_number_vector[f.m_node0_id]) and + (m_node_number_vector[m_node1_id]<m_node_number_vector[f.m_node1_id]))); } PASTIS_INLINE @@ -189,13 +189,21 @@ class ConnectivityFace<2> ConnectivityFace& operator=(ConnectivityFace&&) = default; PASTIS_INLINE - ConnectivityFace(const std::vector<unsigned int>& given_node_id_list) + ConnectivityFace(const std::vector<unsigned int>& node_id_list, + const std::vector<int>& node_number_vector) + : m_node_number_vector(node_number_vector) { - Assert(given_node_id_list.size()==2); -#warning rework this dirty constructor - const auto& [min, max] = std::minmax(given_node_id_list[0], given_node_id_list[1]); - m_node0_id = min; - m_node1_id = max; + Assert(node_id_list.size()==2); + + if (m_node_number_vector[node_id_list[0]] < m_node_number_vector[node_id_list[1]]) { + m_node0_id = node_id_list[0]; + m_node1_id = node_id_list[1]; + m_reversed = false; + } else { + m_node0_id = node_id_list[1]; + m_node1_id = node_id_list[0]; + m_reversed = true; + } } PASTIS_INLINE @@ -225,28 +233,10 @@ class ConnectivityFace<3> } }; + private: bool m_reversed; std::vector<NodeId::base_type> m_node_id_list; - - friend std::ostream& operator<<(std::ostream& os, const ConnectivityFace& f) - { - for (auto id : f.m_node_id_list) { - os << id << ' '; - } - return os; - } - - PASTIS_INLINE - const bool& reversed() const - { - return m_reversed; - } - - PASTIS_INLINE - const std::vector<unsigned int>& nodeIdList() const - { - return m_node_id_list; - } + const std::vector<int>& m_node_number_vector; PASTIS_INLINE std::vector<unsigned int> _sort(const std::vector<unsigned int>& node_list) @@ -269,10 +259,25 @@ class ConnectivityFace<3> return rotated_node_list; } + public: + PASTIS_INLINE + const bool& reversed() const + { + return m_reversed; + } + + PASTIS_INLINE + const std::vector<unsigned int>& nodeIdList() const + { + return m_node_id_list; + } + PASTIS_INLINE - ConnectivityFace(const std::vector<unsigned int>& given_node_id_list) + ConnectivityFace(const std::vector<unsigned int>& given_node_id_list, + const std::vector<int>& node_number_vector) : m_reversed(false), - m_node_id_list(_sort(given_node_id_list)) + m_node_id_list(_sort(given_node_id_list)), + m_node_number_vector(node_number_vector) { ; } @@ -1168,98 +1173,89 @@ __readPhysicalNames2_2() } } +template <size_t Dimension> void -GmshReader::__compute2DCellFaceAndFaceNodeConnectivities(ConnectivityDescriptor& descriptor) +GmshReader::__computeCellFaceAndFaceNodeConnectivities(ConnectivityDescriptor& descriptor) { - // const auto& cell_to_node_matrix - // = this->_getMatrix(ItemType::cell, ItemType::node); - using Face = ConnectivityFace<2>; + static_assert((Dimension==2) or (Dimension==3), + "Invalid dimension to compute cell-face connectivities"); + using CellFaceInfo = std::tuple<CellId, unsigned short, bool>; + using Face = ConnectivityFace<Dimension>; - // In 2D faces are simply define - using CellFaceId = std::pair<CellId, unsigned short>; - std::map<Face, std::vector<CellFaceId>> face_cells_map; + const auto& node_number_vector = descriptor.node_number_vector; + Array<unsigned short> cell_nb_faces(descriptor.cell_by_node_vector.size()); + std::map<Face, std::vector<CellFaceInfo>> face_cells_map; for (CellId j=0; j<descriptor.cell_by_node_vector.size(); ++j) { const auto& cell_nodes = descriptor.cell_by_node_vector[j]; - for (unsigned short r=0; r<cell_nodes.size(); ++r) { - NodeId node0_id = cell_nodes[r]; - NodeId node1_id = cell_nodes[(r+1)%cell_nodes.size()]; - if (node1_id<node0_id) { - std::swap(node0_id, node1_id); - } - face_cells_map[Face({node0_id, node1_id})].push_back(std::make_pair(j, r)); - } - } - { - descriptor.face_to_node_vector.resize(face_cells_map.size()); - int l=0; - for (const auto& face_info : face_cells_map) { - const Face& face = face_info.first; - descriptor.face_to_node_vector[l] = {face.m_node0_id, face.m_node1_id}; - ++l; - } - } - - { - descriptor.face_to_cell_vector.resize(face_cells_map.size()); - int l=0; - for (const auto& face_cells_vector : face_cells_map) { - const auto& [face, cell_info_vector] = face_cells_vector; - for (const auto& cell_info : cell_info_vector) { - descriptor.face_to_cell_vector[l].push_back(cell_info.first); - } - ++l; - } - } + if constexpr (Dimension==2) { + switch (descriptor.cell_type_vector[j]) { + case CellType::Triangle: { + cell_nb_faces[j] = 3; + // face 0 + Face f0({cell_nodes[1], cell_nodes[2]}, node_number_vector); + face_cells_map[f0].emplace_back(std::make_tuple(j, 0, f0.reversed())); - { - descriptor.face_number_vector.resize(face_cells_map.size()); - for (size_t l=0; l<face_cells_map.size(); ++l) { - descriptor.face_number_vector[l] = l; - } - perr() << __FILE__ << ':' << __LINE__ << ": " << rang::fgB::red << "must use provided faces number" << rang::fg::reset << '\n'; - } -} + // face 1 + Face f1({cell_nodes[2], cell_nodes[0]}, node_number_vector); + face_cells_map[f1].emplace_back(std::make_tuple(j, 1, f1.reversed())); -void -GmshReader::__compute3DCellFaceAndFaceNodeConnectivities(ConnectivityDescriptor& descriptor) -{ - using CellFaceInfo = std::tuple<CellId, unsigned short, bool>; - using Face = ConnectivityFace<3>; + // face 2 + Face f2({cell_nodes[0], cell_nodes[1]}, node_number_vector); + face_cells_map[f2].emplace_back(std::make_tuple(j, 2, f2.reversed())); + break; + } + case CellType::Quadrangle: { + cell_nb_faces[j] = 4; + // face 0 + Face f0({cell_nodes[0], cell_nodes[1]}, node_number_vector); + face_cells_map[f0].emplace_back(std::make_tuple(j, 0, f0.reversed())); - // const auto& cell_to_node_matrix - // = this->_getMatrix(ItemType::cell, ItemType::node); + // face 1 + Face f1({cell_nodes[1], cell_nodes[2]}, node_number_vector); + face_cells_map[f1].emplace_back(std::make_tuple(j, 1, f1.reversed())); - Array<unsigned short> cell_nb_faces(descriptor.cell_by_node_vector.size()); - std::map<Face, std::vector<CellFaceInfo>> face_cells_map; - for (CellId j=0; j<descriptor.cell_by_node_vector.size(); ++j) { - const auto& cell_nodes = descriptor.cell_by_node_vector[j]; + // face 2 + Face f2({cell_nodes[2], cell_nodes[3]}, node_number_vector); + face_cells_map[f2].emplace_back(std::make_tuple(j, 2, f2.reversed())); - switch (descriptor.cell_type_vector[j]) { + // face 3 + Face f3({cell_nodes[3], cell_nodes[0]}, node_number_vector); + face_cells_map[f3].emplace_back(std::make_tuple(j, 3, f3.reversed())); + break; + } + default: { + perr() << name(descriptor.cell_type_vector[j]) + << ": unexpected cell type in dimension 2!\n"; + std::terminate(); + } + } + } else if constexpr (Dimension==3) { + switch (descriptor.cell_type_vector[j]) { case CellType::Tetrahedron: { cell_nb_faces[j] = 4; // face 0 Face f0({cell_nodes[1], cell_nodes[2], - cell_nodes[3]}); + cell_nodes[3]}, node_number_vector); face_cells_map[f0].emplace_back(std::make_tuple(j, 0, f0.reversed())); // face 1 Face f1({cell_nodes[0], cell_nodes[3], - cell_nodes[2]}); + cell_nodes[2]}, node_number_vector); face_cells_map[f1].emplace_back(std::make_tuple(j, 1, f1.reversed())); // face 2 Face f2({cell_nodes[0], cell_nodes[1], - cell_nodes[3]}); + cell_nodes[3]}, node_number_vector); face_cells_map[f2].emplace_back(std::make_tuple(j, 2, f2.reversed())); // face 3 Face f3({cell_nodes[0], cell_nodes[2], - cell_nodes[1]}); + cell_nodes[1]}, node_number_vector); face_cells_map[f3].emplace_back(std::make_tuple(j, 3, f3.reversed())); break; } @@ -1268,50 +1264,52 @@ GmshReader::__compute3DCellFaceAndFaceNodeConnectivities(ConnectivityDescriptor& Face f0({cell_nodes[3], cell_nodes[2], cell_nodes[1], - cell_nodes[0]}); + cell_nodes[0]}, node_number_vector); face_cells_map[f0].emplace_back(std::make_tuple(j, 0, f0.reversed())); // face 1 Face f1({cell_nodes[4], cell_nodes[5], cell_nodes[6], - cell_nodes[7]}); + cell_nodes[7]}, node_number_vector); face_cells_map[f1].emplace_back(std::make_tuple(j, 1, f1.reversed())); // face 2 Face f2({cell_nodes[0], cell_nodes[4], cell_nodes[7], - cell_nodes[3]}); + cell_nodes[3]}, node_number_vector); face_cells_map[f2].emplace_back(std::make_tuple(j, 2, f2.reversed())); // face 3 Face f3({cell_nodes[1], cell_nodes[2], cell_nodes[6], - cell_nodes[5]}); + cell_nodes[5]}, node_number_vector); face_cells_map[f3].emplace_back(std::make_tuple(j, 3, f3.reversed())); // face 4 Face f4({cell_nodes[0], cell_nodes[1], cell_nodes[5], - cell_nodes[4]}); + cell_nodes[4]}, node_number_vector); face_cells_map[f4].emplace_back(std::make_tuple(j, 4, f4.reversed())); // face 5 Face f5({cell_nodes[3], cell_nodes[7], cell_nodes[6], - cell_nodes[2]}); + cell_nodes[2]}, node_number_vector); face_cells_map[f5].emplace_back(std::make_tuple(j, 5, f5.reversed())); cell_nb_faces[j] = 6; break; } default: { - perr() << "unexpected cell type!\n"; - std::exit(0); + perr() << name(descriptor.cell_type_vector[j]) + << ": unexpected cell type in dimension 3!\n"; + std::terminate(); + } } } } @@ -1672,7 +1670,7 @@ GmshReader::__proceedData() descriptor.cell_number_vector[jh] = __hexahedra_number[j]; } - __compute3DCellFaceAndFaceNodeConnectivities(descriptor); + __computeCellFaceAndFaceNodeConnectivities<3>(descriptor); descriptor.cell_owner_vector.resize(nb_cells); std::fill(descriptor.cell_owner_vector.begin(), @@ -1691,6 +1689,7 @@ GmshReader::__proceedData() std::shared_ptr p_connectivity = std::make_shared<Connectivity3D>(descriptor); Connectivity3D& connectivity = *p_connectivity; + const auto& node_number_vector = descriptor.node_number_vector; using Face = ConnectivityFace<3>; const std::unordered_map<Face, FaceId, typename Face::Hash> face_to_id_map @@ -1703,7 +1702,7 @@ GmshReader::__proceedData() for (size_t r=0; r<node_list.size(); ++r) { node_vector[r] = node_list[r]; } - face_to_id_map[Face(node_vector)] = l; + face_to_id_map[Face(node_vector, node_number_vector)] = l; } return face_to_id_map; } (); @@ -1712,7 +1711,8 @@ GmshReader::__proceedData() for (unsigned int f=0; f<__triangles.size(); ++f) { const unsigned int face_number = [&]{ - auto i = face_to_id_map.find(Face({__triangles[f][0], __triangles[f][1], __triangles[f][2]})); + auto i = face_to_id_map.find(Face({__triangles[f][0], __triangles[f][1], __triangles[f][2]}, + node_number_vector)); if (i == face_to_id_map.end()) { std::cerr << "face not found!\n"; std::terminate(); @@ -1727,7 +1727,7 @@ GmshReader::__proceedData() const unsigned int face_number = [&]{ auto i = face_to_id_map.find(Face({__quadrangles[f][0], __quadrangles[f][1], - __quadrangles[f][2], __quadrangles[f][3]})); + __quadrangles[f][2], __quadrangles[f][3]}, node_number_vector)); if (i == face_to_id_map.end()) { std::cerr << "face not found!\n"; std::terminate(); @@ -1789,7 +1789,7 @@ GmshReader::__proceedData() descriptor.cell_number_vector[jq] = __quadrangles_number[j]; } - this->__compute2DCellFaceAndFaceNodeConnectivities(descriptor); + this->__computeCellFaceAndFaceNodeConnectivities<2>(descriptor); descriptor.cell_owner_vector.resize(nb_cells); std::fill(descriptor.cell_owner_vector.begin(), @@ -1810,13 +1810,14 @@ GmshReader::__proceedData() Connectivity2D& connectivity = *p_connectivity; using Face = ConnectivityFace<2>; + const auto& node_number_vector = descriptor.node_number_vector; const std::unordered_map<Face, FaceId, typename Face::Hash> face_to_id_map = [&] { std::unordered_map<Face, FaceId, typename Face::Hash> face_to_id_map; const auto& face_node_list = connectivity.faceToNodeMatrix(); for (FaceId l=0; l<connectivity.numberOfFaces(); ++l) { const auto& node_list = face_node_list[l]; - face_to_id_map[Face({node_list[0], node_list[1]})] = l; + face_to_id_map[Face({node_list[0], node_list[1]}, node_number_vector)] = l; } return face_to_id_map; } (); @@ -1825,7 +1826,7 @@ GmshReader::__proceedData() for (unsigned int e=0; e<__edges.size(); ++e) { const unsigned int edge_number = [&]{ - auto i = face_to_id_map.find(Face({__edges[e][0], __edges[e][1]})); + auto i = face_to_id_map.find(Face({__edges[e][0], __edges[e][1]}, node_number_vector)); if (i == face_to_id_map.end()) { std::cerr << "face " << __edges[e][0] << " not found!\n"; std::terminate(); diff --git a/src/mesh/GmshReader.hpp b/src/mesh/GmshReader.hpp index cd7d89f236272cdf6c584a270587677c1339f379..1ddb6c4db32dbb3deac2fe6f87364532f4da84aa 100644 --- a/src/mesh/GmshReader.hpp +++ b/src/mesh/GmshReader.hpp @@ -258,8 +258,9 @@ private: * */ void __readPhysicalNames2_2(); - void __compute2DCellFaceAndFaceNodeConnectivities(ConnectivityDescriptor& descriptor); - void __compute3DCellFaceAndFaceNodeConnectivities(ConnectivityDescriptor& descriptor); + + template <size_t Dimension> + void __computeCellFaceAndFaceNodeConnectivities(ConnectivityDescriptor& descriptor); template <int Dimension> void _dispatch();