diff --git a/src/mesh/ConnectivityToDiamondDualConnectivityDataMapper.hpp b/src/mesh/ConnectivityToDiamondDualConnectivityDataMapper.hpp new file mode 100644 index 0000000000000000000000000000000000000000..577bad4c499cd3aa91e6dd498c033b51ab0aac76 --- /dev/null +++ b/src/mesh/ConnectivityToDiamondDualConnectivityDataMapper.hpp @@ -0,0 +1,204 @@ +#ifndef CONNECTIVITY_TO_DIAMOND_DUAL_CONNECTIVITY_DATA_MAPPER_HPP +#define CONNECTIVITY_TO_DIAMOND_DUAL_CONNECTIVITY_DATA_MAPPER_HPP + +#include <mesh/Connectivity.hpp> +#include <mesh/ItemValue.hpp> +#include <utils/Array.hpp> +#include <utils/PugsAssert.hpp> + +class IConnectivityToDiamondDualConnectivityDataMapper +{ + public: + IConnectivityToDiamondDualConnectivityDataMapper(const IConnectivityToDiamondDualConnectivityDataMapper&) = delete; + IConnectivityToDiamondDualConnectivityDataMapper(IConnectivityToDiamondDualConnectivityDataMapper&&) = delete; + + IConnectivityToDiamondDualConnectivityDataMapper() = default; + virtual ~IConnectivityToDiamondDualConnectivityDataMapper() = default; +}; + +template <size_t Dimension> +class ConnectivityToDiamondDualConnectivityDataMapper : public IConnectivityToDiamondDualConnectivityDataMapper +{ + private: + const IConnectivity* m_primal_connectivity; + const IConnectivity* m_dual_connectivity; + + using NodeIdToNodeIdMap = Array<std::pair<NodeId, NodeId>>; + NodeIdToNodeIdMap m_primal_node_to_dual_node_map; + + using CellIdToNodeIdMap = Array<std::pair<CellId, NodeId>>; + CellIdToNodeIdMap m_primal_cell_to_dual_node_map; + + using FaceIdToCellIdMap = Array<std::pair<FaceId, CellId>>; + FaceIdToCellIdMap m_primal_face_to_dual_cell_map; + + public: + template <typename OriginDataType1, typename OriginDataType2, typename DestinationDataType> + void + toDualNode(const NodeValue<OriginDataType1>& primal_node_value, + const CellValue<OriginDataType2>& primal_cell_value, + const NodeValue<DestinationDataType>& dual_node_value) const + { + static_assert(not std::is_const_v<DestinationDataType>, "destination data type must not be constant"); + static_assert(std::is_same_v<std::remove_const_t<OriginDataType1>, DestinationDataType>, "incompatible types"); + static_assert(std::is_same_v<std::remove_const_t<OriginDataType2>, DestinationDataType>, "incompatible types"); + + Assert(m_primal_connectivity == primal_cell_value.connectivity_ptr().get()); + Assert(m_primal_connectivity == primal_node_value.connectivity_ptr().get()); + Assert(m_dual_connectivity == dual_node_value.connectivity_ptr().get()); + + parallel_for( + m_primal_node_to_dual_node_map.size(), PUGS_LAMBDA(size_t i) { + const auto [primal_node_id, dual_node_id] = m_primal_node_to_dual_node_map[i]; + + dual_node_value[dual_node_id] = primal_node_value[primal_node_id]; + }); + + parallel_for( + m_primal_cell_to_dual_node_map.size(), PUGS_LAMBDA(size_t i) { + const auto [primal_cell_id, dual_node_id] = m_primal_cell_to_dual_node_map[i]; + dual_node_value[dual_node_id] = primal_cell_value[primal_cell_id]; + }); + } + + template <typename OriginDataType, typename DestinationDataType1, typename DestinationDataType2> + void + fromDualNode(const NodeValue<OriginDataType>& dual_node_value, + const NodeValue<DestinationDataType1>& primal_node_value, + const CellValue<DestinationDataType2>& primal_cell_value) const + { + static_assert(not std::is_const_v<DestinationDataType1>, "destination data type must not be constant"); + static_assert(not std::is_const_v<DestinationDataType2>, "destination data type must not be constant"); + static_assert(std::is_same_v<std::remove_const_t<OriginDataType>, DestinationDataType1>, "incompatible types"); + static_assert(std::is_same_v<std::remove_const_t<OriginDataType>, DestinationDataType2>, "incompatible types"); + + Assert(m_primal_connectivity == primal_cell_value.connectivity_ptr().get()); + Assert(m_primal_connectivity == primal_node_value.connectivity_ptr().get()); + Assert(m_dual_connectivity == dual_node_value.connectivity_ptr().get()); + + parallel_for( + m_primal_node_to_dual_node_map.size(), PUGS_LAMBDA(size_t i) { + const auto [primal_node_id, dual_node_id] = m_primal_node_to_dual_node_map[i]; + + primal_node_value[primal_node_id] = dual_node_value[dual_node_id]; + }); + + parallel_for( + m_primal_cell_to_dual_node_map.size(), PUGS_LAMBDA(size_t i) { + const auto [primal_cell_id, dual_node_id] = m_primal_cell_to_dual_node_map[i]; + primal_cell_value[primal_cell_id] = dual_node_value[dual_node_id]; + }); + } + + template <typename OriginDataType, typename DestinationDataType> + void + toDualCell(const FaceValue<OriginDataType>& primal_face_value, + const CellValue<DestinationDataType>& dual_cell_value) const + { + static_assert(not std::is_const_v<DestinationDataType>, "destination data type must not be constant"); + static_assert(std::is_same_v<std::remove_const_t<OriginDataType>, DestinationDataType>, "incompatible types"); + + Assert(m_primal_connectivity == primal_face_value.connectivity_ptr().get()); + Assert(m_dual_connectivity == dual_cell_value.connectivity_ptr().get()); + + parallel_for( + m_primal_face_to_dual_cell_map.size(), PUGS_LAMBDA(size_t i) { + const auto [primal_face_id, dual_cell_id] = m_primal_face_to_dual_cell_map[i]; + + dual_cell_value[dual_cell_id] = primal_face_value[primal_face_id]; + }); + + parallel_for( + m_primal_cell_to_dual_node_map.size(), PUGS_LAMBDA(size_t i) { + const auto [primal_face_id, dual_cell_id] = m_primal_face_to_dual_cell_map[i]; + + dual_cell_value[dual_cell_id] = primal_face_value[primal_face_id]; + }); + } + + template <typename OriginDataType, typename DestinationDataType> + void + fromDualCell(const CellValue<DestinationDataType>& dual_cell_value, + const FaceValue<OriginDataType>& primal_face_value) const + { + static_assert(not std::is_const_v<DestinationDataType>, "destination data type must not be constant"); + static_assert(std::is_same_v<std::remove_const_t<OriginDataType>, DestinationDataType>, "incompatible types"); + + Assert(m_primal_connectivity == primal_face_value.connectivity_ptr().get()); + Assert(m_dual_connectivity == dual_cell_value.connectivity_ptr().get()); + + parallel_for( + m_primal_face_to_dual_cell_map.size(), PUGS_LAMBDA(size_t i) { + const auto [primal_face_id, dual_cell_id] = m_primal_face_to_dual_cell_map[i]; + + primal_face_value[primal_face_id] = dual_cell_value[dual_cell_id]; + }); + + parallel_for( + m_primal_cell_to_dual_node_map.size(), PUGS_LAMBDA(size_t i) { + const auto [primal_face_id, dual_cell_id] = m_primal_face_to_dual_cell_map[i]; + primal_face_value[primal_face_id] = dual_cell_value[dual_cell_id]; + }); + } + + ConnectivityToDiamondDualConnectivityDataMapper(const Connectivity<Dimension>& primal_connectivity, + const Connectivity<Dimension>& dual_connectivity) + : m_primal_connectivity{&primal_connectivity}, m_dual_connectivity{&dual_connectivity} + { + if constexpr (Dimension == 1) { + const auto& node_to_cell_matrix = primal_connectivity.nodeToCellMatrix(); + + NodeId dual_node_id = 0; + m_primal_node_to_dual_node_map = [&]() { + std::vector<std::pair<NodeId, NodeId>> primal_node_to_dual_node_vector; + for (NodeId primal_node_id = 0; primal_node_id < primal_connectivity.numberOfNodes(); ++primal_node_id) { + if (node_to_cell_matrix[primal_node_id].size() == 1) { + primal_node_to_dual_node_vector.push_back(std::make_pair(primal_node_id, dual_node_id++)); + } + } + return convert_to_array(primal_node_to_dual_node_vector); + }(); + + m_primal_cell_to_dual_node_map = [&]() { + CellIdToNodeIdMap primal_cell_to_dual_node_map{primal_connectivity.numberOfCells()}; + for (CellId primal_cell_id = 0; primal_cell_id < primal_cell_to_dual_node_map.size(); ++primal_cell_id) { + primal_cell_to_dual_node_map[primal_cell_id] = std::make_pair(primal_cell_id, dual_node_id++); + } + return primal_cell_to_dual_node_map; + }(); + + } else { + m_primal_node_to_dual_node_map = [&]() { + NodeIdToNodeIdMap primal_node_to_dual_node_map{primal_connectivity.numberOfNodes()}; + for (NodeId primal_node_id = 0; primal_node_id < primal_node_to_dual_node_map.size(); ++primal_node_id) { + const NodeId dual_node_id = primal_node_id; + + primal_node_to_dual_node_map[primal_node_id] = std::make_pair(primal_node_id, dual_node_id); + } + return primal_node_to_dual_node_map; + }(); + + m_primal_cell_to_dual_node_map = [&]() { + CellIdToNodeIdMap primal_cell_to_dual_node_map{primal_connectivity.numberOfCells()}; + NodeId dual_node_id = m_primal_node_to_dual_node_map.size(); + for (CellId primal_cell_id = 0; primal_cell_id < primal_cell_to_dual_node_map.size(); ++primal_cell_id) { + primal_cell_to_dual_node_map[primal_cell_id] = std::make_pair(primal_cell_id, dual_node_id++); + } + return primal_cell_to_dual_node_map; + }(); + } + + m_primal_face_to_dual_cell_map = [&]() { + FaceIdToCellIdMap primal_face_to_dual_cell_map{primal_connectivity.numberOfFaces()}; + for (size_t id = 0; id < primal_face_to_dual_cell_map.size(); ++id) { + const CellId dual_cell_id = id; + const FaceId primal_face_id = id; + + primal_face_to_dual_cell_map[id] = std::make_pair(primal_face_id, dual_cell_id); + } + return primal_face_to_dual_cell_map; + }(); + } +}; + +#endif // CONNECTIVITY_TO_DIAMOND_DUAL_CONNECTIVITY_DATA_MAPPER_HPP diff --git a/src/mesh/DiamondDualConnectivityManager.cpp b/src/mesh/DiamondDualConnectivityManager.cpp index 2f0ff4019f90a6db20a6ad75abda52df289fd243..aed409bdaf6fb6e0f60b71f9d77f1a94ec238fc1 100644 --- a/src/mesh/DiamondDualConnectivityManager.cpp +++ b/src/mesh/DiamondDualConnectivityManager.cpp @@ -1,6 +1,7 @@ #include <utils/PugsAssert.hpp> #include <mesh/Connectivity.hpp> +#include <mesh/ConnectivityToDiamondDualConnectivityDataMapper.hpp> #include <mesh/DiamondDualConnectivityBuilder.hpp> #include <mesh/DiamondDualConnectivityManager.hpp> #include <utils/Exceptions.hpp> @@ -21,11 +22,12 @@ DiamondDualConnectivityManager::destroy() { Assert(m_instance != nullptr, "DiamondDualConnectivityManager was not created!"); - if (m_instance->m_connectivity_to_diamond_dual_connectivity_map.size() > 0) { + if (m_instance->m_connectivity_to_diamond_dual_connectivity_info_map.size() > 0) { std::stringstream error; error << ": some connectivities are still registered\n"; - for (const auto& i_mesh_data : m_instance->m_connectivity_to_diamond_dual_connectivity_map) { - error << " - connectivity " << rang::fgB::magenta << i_mesh_data.first << rang::style::reset << '\n'; + for (const auto& [connectivity, diamond_dual_connectivity_info] : + m_instance->m_connectivity_to_diamond_dual_connectivity_info_map) { + error << " - connectivity " << rang::fgB::magenta << connectivity << rang::style::reset << '\n'; } throw UnexpectedError(error.str()); } @@ -36,7 +38,7 @@ DiamondDualConnectivityManager::destroy() void DiamondDualConnectivityManager::deleteConnectivity(const IConnectivity* p_connectivity) { - m_connectivity_to_diamond_dual_connectivity_map.erase(p_connectivity); + m_connectivity_to_diamond_dual_connectivity_info_map.erase(p_connectivity); } template <size_t Dimension> @@ -45,14 +47,50 @@ DiamondDualConnectivityManager::getDiamondDualConnectivity(const Connectivity<Di { const IConnectivity* p_connectivity = &connectivity; - if (auto i_mesh_data = m_connectivity_to_diamond_dual_connectivity_map.find(p_connectivity); - i_mesh_data != m_connectivity_to_diamond_dual_connectivity_map.end()) { - return std::dynamic_pointer_cast<const Connectivity<Dimension>>(i_mesh_data->second); + if (auto i_connectivity = m_connectivity_to_diamond_dual_connectivity_info_map.find(p_connectivity); + i_connectivity != m_connectivity_to_diamond_dual_connectivity_info_map.end()) { + auto& [connectivity, diamond_dual_connectivity_info] = *i_connectivity; + return std::dynamic_pointer_cast<const Connectivity<Dimension>>( + diamond_dual_connectivity_info.diamondDualConnectivity()); } else { DiamondDualConnectivityBuilder builder{connectivity}; - m_connectivity_to_diamond_dual_connectivity_map[p_connectivity] = builder.connectivity(); - return std::dynamic_pointer_cast<const Connectivity<Dimension>>(builder.connectivity()); + std::shared_ptr diamond_connectivity = + std::dynamic_pointer_cast<const Connectivity<Dimension>>(builder.connectivity()); + std::shared_ptr<IConnectivityToDiamondDualConnectivityDataMapper> mapper = + std::make_shared<ConnectivityToDiamondDualConnectivityDataMapper<Dimension>>(connectivity, *diamond_connectivity); + + m_connectivity_to_diamond_dual_connectivity_info_map[p_connectivity] = + DiamondDualConnectivityInfo{diamond_connectivity, mapper}; + + return diamond_connectivity; + } +} + +template <size_t Dimension> +std::shared_ptr<const ConnectivityToDiamondDualConnectivityDataMapper<Dimension>> +DiamondDualConnectivityManager::getConnectivityToDiamondDualConnectivityDataMapper( + const Connectivity<Dimension>& connectivity) +{ + const IConnectivity* p_connectivity = &connectivity; + + if (auto i_connectivity = m_connectivity_to_diamond_dual_connectivity_info_map.find(p_connectivity); + i_connectivity != m_connectivity_to_diamond_dual_connectivity_info_map.end()) { + auto& [connectivity, diamond_dual_connectivity_info] = *i_connectivity; + return std::dynamic_pointer_cast<const ConnectivityToDiamondDualConnectivityDataMapper<Dimension>>( + diamond_dual_connectivity_info.connectivityToDiamondDualConnectivityDataMapper()); + } else { + DiamondDualConnectivityBuilder builder{connectivity}; + + std::shared_ptr diamond_connectivity = + std::dynamic_pointer_cast<const Connectivity<Dimension>>(builder.connectivity()); + std::shared_ptr<IConnectivityToDiamondDualConnectivityDataMapper> mapper = + std::make_shared<ConnectivityToDiamondDualConnectivityDataMapper<Dimension>>(connectivity, *diamond_connectivity); + + m_connectivity_to_diamond_dual_connectivity_info_map[p_connectivity] = + DiamondDualConnectivityInfo{diamond_connectivity, mapper}; + + return std::dynamic_pointer_cast<const ConnectivityToDiamondDualConnectivityDataMapper<Dimension>>(mapper); } } @@ -64,3 +102,12 @@ template std::shared_ptr<const Connectivity<2>> DiamondDualConnectivityManager:: template std::shared_ptr<const Connectivity<3>> DiamondDualConnectivityManager::getDiamondDualConnectivity( const Connectivity<3>& connectivity); + +template std::shared_ptr<const ConnectivityToDiamondDualConnectivityDataMapper<1>> +DiamondDualConnectivityManager::getConnectivityToDiamondDualConnectivityDataMapper(const Connectivity<1>&); + +template std::shared_ptr<const ConnectivityToDiamondDualConnectivityDataMapper<2>> +DiamondDualConnectivityManager::getConnectivityToDiamondDualConnectivityDataMapper(const Connectivity<2>&); + +template std::shared_ptr<const ConnectivityToDiamondDualConnectivityDataMapper<3>> +DiamondDualConnectivityManager::getConnectivityToDiamondDualConnectivityDataMapper(const Connectivity<3>&); diff --git a/src/mesh/DiamondDualConnectivityManager.hpp b/src/mesh/DiamondDualConnectivityManager.hpp index 6c45d646256c63977be2535e30cf387aa7f6220a..3b7eb2ceaff5c1cacfa26f0bb4194af457e209a2 100644 --- a/src/mesh/DiamondDualConnectivityManager.hpp +++ b/src/mesh/DiamondDualConnectivityManager.hpp @@ -9,11 +9,55 @@ template <size_t Dimension> class Connectivity; +class IConnectivityToDiamondDualConnectivityDataMapper; + +template <size_t Dimension> +class ConnectivityToDiamondDualConnectivityDataMapper; + class DiamondDualConnectivityManager { private: - std::unordered_map<const IConnectivity*, std::shared_ptr<const IConnectivity>> - m_connectivity_to_diamond_dual_connectivity_map; + class DiamondDualConnectivityInfo + { + private: + std::shared_ptr<const IConnectivity> m_diamond_dual_connectivity; + std::shared_ptr<const IConnectivityToDiamondDualConnectivityDataMapper> + m_connectivity_to_diamond_dual_connectivity_data_mapper; + + public: + PUGS_INLINE + std::shared_ptr<const IConnectivity> + diamondDualConnectivity() const + { + return m_diamond_dual_connectivity; + } + + PUGS_INLINE + std::shared_ptr<const IConnectivityToDiamondDualConnectivityDataMapper> + connectivityToDiamondDualConnectivityDataMapper() + { + return m_connectivity_to_diamond_dual_connectivity_data_mapper; + } + + DiamondDualConnectivityInfo& operator=(const DiamondDualConnectivityInfo&) = default; + DiamondDualConnectivityInfo& operator=(DiamondDualConnectivityInfo&&) = default; + + DiamondDualConnectivityInfo() = default; + DiamondDualConnectivityInfo(const DiamondDualConnectivityInfo&) = default; + DiamondDualConnectivityInfo(DiamondDualConnectivityInfo&&) = default; + + DiamondDualConnectivityInfo(const std::shared_ptr<const IConnectivity>& diamond_dual_connectivity, + const std::shared_ptr<const IConnectivityToDiamondDualConnectivityDataMapper>& + connectivity_to_diamond_dual_connectivity_data_mapper) + : m_diamond_dual_connectivity{diamond_dual_connectivity}, + m_connectivity_to_diamond_dual_connectivity_data_mapper{connectivity_to_diamond_dual_connectivity_data_mapper} + {} + + ~DiamondDualConnectivityInfo() = default; + }; + + std::unordered_map<const IConnectivity*, DiamondDualConnectivityInfo> + m_connectivity_to_diamond_dual_connectivity_info_map; static DiamondDualConnectivityManager* m_instance; @@ -39,6 +83,10 @@ class DiamondDualConnectivityManager template <size_t Dimension> std::shared_ptr<const Connectivity<Dimension>> getDiamondDualConnectivity(const Connectivity<Dimension>&); + + template <size_t Dimension> + std::shared_ptr<const ConnectivityToDiamondDualConnectivityDataMapper<Dimension>> + getConnectivityToDiamondDualConnectivityDataMapper(const Connectivity<Dimension>&); }; #endif // DIAMOND_DUAL_CONNECTIVITY_MANAGER_HPP diff --git a/src/mesh/DiamondDualMeshBuilder.cpp b/src/mesh/DiamondDualMeshBuilder.cpp index 482920f1c3382e67e8295e889421ab68022b6a78..df4157c9c19b377f77b754d3f33ac54141539f2f 100644 --- a/src/mesh/DiamondDualMeshBuilder.cpp +++ b/src/mesh/DiamondDualMeshBuilder.cpp @@ -1,203 +1,13 @@ #include <mesh/DiamondDualMeshBuilder.hpp> #include <mesh/Connectivity.hpp> -#include <mesh/ConnectivityDescriptor.hpp> -#include <mesh/ConnectivityDispatcher.hpp> +#include <mesh/ConnectivityToDiamondDualConnectivityDataMapper.hpp> #include <mesh/DiamondDualConnectivityBuilder.hpp> #include <mesh/DiamondDualConnectivityManager.hpp> #include <mesh/ItemValueUtils.hpp> #include <mesh/Mesh.hpp> #include <mesh/MeshData.hpp> #include <mesh/MeshDataManager.hpp> -#include <mesh/RefId.hpp> -#include <utils/Array.hpp> -#include <utils/CastArray.hpp> -#include <utils/Messenger.hpp> -#include <utils/PugsAssert.hpp> - -template <size_t Dimension> -class MeshToDualDataMapper -{ - private: - const IConnectivity* m_primal_connectivity; - const IConnectivity* m_dual_connectivity; - - using NodeIdToNodeIdMap = Array<std::pair<NodeId, NodeId>>; - NodeIdToNodeIdMap m_primal_node_to_dual_node_map; - - using CellIdToNodeIdMap = Array<std::pair<CellId, NodeId>>; - CellIdToNodeIdMap m_primal_cell_to_dual_node_map; - - using FaceIdToCellIdMap = Array<std::pair<FaceId, CellId>>; - FaceIdToCellIdMap m_primal_face_to_dual_cell_map; - - public: - template <typename OriginDataType1, typename OriginDataType2, typename DestinationDataType> - void - toDualNode(const NodeValue<OriginDataType1>& primal_node_value, - const CellValue<OriginDataType2>& primal_cell_value, - const NodeValue<DestinationDataType>& dual_node_value) - { - static_assert(not std::is_const_v<DestinationDataType>, "destination data type must not be constant"); - static_assert(std::is_same_v<std::remove_const_t<OriginDataType1>, DestinationDataType>, "incompatible types"); - static_assert(std::is_same_v<std::remove_const_t<OriginDataType2>, DestinationDataType>, "incompatible types"); - - Assert(m_primal_connectivity == primal_cell_value.connectivity_ptr().get()); - Assert(m_primal_connectivity == primal_node_value.connectivity_ptr().get()); - Assert(m_dual_connectivity == dual_node_value.connectivity_ptr().get()); - - parallel_for( - m_primal_node_to_dual_node_map.size(), PUGS_LAMBDA(size_t i) { - const auto [primal_node_id, dual_node_id] = m_primal_node_to_dual_node_map[i]; - - dual_node_value[dual_node_id] = primal_node_value[primal_node_id]; - }); - - parallel_for( - m_primal_cell_to_dual_node_map.size(), PUGS_LAMBDA(size_t i) { - const auto [primal_cell_id, dual_node_id] = m_primal_cell_to_dual_node_map[i]; - dual_node_value[dual_node_id] = primal_cell_value[primal_cell_id]; - }); - } - - template <typename OriginDataType, typename DestinationDataType1, typename DestinationDataType2> - void - fromDualNode(const NodeValue<OriginDataType>& dual_node_value, - const NodeValue<DestinationDataType1>& primal_node_value, - const CellValue<DestinationDataType2>& primal_cell_value) - { - static_assert(not std::is_const_v<DestinationDataType1>, "destination data type must not be constant"); - static_assert(not std::is_const_v<DestinationDataType2>, "destination data type must not be constant"); - static_assert(std::is_same_v<std::remove_const_t<OriginDataType>, DestinationDataType1>, "incompatible types"); - static_assert(std::is_same_v<std::remove_const_t<OriginDataType>, DestinationDataType2>, "incompatible types"); - - Assert(m_primal_connectivity == primal_cell_value.connectivity_ptr().get()); - Assert(m_primal_connectivity == primal_node_value.connectivity_ptr().get()); - Assert(m_dual_connectivity == dual_node_value.connectivity_ptr().get()); - - parallel_for( - m_primal_node_to_dual_node_map.size(), PUGS_LAMBDA(size_t i) { - const auto [primal_node_id, dual_node_id] = m_primal_node_to_dual_node_map[i]; - - primal_node_value[primal_node_id] = dual_node_value[dual_node_id]; - }); - - parallel_for( - m_primal_cell_to_dual_node_map.size(), PUGS_LAMBDA(size_t i) { - const auto [primal_cell_id, dual_node_id] = m_primal_cell_to_dual_node_map[i]; - primal_cell_value[primal_cell_id] = dual_node_value[dual_node_id]; - }); - } - - template <typename OriginDataType, typename DestinationDataType> - void - toDualCell(const FaceValue<OriginDataType>& primal_face_value, const CellValue<DestinationDataType>& dual_cell_value) - { - static_assert(not std::is_const_v<DestinationDataType>, "destination data type must not be constant"); - static_assert(std::is_same_v<std::remove_const_t<OriginDataType>, DestinationDataType>, "incompatible types"); - - Assert(m_primal_connectivity == primal_face_value.connectivity_ptr().get()); - Assert(m_dual_connectivity == dual_cell_value.connectivity_ptr().get()); - - parallel_for( - m_primal_face_to_dual_cell_map.size(), PUGS_LAMBDA(size_t i) { - const auto [primal_face_id, dual_cell_id] = m_primal_face_to_dual_cell_map[i]; - - dual_cell_value[dual_cell_id] = primal_face_value[primal_face_id]; - }); - - parallel_for( - m_primal_cell_to_dual_node_map.size(), PUGS_LAMBDA(size_t i) { - const auto [primal_face_id, dual_cell_id] = m_primal_face_to_dual_cell_map[i]; - - dual_cell_value[dual_cell_id] = primal_face_value[primal_face_id]; - }); - } - - template <typename OriginDataType, typename DestinationDataType> - void - fromDualCell(const CellValue<DestinationDataType>& dual_cell_value, - const FaceValue<OriginDataType>& primal_face_value) - { - static_assert(not std::is_const_v<DestinationDataType>, "destination data type must not be constant"); - static_assert(std::is_same_v<std::remove_const_t<OriginDataType>, DestinationDataType>, "incompatible types"); - - Assert(m_primal_connectivity == primal_face_value.connectivity_ptr().get()); - Assert(m_dual_connectivity == dual_cell_value.connectivity_ptr().get()); - - parallel_for( - m_primal_face_to_dual_cell_map.size(), PUGS_LAMBDA(size_t i) { - const auto [primal_face_id, dual_cell_id] = m_primal_face_to_dual_cell_map[i]; - - primal_face_value[primal_face_id] = dual_cell_value[dual_cell_id]; - }); - - parallel_for( - m_primal_cell_to_dual_node_map.size(), PUGS_LAMBDA(size_t i) { - const auto [primal_face_id, dual_cell_id] = m_primal_face_to_dual_cell_map[i]; - primal_face_value[primal_face_id] = dual_cell_value[dual_cell_id]; - }); - } - - MeshToDualDataMapper(const Connectivity<Dimension>& primal_connectivity, - const Connectivity<Dimension>& dual_connectivity) - : m_primal_connectivity{&primal_connectivity}, m_dual_connectivity{&dual_connectivity} - { - if constexpr (Dimension == 1) { - const auto& node_to_cell_matrix = primal_connectivity.nodeToCellMatrix(); - - NodeId dual_node_id = 0; - m_primal_node_to_dual_node_map = [&]() { - std::vector<std::pair<NodeId, NodeId>> primal_node_to_dual_node_vector; - for (NodeId primal_node_id = 0; primal_node_id < primal_connectivity.numberOfNodes(); ++primal_node_id) { - if (node_to_cell_matrix[primal_node_id].size() == 1) { - primal_node_to_dual_node_vector.push_back(std::make_pair(primal_node_id, dual_node_id++)); - } - } - return convert_to_array(primal_node_to_dual_node_vector); - }(); - - m_primal_cell_to_dual_node_map = [&]() { - CellIdToNodeIdMap primal_cell_to_dual_node_map{primal_connectivity.numberOfCells()}; - for (CellId primal_cell_id = 0; primal_cell_id < primal_cell_to_dual_node_map.size(); ++primal_cell_id) { - primal_cell_to_dual_node_map[primal_cell_id] = std::make_pair(primal_cell_id, dual_node_id++); - } - return primal_cell_to_dual_node_map; - }(); - - } else { - m_primal_node_to_dual_node_map = [&]() { - NodeIdToNodeIdMap primal_node_to_dual_node_map{primal_connectivity.numberOfNodes()}; - for (NodeId primal_node_id = 0; primal_node_id < primal_node_to_dual_node_map.size(); ++primal_node_id) { - const NodeId dual_node_id = primal_node_id; - - primal_node_to_dual_node_map[primal_node_id] = std::make_pair(primal_node_id, dual_node_id); - } - return primal_node_to_dual_node_map; - }(); - - m_primal_cell_to_dual_node_map = [&]() { - CellIdToNodeIdMap primal_cell_to_dual_node_map{primal_connectivity.numberOfCells()}; - NodeId dual_node_id = m_primal_node_to_dual_node_map.size(); - for (CellId primal_cell_id = 0; primal_cell_id < primal_cell_to_dual_node_map.size(); ++primal_cell_id) { - primal_cell_to_dual_node_map[primal_cell_id] = std::make_pair(primal_cell_id, dual_node_id++); - } - return primal_cell_to_dual_node_map; - }(); - } - - m_primal_face_to_dual_cell_map = [&]() { - FaceIdToCellIdMap primal_face_to_dual_cell_map{primal_connectivity.numberOfFaces()}; - for (size_t id = 0; id < primal_face_to_dual_cell_map.size(); ++id) { - const CellId dual_cell_id = id; - const FaceId primal_face_id = id; - - primal_face_to_dual_cell_map[id] = std::make_pair(primal_face_id, dual_cell_id); - } - return primal_face_to_dual_cell_map; - }(); - } -}; template <size_t Dimension> void @@ -221,10 +31,11 @@ DiamondDualMeshBuilder::_buildDualDiamondMeshFrom(const std::shared_ptr<const IM MeshData<Dimension>& primal_mesh_data = MeshDataManager::instance().getMeshData(primal_mesh); const CellValue<const TinyVector<Dimension>> primal_xj = primal_mesh_data.xj(); - MeshToDualDataMapper<Dimension> mesh_to_dual_data_mapper{primal_mesh.connectivity(), diamond_connectivity}; + std::shared_ptr connectivity_to_diamond_dual_connectivity_data_mapper = + manager.getConnectivityToDiamondDualConnectivityDataMapper(primal_mesh.connectivity()); NodeValue<TinyVector<Dimension>> diamond_xr{diamond_connectivity}; - mesh_to_dual_data_mapper.toDualNode(primal_xr, primal_xj, diamond_xr); + connectivity_to_diamond_dual_connectivity_data_mapper->toDualNode(primal_xr, primal_xj, diamond_xr); m_mesh = std::make_shared<MeshType>(p_diamond_connectivity, diamond_xr); }