diff --git a/src/mesh/DiamondDualMeshBuilder.cpp b/src/mesh/DiamondDualMeshBuilder.cpp index faa7f27793f6a654700f7c3f143a500a816a4a98..52857868c67382d0f8f766ec243a2c39aeb95146 100644 --- a/src/mesh/DiamondDualMeshBuilder.cpp +++ b/src/mesh/DiamondDualMeshBuilder.cpp @@ -164,6 +164,9 @@ DiamondDualMeshBuilder::_buildDiamondMeshFrom(const std::shared_ptr<const IMesh> this->_buildDiamondConnectivityDescriptor(primal_connectivity, diamond_descriptor); MeshBuilderBase::_computeCellFaceAndFaceNodeConnectivities<Dimension>(diamond_descriptor); + if constexpr (Dimension == 3) { + MeshBuilderBase::_computeFaceEdgeAndEdgeNodeAndCellEdgeConnectivities<Dimension>(diamond_descriptor); + } { const auto& primal_face_to_node_matrix = primal_connectivity.faceToNodeMatrix(); @@ -257,6 +260,33 @@ DiamondDualMeshBuilder::_buildDiamondMeshFrom(const std::shared_ptr<const IMesh> } } + if constexpr (Dimension == 3) { + const size_t number_of_edges = diamond_descriptor.edge_to_node_vector.size(); + diamond_descriptor.edge_number_vector.resize(number_of_edges); + for (size_t i_edge = 0; i_edge < number_of_edges; ++i_edge) { + diamond_descriptor.edge_number_vector[i_edge] = i_edge; + } + if (parallel::size() > 1) { + throw NotImplementedError("parallel edge numbering is undefined"); + } + + std::vector<int> edge_cell_owner(number_of_edges); + std::fill(std::begin(edge_cell_owner), std::end(edge_cell_owner), parallel::size()); + + for (size_t i_cell = 0; i_cell < diamond_descriptor.cell_to_face_vector.size(); ++i_cell) { + const auto& cell_edge_list = diamond_descriptor.cell_to_edge_vector[i_cell]; + for (size_t i_edge = 0; i_edge < cell_edge_list.size(); ++i_edge) { + const size_t edge_id = cell_edge_list[i_edge]; + edge_cell_owner[edge_id] = std::min(edge_cell_owner[edge_id], diamond_descriptor.cell_number_vector[i_cell]); + } + } + + diamond_descriptor.edge_owner_vector.resize(edge_cell_owner.size()); + for (size_t i_edge = 0; i_edge < edge_cell_owner.size(); ++i_edge) { + diamond_descriptor.face_owner_vector[i_edge] = diamond_descriptor.cell_owner_vector[edge_cell_owner[i_edge]]; + } + } + std::shared_ptr p_diamond_connectivity = ConnectivityType::build(diamond_descriptor); ConnectivityType& diamond_connectivity = *p_diamond_connectivity; diff --git a/src/mesh/MeshBuilderBase.cpp b/src/mesh/MeshBuilderBase.cpp index 33236a9e2619d546c3bd6db1e7dbd307afa5da23..7f7221b049872fac2d78b936093be706f03ea080 100644 --- a/src/mesh/MeshBuilderBase.cpp +++ b/src/mesh/MeshBuilderBase.cpp @@ -321,7 +321,7 @@ MeshBuilderBase::_computeFaceEdgeAndEdgeNodeAndCellEdgeConnectivities(Connectivi } { - descriptor.cell_to_node_vector.reserve(descriptor.cell_to_node_vector.size()); + descriptor.cell_to_edge_vector.reserve(descriptor.cell_to_node_vector.size()); for (CellId j = 0; j < descriptor.cell_to_node_vector.size(); ++j) { const auto& cell_nodes = descriptor.cell_to_node_vector[j]; @@ -359,10 +359,78 @@ MeshBuilderBase::_computeFaceEdgeAndEdgeNodeAndCellEdgeConnectivities(Connectivi descriptor.cell_to_edge_vector.emplace_back(cell_edge_vector); break; } + case CellType::Pyramid: { + const size_t number_of_edges = 2 * cell_nodes.size(); + std::vector<unsigned int> base_nodes; + std::copy_n(cell_nodes.begin(), cell_nodes.size() - 1, std::back_inserter(base_nodes)); + + std::vector<unsigned int> cell_edge_vector; + cell_edge_vector.reserve(number_of_edges); + for (size_t i_edge = 0; i_edge < base_nodes.size(); ++i_edge) { + Edge edge{{base_nodes[i_edge], base_nodes[(i_edge + 1) % base_nodes.size()]}, node_number_vector}; + auto i = edge_id_map.find(edge); + if (i == edge_id_map.end()) { + throw NormalError("could not find this edge"); + } + cell_edge_vector.push_back(i->second); + } + + const unsigned int top_vertex = cell_nodes[cell_nodes.size() - 1]; + for (size_t i_edge = 0; i_edge < base_nodes.size(); ++i_edge) { + Edge edge{{base_nodes[i_edge], top_vertex}, node_number_vector}; + auto i = edge_id_map.find(edge); + if (i == edge_id_map.end()) { + throw NormalError("could not find this edge"); + } + cell_edge_vector.push_back(i->second); + } + descriptor.cell_to_edge_vector.emplace_back(cell_edge_vector); + break; + } + case CellType::Diamond: { + const size_t number_of_edges = 3 * cell_nodes.size(); + std::vector<unsigned int> base_nodes; + std::copy_n(cell_nodes.begin() + 1, cell_nodes.size() - 2, std::back_inserter(base_nodes)); + + std::vector<unsigned int> cell_edge_vector; + cell_edge_vector.reserve(number_of_edges); + for (size_t i_edge = 0; i_edge < base_nodes.size(); ++i_edge) { + Edge edge{{base_nodes[i_edge], base_nodes[(i_edge + 1) % base_nodes.size()]}, node_number_vector}; + auto i = edge_id_map.find(edge); + if (i == edge_id_map.end()) { + throw NormalError("could not find this edge"); + } + cell_edge_vector.push_back(i->second); + } + + const unsigned int top_vertex = cell_nodes[cell_nodes.size() - 1]; + for (size_t i_edge = 0; i_edge < base_nodes.size(); ++i_edge) { + Edge edge{{base_nodes[i_edge], top_vertex}, node_number_vector}; + auto i = edge_id_map.find(edge); + if (i == edge_id_map.end()) { + throw NormalError("could not find this edge"); + } + cell_edge_vector.push_back(i->second); + } + + const unsigned int bottom_vertex = cell_nodes[0]; + for (size_t i_edge = 0; i_edge < base_nodes.size(); ++i_edge) { + Edge edge{{base_nodes[i_edge], bottom_vertex}, node_number_vector}; + auto i = edge_id_map.find(edge); + if (i == edge_id_map.end()) { + throw NormalError("could not find this edge"); + } + cell_edge_vector.push_back(i->second); + } + + descriptor.cell_to_edge_vector.emplace_back(cell_edge_vector); + + break; + } default: { std::stringstream error_msg; error_msg << name(descriptor.cell_type_vector[j]) << ": unexpected cell type in dimension 3"; - throw UnexpectedError(error_msg.str()); + throw NotImplementedError(error_msg.str()); } } }