diff --git a/src/mesh/Connectivity.hpp b/src/mesh/Connectivity.hpp index 3ec986e8b710181643bfe02cbfdf8d7c55b52d7c..86b6606c7f24c2271569f07cbb5fe9d10a8b8fe3 100644 --- a/src/mesh/Connectivity.hpp +++ b/src/mesh/Connectivity.hpp @@ -80,21 +80,21 @@ class Connectivity final : public IConnectivity WeakFaceValuePerCell<const bool> m_cell_face_is_reversed; WeakEdgeValuePerFace<const bool> m_face_edge_is_reversed; - WeakFaceValuePerCell<const unsigned short> m_cell_local_numbers_in_their_faces; - WeakEdgeValuePerCell<const unsigned short> m_cell_local_numbers_in_their_edges; - WeakNodeValuePerCell<const unsigned short> m_cell_local_numbers_in_their_nodes; + WeakFaceValuePerCell<const uint16_t> m_cell_local_numbers_in_their_faces; + WeakEdgeValuePerCell<const uint16_t> m_cell_local_numbers_in_their_edges; + WeakNodeValuePerCell<const uint16_t> m_cell_local_numbers_in_their_nodes; - WeakCellValuePerFace<const unsigned short> m_face_local_numbers_in_their_cells; - WeakEdgeValuePerFace<const unsigned short> m_face_local_numbers_in_their_edges; - WeakNodeValuePerFace<const unsigned short> m_face_local_numbers_in_their_nodes; + WeakCellValuePerFace<const uint16_t> m_face_local_numbers_in_their_cells; + WeakEdgeValuePerFace<const uint16_t> m_face_local_numbers_in_their_edges; + WeakNodeValuePerFace<const uint16_t> m_face_local_numbers_in_their_nodes; - WeakCellValuePerEdge<const unsigned short> m_edge_local_numbers_in_their_cells; - WeakFaceValuePerEdge<const unsigned short> m_edge_local_numbers_in_their_faces; - WeakNodeValuePerEdge<const unsigned short> m_edge_local_numbers_in_their_nodes; + WeakCellValuePerEdge<const uint16_t> m_edge_local_numbers_in_their_cells; + WeakFaceValuePerEdge<const uint16_t> m_edge_local_numbers_in_their_faces; + WeakNodeValuePerEdge<const uint16_t> m_edge_local_numbers_in_their_nodes; - WeakCellValuePerNode<const unsigned short> m_node_local_numbers_in_their_cells; - WeakFaceValuePerNode<const unsigned short> m_node_local_numbers_in_their_faces; - WeakEdgeValuePerNode<const unsigned short> m_node_local_numbers_in_their_edges; + WeakCellValuePerNode<const uint16_t> m_node_local_numbers_in_their_cells; + WeakFaceValuePerNode<const uint16_t> m_node_local_numbers_in_their_faces; + WeakEdgeValuePerNode<const uint16_t> m_node_local_numbers_in_their_edges; ConnectivityComputer m_connectivity_computer; @@ -109,18 +109,6 @@ class Connectivity final : public IConnectivity void _buildIsBoundaryEdge() const; void _buildIsBoundaryNode() const; - template <typename SubItemValuePerItemType> - PUGS_INLINE const SubItemValuePerItemType& - _lazzyBuildItemNumberInTheirChild(const SubItemValuePerItemType& sub_item_value_per_item) const - { - using ReversedItemOfItem = typename SubItemValuePerItemType::ItemOfItemType::Reversed; - if (not sub_item_value_per_item.isBuilt()) { - const_cast<SubItemValuePerItemType&>(sub_item_value_per_item) = - m_connectivity_computer.computeLocalItemNumberInChildItem<ReversedItemOfItem>(*this); - } - return sub_item_value_per_item; - } - friend class ConnectivityComputer; public: @@ -446,109 +434,129 @@ class Connectivity final : public IConnectivity } PUGS_INLINE - const auto& - cellLocalNumbersInTheirNodes() const + FaceValuePerCell<const uint16_t> + cellLocalNumbersInTheirFaces() const { - return _lazzyBuildItemNumberInTheirChild(m_cell_local_numbers_in_their_nodes); + if (not m_cell_local_numbers_in_their_faces.isBuilt()) { + m_connectivity_computer.computeLocalItemNumberInChildItem<FaceOfCell>(*this); + } + return m_cell_local_numbers_in_their_faces; } PUGS_INLINE - const auto& + EdgeValuePerCell<const uint16_t> cellLocalNumbersInTheirEdges() const { - if constexpr (Dimension > 2) { - return _lazzyBuildItemNumberInTheirChild(m_cell_local_numbers_in_their_edges); - } else { - return cellLocalNumbersInTheirFaces(); + if (not m_cell_local_numbers_in_their_edges.isBuilt()) { + m_connectivity_computer.computeLocalItemNumberInChildItem<EdgeOfCell>(*this); } + return m_cell_local_numbers_in_their_edges; } PUGS_INLINE - const auto& - cellLocalNumbersInTheirFaces() const + NodeValuePerCell<const uint16_t> + cellLocalNumbersInTheirNodes() const { - if constexpr (Dimension > 1) { - return _lazzyBuildItemNumberInTheirChild(m_cell_local_numbers_in_their_faces); - } else { - return cellLocalNumbersInTheirNodes(); + if (not m_cell_local_numbers_in_their_nodes.isBuilt()) { + m_connectivity_computer.computeLocalItemNumberInChildItem<NodeOfCell>(*this); } + return m_cell_local_numbers_in_their_nodes; } PUGS_INLINE - const auto& + CellValuePerFace<const uint16_t> faceLocalNumbersInTheirCells() const { - if constexpr (Dimension > 1) { - return _lazzyBuildItemNumberInTheirChild(m_face_local_numbers_in_their_cells); - } else { - return nodeLocalNumbersInTheirCells(); + if (not m_face_local_numbers_in_their_cells.isBuilt()) { + m_connectivity_computer.computeLocalItemNumberInChildItem<CellOfFace>(*this); } + return m_face_local_numbers_in_their_cells; } PUGS_INLINE - const auto& + EdgeValuePerFace<const uint16_t> faceLocalNumbersInTheirEdges() const { static_assert(Dimension > 2, "this function has no meaning in 1d or 2d"); - return _lazzyBuildItemNumberInTheirChild(m_face_local_numbers_in_their_edges); + if (not m_face_local_numbers_in_their_edges.isBuilt()) { + m_connectivity_computer.computeLocalItemNumberInChildItem<EdgeOfFace>(*this); + } + return m_face_local_numbers_in_their_edges; } PUGS_INLINE - const auto& + NodeValuePerFace<const uint16_t> faceLocalNumbersInTheirNodes() const { static_assert(Dimension > 1, "this function has no meaning in 1d"); - return _lazzyBuildItemNumberInTheirChild(m_face_local_numbers_in_their_nodes); + if (not m_face_local_numbers_in_their_nodes.isBuilt()) { + m_connectivity_computer.computeLocalItemNumberInChildItem<NodeOfFace>(*this); + } + return m_face_local_numbers_in_their_nodes; } PUGS_INLINE - const auto& + CellValuePerEdge<const uint16_t> edgeLocalNumbersInTheirCells() const { - if constexpr (Dimension > 2) { - return _lazzyBuildItemNumberInTheirChild(m_edge_local_numbers_in_their_cells); - } else { - return faceLocalNumbersInTheirCells(); + if (not m_edge_local_numbers_in_their_cells.isBuilt()) { + m_connectivity_computer.computeLocalItemNumberInChildItem<CellOfEdge>(*this); } + return m_edge_local_numbers_in_their_cells; } PUGS_INLINE - const auto& + FaceValuePerEdge<const uint16_t> edgeLocalNumbersInTheirFaces() const { static_assert(Dimension > 2, "this function has no meaning in 1d or 2d"); - return _lazzyBuildItemNumberInTheirChild(m_edge_local_numbers_in_their_faces); + if (not m_edge_local_numbers_in_their_faces.isBuilt()) { + m_connectivity_computer.computeLocalItemNumberInChildItem<FaceOfEdge>(*this); + } + return m_edge_local_numbers_in_their_faces; } PUGS_INLINE - const auto& + NodeValuePerEdge<const uint16_t> edgeLocalNumbersInTheirNodes() const { - static_assert(Dimension > 2, "this function has no meaning in 1d or 2d"); - return _lazzyBuildItemNumberInTheirChild(m_edge_local_numbers_in_their_nodes); + static_assert(Dimension > 1, "this function has no meaning in 1d"); + if (not m_edge_local_numbers_in_their_nodes.isBuilt()) { + m_connectivity_computer.computeLocalItemNumberInChildItem<NodeOfEdge>(*this); + } + return m_edge_local_numbers_in_their_nodes; } PUGS_INLINE - const auto& + CellValuePerNode<const uint16_t> nodeLocalNumbersInTheirCells() const { - return _lazzyBuildItemNumberInTheirChild(m_node_local_numbers_in_their_cells); + if (not m_node_local_numbers_in_their_cells.isBuilt()) { + m_connectivity_computer.computeLocalItemNumberInChildItem<CellOfNode>(*this); + } + return m_node_local_numbers_in_their_cells; } PUGS_INLINE - const auto& - nodeLocalNumbersInTheirEdges() const + FaceValuePerNode<const uint16_t> + nodeLocalNumbersInTheirFaces() const { - static_assert(Dimension > 2, "this function has no meaning in 1d or 2d"); - return _lazzyBuildItemNumberInTheirChild(m_node_local_numbers_in_their_edges); + static_assert(Dimension > 1, "this function has no meaning in 1d"); + if (not m_node_local_numbers_in_their_faces.isBuilt()) { + m_connectivity_computer.computeLocalItemNumberInChildItem<FaceOfNode>(*this); + } + return m_node_local_numbers_in_their_faces; } PUGS_INLINE - const auto& - nodeLocalNumbersInTheirFaces() const + EdgeValuePerNode<const uint16_t> + nodeLocalNumbersInTheirEdges() const { - static_assert(Dimension > 1, "this function has no meaning in 1d"); - return _lazzyBuildItemNumberInTheirChild(m_node_local_numbers_in_their_faces); + static_assert(Dimension > 1, "this function has no meaning in 1d or 2d"); + if (not m_node_local_numbers_in_their_edges.isBuilt()) { + m_connectivity_computer.computeLocalItemNumberInChildItem<EdgeOfNode>(*this); + } + return m_node_local_numbers_in_their_edges; } template <ItemType item_type> diff --git a/src/mesh/ConnectivityComputer.cpp b/src/mesh/ConnectivityComputer.cpp index 7e8b32020843d9a1c8ea5ec1077dc34135e2dd88..67463bb8a043424bc173073cff3413ce884f5600 100644 --- a/src/mesh/ConnectivityComputer.cpp +++ b/src/mesh/ConnectivityComputer.cpp @@ -73,98 +73,228 @@ ConnectivityComputer::_computeInverse(const ConnectivityMatrix& item_to_child_ma } template <typename ItemOfItem, typename ConnectivityType> -WeakSubItemValuePerItem<const unsigned short, typename ItemOfItem::Reversed> +void ConnectivityComputer::computeLocalItemNumberInChildItem(const ConnectivityType& connectivity) const { - using ReversedItemOfItem = typename ItemOfItem::Reversed; + constexpr ItemType item_type = ItemOfItem::item_type; + constexpr ItemType sub_item_type = ItemOfItem::sub_item_type; - constexpr ItemType item_type = ReversedItemOfItem::item_type; - constexpr ItemType child_item_type = ReversedItemOfItem::sub_item_type; + ItemToItemMatrix item_to_child_items_matrix = connectivity.template getItemToItemMatrix<item_type, sub_item_type>(); + ItemToItemMatrix child_item_to_items_matrix = connectivity.template getItemToItemMatrix<sub_item_type, item_type>(); - ItemToItemMatrix item_to_child_items_matrix = connectivity.template getItemToItemMatrix<item_type, child_item_type>(); - ItemToItemMatrix child_item_to_items_matrix = connectivity.template getItemToItemMatrix<child_item_type, item_type>(); - - WeakSubItemValuePerItem<unsigned short, ReversedItemOfItem> item_number_in_child_item(connectivity); - for (ItemIdT<item_type> r = 0; r < connectivity.template numberOf<item_type>(); ++r) { - const auto& item_to_child_items = item_to_child_items_matrix[r]; - for (unsigned short J = 0; J < item_to_child_items_matrix[r].size(); ++J) { - ItemIdT j = item_to_child_items[J]; - const auto& child_item_to_items = child_item_to_items_matrix[j]; - - for (unsigned int R = 0; R < child_item_to_items.size(); ++R) { - if (child_item_to_items[R] == r) { - item_number_in_child_item(r, J) = R; - break; + Array<unsigned short> number_in_child_array{item_to_child_items_matrix.numberOfValues()}; + { + WeakSubItemValuePerItem<unsigned short, ItemOfItem> item_number_in_child_item(connectivity, number_in_child_array); + for (ItemIdT<item_type> item_id = 0; item_id < connectivity.template numberOf<item_type>(); ++item_id) { + const auto& item_to_child_items = item_to_child_items_matrix[item_id]; + for (unsigned short i_item_child = 0; i_item_child < item_to_child_items_matrix[item_id].size(); ++i_item_child) { + ItemIdT j = item_to_child_items[i_item_child]; + const auto& child_item_to_items = child_item_to_items_matrix[j]; + + for (unsigned int i_item_in_child = 0; i_item_in_child < child_item_to_items.size(); ++i_item_in_child) { + if (child_item_to_items[i_item_in_child] == item_id) { + item_number_in_child_item(item_id, i_item_child) = i_item_in_child; + break; + } } } } } - return item_number_in_child_item; + if constexpr (ConnectivityType::Dimension == 1) { + if constexpr (item_type == ItemType::cell) { + const_cast<WeakSubItemValuePerItem<const unsigned short, FaceOfCell>&>( + connectivity.m_cell_local_numbers_in_their_faces) = + WeakSubItemValuePerItem<unsigned short, FaceOfCell>(connectivity, number_in_child_array); + const_cast<WeakSubItemValuePerItem<const unsigned short, EdgeOfCell>&>( + connectivity.m_cell_local_numbers_in_their_edges) = + WeakSubItemValuePerItem<unsigned short, EdgeOfCell>(connectivity, number_in_child_array); + const_cast<WeakSubItemValuePerItem<const unsigned short, NodeOfCell>&>( + connectivity.m_cell_local_numbers_in_their_nodes) = + WeakSubItemValuePerItem<unsigned short, NodeOfCell>(connectivity, number_in_child_array); + } else if constexpr (sub_item_type == ItemType::cell) { + const_cast<WeakSubItemValuePerItem<const unsigned short, CellOfFace>&>( + connectivity.m_face_local_numbers_in_their_cells) = + WeakSubItemValuePerItem<unsigned short, CellOfFace>(connectivity, number_in_child_array); + const_cast<WeakSubItemValuePerItem<const unsigned short, CellOfEdge>&>( + connectivity.m_edge_local_numbers_in_their_cells) = + WeakSubItemValuePerItem<unsigned short, CellOfEdge>(connectivity, number_in_child_array); + const_cast<WeakSubItemValuePerItem<const unsigned short, CellOfNode>&>( + connectivity.m_node_local_numbers_in_their_cells) = + WeakSubItemValuePerItem<unsigned short, CellOfNode>(connectivity, number_in_child_array); + } + } else if constexpr (ConnectivityType::Dimension == 2) { + if constexpr (item_type == ItemType::cell) { + if constexpr ((sub_item_type == ItemType::face) or (sub_item_type == ItemType::edge)) { + const_cast<WeakSubItemValuePerItem<const unsigned short, FaceOfCell>&>( + connectivity.m_cell_local_numbers_in_their_faces) = + WeakSubItemValuePerItem<unsigned short, FaceOfCell>(connectivity, number_in_child_array); + const_cast<WeakSubItemValuePerItem<const unsigned short, EdgeOfCell>&>( + connectivity.m_cell_local_numbers_in_their_edges) = + WeakSubItemValuePerItem<unsigned short, EdgeOfCell>(connectivity, number_in_child_array); + } else { + static_assert(sub_item_type == ItemType::node); + const_cast<WeakSubItemValuePerItem<const unsigned short, NodeOfCell>&>( + connectivity.m_cell_local_numbers_in_their_nodes) = + WeakSubItemValuePerItem<unsigned short, NodeOfCell>(connectivity, number_in_child_array); + } + } else if constexpr (item_type == ItemType::face or item_type == ItemType::edge) { + if constexpr (sub_item_type == ItemType::cell) { + const_cast<WeakSubItemValuePerItem<const unsigned short, CellOfFace>&>( + connectivity.m_face_local_numbers_in_their_cells) = + WeakSubItemValuePerItem<unsigned short, CellOfFace>(connectivity, number_in_child_array); + const_cast<WeakSubItemValuePerItem<const unsigned short, CellOfEdge>&>( + connectivity.m_edge_local_numbers_in_their_cells) = + WeakSubItemValuePerItem<unsigned short, CellOfEdge>(connectivity, number_in_child_array); + } else { + static_assert(sub_item_type == ItemType::node); + const_cast<WeakSubItemValuePerItem<const unsigned short, NodeOfFace>&>( + connectivity.m_face_local_numbers_in_their_nodes) = + WeakSubItemValuePerItem<unsigned short, NodeOfFace>(connectivity, number_in_child_array); + const_cast<WeakSubItemValuePerItem<const unsigned short, NodeOfEdge>&>( + connectivity.m_edge_local_numbers_in_their_nodes) = + WeakSubItemValuePerItem<unsigned short, NodeOfEdge>(connectivity, number_in_child_array); + } + } else { + static_assert(item_type == ItemType::node); + if constexpr (sub_item_type == ItemType::cell) { + const_cast<WeakSubItemValuePerItem<const unsigned short, CellOfNode>&>( + connectivity.m_node_local_numbers_in_their_cells) = + WeakSubItemValuePerItem<unsigned short, CellOfNode>(connectivity, number_in_child_array); + } else { + static_assert(sub_item_type == ItemType::face or sub_item_type == ItemType::edge); + const_cast<WeakSubItemValuePerItem<const unsigned short, FaceOfNode>&>( + connectivity.m_node_local_numbers_in_their_faces) = + WeakSubItemValuePerItem<unsigned short, FaceOfNode>(connectivity, number_in_child_array); + const_cast<WeakSubItemValuePerItem<const unsigned short, EdgeOfNode>&>( + connectivity.m_node_local_numbers_in_their_edges) = + WeakSubItemValuePerItem<unsigned short, EdgeOfNode>(connectivity, number_in_child_array); + } + } + } else if constexpr (ConnectivityType::Dimension == 3) { + if constexpr (item_type == ItemType::cell) { + if constexpr (sub_item_type == ItemType::face) { + const_cast<WeakSubItemValuePerItem<const unsigned short, FaceOfCell>&>( + connectivity.m_cell_local_numbers_in_their_faces) = + WeakSubItemValuePerItem<unsigned short, FaceOfCell>(connectivity, number_in_child_array); + } else if constexpr (sub_item_type == ItemType::edge) { + const_cast<WeakSubItemValuePerItem<const unsigned short, EdgeOfCell>&>( + connectivity.m_cell_local_numbers_in_their_edges) = + WeakSubItemValuePerItem<unsigned short, EdgeOfCell>(connectivity, number_in_child_array); + } else { + static_assert(sub_item_type == ItemType::node); + const_cast<WeakSubItemValuePerItem<const unsigned short, NodeOfCell>&>( + connectivity.m_cell_local_numbers_in_their_nodes) = + WeakSubItemValuePerItem<unsigned short, NodeOfCell>(connectivity, number_in_child_array); + } + } else if constexpr (item_type == ItemType::face) { + if constexpr (sub_item_type == ItemType::cell) { + const_cast<WeakSubItemValuePerItem<const unsigned short, CellOfFace>&>( + connectivity.m_face_local_numbers_in_their_cells) = + WeakSubItemValuePerItem<unsigned short, CellOfFace>(connectivity, number_in_child_array); + } else if constexpr (sub_item_type == ItemType::edge) { + const_cast<WeakSubItemValuePerItem<const unsigned short, EdgeOfFace>&>( + connectivity.m_face_local_numbers_in_their_edges) = + WeakSubItemValuePerItem<unsigned short, EdgeOfFace>(connectivity, number_in_child_array); + } else { + static_assert(sub_item_type == ItemType::node); + const_cast<WeakSubItemValuePerItem<const unsigned short, NodeOfFace>&>( + connectivity.m_face_local_numbers_in_their_nodes) = + WeakSubItemValuePerItem<unsigned short, NodeOfFace>(connectivity, number_in_child_array); + } + } else if constexpr (item_type == ItemType::edge) { + if constexpr (sub_item_type == ItemType::cell) { + const_cast<WeakSubItemValuePerItem<const unsigned short, CellOfEdge>&>( + connectivity.m_edge_local_numbers_in_their_cells) = + WeakSubItemValuePerItem<unsigned short, CellOfEdge>(connectivity, number_in_child_array); + } else if constexpr (sub_item_type == ItemType::face) { + const_cast<WeakSubItemValuePerItem<const unsigned short, FaceOfEdge>&>( + connectivity.m_edge_local_numbers_in_their_faces) = + WeakSubItemValuePerItem<unsigned short, FaceOfEdge>(connectivity, number_in_child_array); + } else { + static_assert(sub_item_type == ItemType::node); + const_cast<WeakSubItemValuePerItem<const unsigned short, NodeOfEdge>&>( + connectivity.m_edge_local_numbers_in_their_nodes) = + WeakSubItemValuePerItem<unsigned short, NodeOfEdge>(connectivity, number_in_child_array); + } + } else { + static_assert(item_type == ItemType::node); + if constexpr (sub_item_type == ItemType::cell) { + const_cast<WeakSubItemValuePerItem<const unsigned short, CellOfNode>&>( + connectivity.m_node_local_numbers_in_their_cells) = + WeakSubItemValuePerItem<unsigned short, CellOfNode>(connectivity, number_in_child_array); + } else if constexpr (sub_item_type == ItemType::face) { + const_cast<WeakSubItemValuePerItem<const unsigned short, FaceOfNode>&>( + connectivity.m_node_local_numbers_in_their_faces) = + WeakSubItemValuePerItem<unsigned short, FaceOfNode>(connectivity, number_in_child_array); + } else { + static_assert(sub_item_type == ItemType::edge); + const_cast<WeakSubItemValuePerItem<const unsigned short, EdgeOfNode>&>( + connectivity.m_node_local_numbers_in_their_edges) = + WeakSubItemValuePerItem<unsigned short, EdgeOfNode>(connectivity, number_in_child_array); + } + } + } } // 1D -template WeakSubItemValuePerItem<const unsigned short, CellOfNode> -ConnectivityComputer::computeLocalItemNumberInChildItem<NodeOfCell>(const Connectivity1D&) const; +template void ConnectivityComputer::computeLocalItemNumberInChildItem<CellOfFace>(const Connectivity1D&) const; + +template void ConnectivityComputer::computeLocalItemNumberInChildItem<CellOfEdge>(const Connectivity1D&) const; + +template void ConnectivityComputer::computeLocalItemNumberInChildItem<CellOfNode>(const Connectivity1D&) const; + +template void ConnectivityComputer::computeLocalItemNumberInChildItem<FaceOfCell>(const Connectivity1D&) const; -template WeakSubItemValuePerItem<const unsigned short, NodeOfCell> -ConnectivityComputer::computeLocalItemNumberInChildItem<CellOfNode>(const Connectivity1D&) const; +template void ConnectivityComputer::computeLocalItemNumberInChildItem<EdgeOfCell>(const Connectivity1D&) const; + +template void ConnectivityComputer::computeLocalItemNumberInChildItem<NodeOfCell>(const Connectivity1D&) const; // 2D -template WeakSubItemValuePerItem<const unsigned short, CellOfNode> -ConnectivityComputer::computeLocalItemNumberInChildItem<NodeOfCell>(const Connectivity2D&) const; +template void ConnectivityComputer::computeLocalItemNumberInChildItem<CellOfFace>(const Connectivity2D&) const; + +template void ConnectivityComputer::computeLocalItemNumberInChildItem<CellOfEdge>(const Connectivity2D&) const; + +template void ConnectivityComputer::computeLocalItemNumberInChildItem<CellOfNode>(const Connectivity2D&) const; + +template void ConnectivityComputer::computeLocalItemNumberInChildItem<FaceOfCell>(const Connectivity2D&) const; + +template void ConnectivityComputer::computeLocalItemNumberInChildItem<FaceOfNode>(const Connectivity2D&) const; -template WeakSubItemValuePerItem<const unsigned short, CellOfFace> -ConnectivityComputer::computeLocalItemNumberInChildItem<FaceOfCell>(const Connectivity2D&) const; +template void ConnectivityComputer::computeLocalItemNumberInChildItem<EdgeOfCell>(const Connectivity2D&) const; -template WeakSubItemValuePerItem<const unsigned short, FaceOfNode> -ConnectivityComputer::computeLocalItemNumberInChildItem<NodeOfFace>(const Connectivity2D&) const; +template void ConnectivityComputer::computeLocalItemNumberInChildItem<EdgeOfNode>(const Connectivity2D&) const; -template WeakSubItemValuePerItem<const unsigned short, FaceOfCell> -ConnectivityComputer::computeLocalItemNumberInChildItem<CellOfFace>(const Connectivity2D&) const; +template void ConnectivityComputer::computeLocalItemNumberInChildItem<NodeOfCell>(const Connectivity2D&) const; -template WeakSubItemValuePerItem<const unsigned short, NodeOfFace> -ConnectivityComputer::computeLocalItemNumberInChildItem<FaceOfNode>(const Connectivity2D&) const; +template void ConnectivityComputer::computeLocalItemNumberInChildItem<NodeOfFace>(const Connectivity2D&) const; -template WeakSubItemValuePerItem<const unsigned short, NodeOfCell> -ConnectivityComputer::computeLocalItemNumberInChildItem<CellOfNode>(const Connectivity2D&) const; +template void ConnectivityComputer::computeLocalItemNumberInChildItem<NodeOfEdge>(const Connectivity2D&) const; // 3D -template WeakSubItemValuePerItem<const unsigned short, CellOfNode> -ConnectivityComputer::computeLocalItemNumberInChildItem<NodeOfCell>(const Connectivity3D&) const; +template void ConnectivityComputer::computeLocalItemNumberInChildItem<CellOfFace>(const Connectivity3D&) const; -template WeakSubItemValuePerItem<const unsigned short, CellOfEdge> -ConnectivityComputer::computeLocalItemNumberInChildItem<EdgeOfCell>(const Connectivity3D&) const; +template void ConnectivityComputer::computeLocalItemNumberInChildItem<CellOfEdge>(const Connectivity3D&) const; -template WeakSubItemValuePerItem<const unsigned short, CellOfFace> -ConnectivityComputer::computeLocalItemNumberInChildItem<FaceOfCell>(const Connectivity3D&) const; +template void ConnectivityComputer::computeLocalItemNumberInChildItem<CellOfNode>(const Connectivity3D&) const; -template WeakSubItemValuePerItem<const unsigned short, FaceOfNode> -ConnectivityComputer::computeLocalItemNumberInChildItem<NodeOfFace>(const Connectivity3D&) const; +template void ConnectivityComputer::computeLocalItemNumberInChildItem<FaceOfCell>(const Connectivity3D&) const; -template WeakSubItemValuePerItem<const unsigned short, FaceOfEdge> -ConnectivityComputer::computeLocalItemNumberInChildItem<EdgeOfFace>(const Connectivity3D&) const; +template void ConnectivityComputer::computeLocalItemNumberInChildItem<FaceOfEdge>(const Connectivity3D&) const; -template WeakSubItemValuePerItem<const unsigned short, FaceOfCell> -ConnectivityComputer::computeLocalItemNumberInChildItem<CellOfFace>(const Connectivity3D&) const; +template void ConnectivityComputer::computeLocalItemNumberInChildItem<FaceOfNode>(const Connectivity3D&) const; -template WeakSubItemValuePerItem<const unsigned short, EdgeOfNode> -ConnectivityComputer::computeLocalItemNumberInChildItem<NodeOfEdge>(const Connectivity3D&) const; +template void ConnectivityComputer::computeLocalItemNumberInChildItem<EdgeOfCell>(const Connectivity3D&) const; -template WeakSubItemValuePerItem<const unsigned short, EdgeOfFace> -ConnectivityComputer::computeLocalItemNumberInChildItem<FaceOfEdge>(const Connectivity3D&) const; +template void ConnectivityComputer::computeLocalItemNumberInChildItem<EdgeOfFace>(const Connectivity3D&) const; -template WeakSubItemValuePerItem<const unsigned short, EdgeOfCell> -ConnectivityComputer::computeLocalItemNumberInChildItem<CellOfEdge>(const Connectivity3D&) const; +template void ConnectivityComputer::computeLocalItemNumberInChildItem<EdgeOfNode>(const Connectivity3D&) const; -template WeakSubItemValuePerItem<const unsigned short, NodeOfEdge> -ConnectivityComputer::computeLocalItemNumberInChildItem<EdgeOfNode>(const Connectivity3D&) const; +template void ConnectivityComputer::computeLocalItemNumberInChildItem<NodeOfCell>(const Connectivity3D&) const; -template WeakSubItemValuePerItem<const unsigned short, NodeOfFace> -ConnectivityComputer::computeLocalItemNumberInChildItem<FaceOfNode>(const Connectivity3D&) const; +template void ConnectivityComputer::computeLocalItemNumberInChildItem<NodeOfFace>(const Connectivity3D&) const; -template WeakSubItemValuePerItem<const unsigned short, NodeOfCell> -ConnectivityComputer::computeLocalItemNumberInChildItem<CellOfNode>(const Connectivity3D&) const; +template void ConnectivityComputer::computeLocalItemNumberInChildItem<NodeOfEdge>(const Connectivity3D&) const; diff --git a/src/mesh/ConnectivityComputer.hpp b/src/mesh/ConnectivityComputer.hpp index a4f843e218107b49a6913e3f9028bf034df7c63f..b033a25d5ccc04db84c194e79e492a081216a49e 100644 --- a/src/mesh/ConnectivityComputer.hpp +++ b/src/mesh/ConnectivityComputer.hpp @@ -16,8 +16,7 @@ class ConnectivityComputer ItemType child_item_type) const; template <typename ItemOfItem, typename ConnectivityType> - WeakSubItemValuePerItem<const unsigned short, typename ItemOfItem::Reversed> computeLocalItemNumberInChildItem( - const ConnectivityType& connectivity) const; + void computeLocalItemNumberInChildItem(const ConnectivityType& connectivity) const; ConnectivityComputer(const ConnectivityComputer&) = default; ConnectivityComputer() = default; diff --git a/src/mesh/ItemToItemMatrix.hpp b/src/mesh/ItemToItemMatrix.hpp index 8ee4e9d74757e904cc5b5581c9421145b4eeaac3..6cd2d798b6eaa2844d4eae0d33f8405d344593b7 100644 --- a/src/mesh/ItemToItemMatrix.hpp +++ b/src/mesh/ItemToItemMatrix.hpp @@ -58,6 +58,14 @@ class ItemToItemMatrix const ConnectivityMatrix& m_connectivity_matrix; public: + PUGS_INLINE + size_t + numberOfValues() const + { + return m_connectivity_matrix.numberOfValues(); + } + + PUGS_INLINE auto values() const { diff --git a/tests/test_Connectivity.cpp b/tests/test_Connectivity.cpp index dcc979dd9f833d00ff97ac50816b5102b3ec3e2f..f7d2ab7de77a04e3f5eb46efd458d5299740fc36 100644 --- a/tests/test_Connectivity.cpp +++ b/tests/test_Connectivity.cpp @@ -669,4 +669,305 @@ TEST_CASE("Connectivity", "[mesh]") } } } + + SECTION("ItemLocalNumbersInTheirSubItems") + { + auto check_item_local_numbers_in_their_subitems = [](auto item_to_subitem_matrix, auto subitem_to_item_matrix, + auto item_local_numbers_in_subitems) -> bool { + using ItemId = typename decltype(item_to_subitem_matrix)::SourceItemId; + using SubItemId = typename decltype(item_to_subitem_matrix)::TargetItemId; + + static_assert(std::is_same_v<typename decltype(item_to_subitem_matrix)::SourceItemId, + typename decltype(subitem_to_item_matrix)::TargetItemId>); + static_assert(std::is_same_v<typename decltype(item_to_subitem_matrix)::TargetItemId, + typename decltype(subitem_to_item_matrix)::SourceItemId>); + static_assert(std::is_same_v<typename decltype(item_to_subitem_matrix)::SourceItemId, + typename decltype(item_local_numbers_in_subitems)::ItemId>); + + for (ItemId item_id = 0; item_id < item_local_numbers_in_subitems.numberOfItems(); ++item_id) { + auto item_subitem_list = item_to_subitem_matrix[item_id]; + auto item_numbers = item_local_numbers_in_subitems.itemArray(item_id); + + for (size_t i_item_subitem = 0; i_item_subitem < item_subitem_list.size(); ++i_item_subitem) { + const SubItemId node_cell_id = item_subitem_list[i_item_subitem]; + const size_t i_local_item = item_numbers[i_item_subitem]; + if (subitem_to_item_matrix[node_cell_id][i_local_item] != item_id) { + return false; + } + } + } + return true; + }; + + SECTION("1D") + { + std::array mesh_list = MeshDataBaseForTests::get().all1DMeshes(); + + for (auto named_mesh : mesh_list) { + SECTION(named_mesh.name()) + { + auto mesh = named_mesh.mesh(); + const Connectivity<1>& connectivity = mesh->connectivity(); + + SECTION("node <-> cell") + { + auto node_to_cell_matrix = connectivity.nodeToCellMatrix(); + auto cell_to_node_matrix = connectivity.cellToNodeMatrix(); + + auto node_local_numbers_in_their_cells = connectivity.nodeLocalNumbersInTheirCells(); + REQUIRE(check_item_local_numbers_in_their_subitems(node_to_cell_matrix, cell_to_node_matrix, + node_local_numbers_in_their_cells)); + + auto cell_local_numbers_in_their_nodes = connectivity.cellLocalNumbersInTheirNodes(); + REQUIRE(check_item_local_numbers_in_their_subitems(cell_to_node_matrix, node_to_cell_matrix, + cell_local_numbers_in_their_nodes)); + } + + SECTION("edge <-> cell") + { + auto edge_to_cell_matrix = connectivity.edgeToCellMatrix(); + auto cell_to_edge_matrix = connectivity.cellToEdgeMatrix(); + + auto edge_local_numbers_in_their_cells = connectivity.edgeLocalNumbersInTheirCells(); + REQUIRE(check_item_local_numbers_in_their_subitems(edge_to_cell_matrix, cell_to_edge_matrix, + edge_local_numbers_in_their_cells)); + + auto cell_local_numbers_in_their_edges = connectivity.cellLocalNumbersInTheirEdges(); + REQUIRE(check_item_local_numbers_in_their_subitems(cell_to_edge_matrix, edge_to_cell_matrix, + cell_local_numbers_in_their_edges)); + } + + SECTION("face <-> cell") + { + auto face_to_cell_matrix = connectivity.faceToCellMatrix(); + auto cell_to_face_matrix = connectivity.cellToFaceMatrix(); + + auto face_local_numbers_in_their_cells = connectivity.faceLocalNumbersInTheirCells(); + REQUIRE(check_item_local_numbers_in_their_subitems(face_to_cell_matrix, cell_to_face_matrix, + face_local_numbers_in_their_cells)); + + auto cell_local_numbers_in_their_faces = connectivity.cellLocalNumbersInTheirFaces(); + REQUIRE(check_item_local_numbers_in_their_subitems(cell_to_face_matrix, face_to_cell_matrix, + cell_local_numbers_in_their_faces)); + } + + SECTION("shared data") + { + auto face_local_numbers_in_their_cells = connectivity.faceLocalNumbersInTheirCells(); + auto edge_local_numbers_in_their_cells = connectivity.edgeLocalNumbersInTheirCells(); + auto node_local_numbers_in_their_cells = connectivity.nodeLocalNumbersInTheirCells(); + + REQUIRE(&(face_local_numbers_in_their_cells[0]) == &(edge_local_numbers_in_their_cells[0])); + REQUIRE(&(face_local_numbers_in_their_cells[0]) == &(node_local_numbers_in_their_cells[0])); + + auto cell_local_numbers_in_their_faces = connectivity.cellLocalNumbersInTheirFaces(); + auto cell_local_numbers_in_their_edges = connectivity.cellLocalNumbersInTheirEdges(); + auto cell_local_numbers_in_their_nodes = connectivity.cellLocalNumbersInTheirNodes(); + + REQUIRE(&(cell_local_numbers_in_their_faces[0]) == &(cell_local_numbers_in_their_edges[0])); + REQUIRE(&(cell_local_numbers_in_their_faces[0]) == &(cell_local_numbers_in_their_nodes[0])); + } + } + } + } + + SECTION("2D") + { + std::array mesh_list = MeshDataBaseForTests::get().all2DMeshes(); + + for (auto named_mesh : mesh_list) { + SECTION(named_mesh.name()) + { + auto mesh = named_mesh.mesh(); + const Connectivity<2>& connectivity = mesh->connectivity(); + + SECTION("node <-> cell") + { + auto node_to_cell_matrix = connectivity.nodeToCellMatrix(); + auto cell_to_node_matrix = connectivity.cellToNodeMatrix(); + + auto node_local_numbers_in_their_cells = connectivity.nodeLocalNumbersInTheirCells(); + REQUIRE(check_item_local_numbers_in_their_subitems(node_to_cell_matrix, cell_to_node_matrix, + node_local_numbers_in_their_cells)); + + auto cell_local_numbers_in_their_nodes = connectivity.cellLocalNumbersInTheirNodes(); + REQUIRE(check_item_local_numbers_in_their_subitems(cell_to_node_matrix, node_to_cell_matrix, + cell_local_numbers_in_their_nodes)); + } + + SECTION("edge <-> cell") + { + auto edge_to_cell_matrix = connectivity.edgeToCellMatrix(); + auto cell_to_edge_matrix = connectivity.cellToEdgeMatrix(); + + auto edge_local_numbers_in_their_cells = connectivity.edgeLocalNumbersInTheirCells(); + REQUIRE(check_item_local_numbers_in_their_subitems(edge_to_cell_matrix, cell_to_edge_matrix, + edge_local_numbers_in_their_cells)); + + auto cell_local_numbers_in_their_edges = connectivity.cellLocalNumbersInTheirEdges(); + REQUIRE(check_item_local_numbers_in_their_subitems(cell_to_edge_matrix, edge_to_cell_matrix, + cell_local_numbers_in_their_edges)); + } + + SECTION("face <-> cell") + { + auto face_to_cell_matrix = connectivity.faceToCellMatrix(); + auto cell_to_face_matrix = connectivity.cellToFaceMatrix(); + + auto face_local_numbers_in_their_cells = connectivity.faceLocalNumbersInTheirCells(); + REQUIRE(check_item_local_numbers_in_their_subitems(face_to_cell_matrix, cell_to_face_matrix, + face_local_numbers_in_their_cells)); + + auto cell_local_numbers_in_their_faces = connectivity.cellLocalNumbersInTheirFaces(); + REQUIRE(check_item_local_numbers_in_their_subitems(cell_to_face_matrix, face_to_cell_matrix, + cell_local_numbers_in_their_faces)); + } + + SECTION("node <-> face") + { + auto node_to_face_matrix = connectivity.nodeToFaceMatrix(); + auto face_to_node_matrix = connectivity.faceToNodeMatrix(); + + auto node_local_numbers_in_their_faces = connectivity.nodeLocalNumbersInTheirFaces(); + REQUIRE(check_item_local_numbers_in_their_subitems(node_to_face_matrix, face_to_node_matrix, + node_local_numbers_in_their_faces)); + + auto face_local_numbers_in_their_nodes = connectivity.faceLocalNumbersInTheirNodes(); + REQUIRE(check_item_local_numbers_in_their_subitems(face_to_node_matrix, node_to_face_matrix, + face_local_numbers_in_their_nodes)); + } + + SECTION("node <-> edge") + { + auto node_to_edge_matrix = connectivity.nodeToEdgeMatrix(); + auto edge_to_node_matrix = connectivity.edgeToNodeMatrix(); + + auto node_local_numbers_in_their_edges = connectivity.nodeLocalNumbersInTheirEdges(); + REQUIRE(check_item_local_numbers_in_their_subitems(node_to_edge_matrix, edge_to_node_matrix, + node_local_numbers_in_their_edges)); + + auto edge_local_numbers_in_their_nodes = connectivity.edgeLocalNumbersInTheirNodes(); + REQUIRE(check_item_local_numbers_in_their_subitems(edge_to_node_matrix, node_to_edge_matrix, + edge_local_numbers_in_their_nodes)); + } + + SECTION("shared data") + { + auto face_local_numbers_in_their_cells = connectivity.faceLocalNumbersInTheirCells(); + auto edge_local_numbers_in_their_cells = connectivity.edgeLocalNumbersInTheirCells(); + auto face_local_numbers_in_their_nodes = connectivity.faceLocalNumbersInTheirNodes(); + auto edge_local_numbers_in_their_nodes = connectivity.edgeLocalNumbersInTheirNodes(); + + REQUIRE(&(face_local_numbers_in_their_cells[0]) == &(edge_local_numbers_in_their_cells[0])); + REQUIRE(&(face_local_numbers_in_their_nodes[0]) == &(edge_local_numbers_in_their_nodes[0])); + + auto cell_local_numbers_in_their_faces = connectivity.cellLocalNumbersInTheirFaces(); + auto cell_local_numbers_in_their_edges = connectivity.cellLocalNumbersInTheirEdges(); + auto node_local_numbers_in_their_faces = connectivity.nodeLocalNumbersInTheirFaces(); + auto node_local_numbers_in_their_edges = connectivity.nodeLocalNumbersInTheirEdges(); + + REQUIRE(&(cell_local_numbers_in_their_faces[0]) == &(cell_local_numbers_in_their_edges[0])); + REQUIRE(&(node_local_numbers_in_their_faces[0]) == &(node_local_numbers_in_their_edges[0])); + } + } + } + } + + SECTION("3D") + { + std::array mesh_list = MeshDataBaseForTests::get().all3DMeshes(); + + for (auto named_mesh : mesh_list) { + SECTION(named_mesh.name()) + { + auto mesh = named_mesh.mesh(); + const Connectivity<3>& connectivity = mesh->connectivity(); + + SECTION("node <-> cell") + { + auto node_to_cell_matrix = connectivity.nodeToCellMatrix(); + auto cell_to_node_matrix = connectivity.cellToNodeMatrix(); + + auto node_local_numbers_in_their_cells = connectivity.nodeLocalNumbersInTheirCells(); + REQUIRE(check_item_local_numbers_in_their_subitems(node_to_cell_matrix, cell_to_node_matrix, + node_local_numbers_in_their_cells)); + + auto cell_local_numbers_in_their_nodes = connectivity.cellLocalNumbersInTheirNodes(); + REQUIRE(check_item_local_numbers_in_their_subitems(cell_to_node_matrix, node_to_cell_matrix, + cell_local_numbers_in_their_nodes)); + } + + SECTION("edge <-> cell") + { + auto edge_to_cell_matrix = connectivity.edgeToCellMatrix(); + auto cell_to_edge_matrix = connectivity.cellToEdgeMatrix(); + + auto edge_local_numbers_in_their_cells = connectivity.edgeLocalNumbersInTheirCells(); + REQUIRE(check_item_local_numbers_in_their_subitems(edge_to_cell_matrix, cell_to_edge_matrix, + edge_local_numbers_in_their_cells)); + + auto cell_local_numbers_in_their_edges = connectivity.cellLocalNumbersInTheirEdges(); + REQUIRE(check_item_local_numbers_in_their_subitems(cell_to_edge_matrix, edge_to_cell_matrix, + cell_local_numbers_in_their_edges)); + } + + SECTION("face <-> cell") + { + auto face_to_cell_matrix = connectivity.faceToCellMatrix(); + auto cell_to_face_matrix = connectivity.cellToFaceMatrix(); + + auto face_local_numbers_in_their_cells = connectivity.faceLocalNumbersInTheirCells(); + REQUIRE(check_item_local_numbers_in_their_subitems(face_to_cell_matrix, cell_to_face_matrix, + face_local_numbers_in_their_cells)); + + auto cell_local_numbers_in_their_faces = connectivity.cellLocalNumbersInTheirFaces(); + REQUIRE(check_item_local_numbers_in_their_subitems(cell_to_face_matrix, face_to_cell_matrix, + cell_local_numbers_in_their_faces)); + } + + SECTION("node <-> face") + { + auto node_to_face_matrix = connectivity.nodeToFaceMatrix(); + auto face_to_node_matrix = connectivity.faceToNodeMatrix(); + + auto node_local_numbers_in_their_faces = connectivity.nodeLocalNumbersInTheirFaces(); + REQUIRE(check_item_local_numbers_in_their_subitems(node_to_face_matrix, face_to_node_matrix, + node_local_numbers_in_their_faces)); + + auto face_local_numbers_in_their_nodes = connectivity.faceLocalNumbersInTheirNodes(); + REQUIRE(check_item_local_numbers_in_their_subitems(face_to_node_matrix, node_to_face_matrix, + face_local_numbers_in_their_nodes)); + } + + SECTION("edge <-> face") + { + auto edge_to_face_matrix = connectivity.edgeToFaceMatrix(); + auto face_to_edge_matrix = connectivity.faceToEdgeMatrix(); + + auto edge_local_numbers_in_their_faces = connectivity.edgeLocalNumbersInTheirFaces(); + REQUIRE(check_item_local_numbers_in_their_subitems(edge_to_face_matrix, face_to_edge_matrix, + edge_local_numbers_in_their_faces)); + + auto face_local_numbers_in_their_edges = connectivity.faceLocalNumbersInTheirEdges(); + REQUIRE(check_item_local_numbers_in_their_subitems(face_to_edge_matrix, edge_to_face_matrix, + face_local_numbers_in_their_edges)); + } + + SECTION("node <-> edge") + { + auto node_to_edge_matrix = connectivity.nodeToEdgeMatrix(); + auto edge_to_node_matrix = connectivity.edgeToNodeMatrix(); + + auto node_local_numbers_in_their_edges = connectivity.nodeLocalNumbersInTheirEdges(); + REQUIRE(check_item_local_numbers_in_their_subitems(node_to_edge_matrix, edge_to_node_matrix, + node_local_numbers_in_their_edges)); + + auto edge_local_numbers_in_their_nodes = connectivity.edgeLocalNumbersInTheirNodes(); + REQUIRE(check_item_local_numbers_in_their_subitems(edge_to_node_matrix, node_to_edge_matrix, + edge_local_numbers_in_their_nodes)); + } + } + } + } + } }