From fb8866f92f0a03983f584a0f383d571cec9939c6 Mon Sep 17 00:00:00 2001 From: Stephane Del Pino <stephane.delpino44@gmail.com> Date: Fri, 10 Jul 2020 14:07:15 +0200 Subject: [PATCH] Add DiamondDualConnectivityManager and DiamondDualMeshManager These mechanisms are designed to manage diamond meshes/connectivities The main idea is that the diamond mesh is stored as long as its primary mesh lives, and can be retrieved easily. The same mechanism is defined for diamond mesh connectivities. Thus in a moving grid context, the only required calculations will be the definition of the diamond mesh's vertices coordinates. Recall that diamond meshes are just meshes so all meshes' functionality apply to them. --- src/language/modules/MeshModule.cpp | 29 +++++++-- src/main.cpp | 6 ++ src/mesh/CMakeLists.txt | 3 + src/mesh/Connectivity.hpp | 7 +-- src/mesh/DiamondDualConnectivityBuilder.hpp | 4 +- src/mesh/DiamondDualConnectivityManager.cpp | 66 +++++++++++++++++++++ src/mesh/DiamondDualConnectivityManager.hpp | 44 ++++++++++++++ src/mesh/DiamondDualMeshBuilder.cpp | 24 +++++--- src/mesh/DiamondDualMeshBuilder.hpp | 4 +- src/mesh/DiamondDualMeshManager.cpp | 65 ++++++++++++++++++++ src/mesh/DiamondDualMeshManager.hpp | 49 +++++++++++++++ src/mesh/IConnectivity.cpp | 10 ++++ src/mesh/IConnectivity.hpp | 2 +- src/mesh/IMesh.cpp | 4 +- src/mesh/MeshDataManager.cpp | 4 +- src/mesh/MeshDataManager.hpp | 2 +- 16 files changed, 298 insertions(+), 25 deletions(-) create mode 100644 src/mesh/DiamondDualConnectivityManager.cpp create mode 100644 src/mesh/DiamondDualConnectivityManager.hpp create mode 100644 src/mesh/DiamondDualMeshManager.cpp create mode 100644 src/mesh/DiamondDualMeshManager.hpp create mode 100644 src/mesh/IConnectivity.cpp diff --git a/src/language/modules/MeshModule.cpp b/src/language/modules/MeshModule.cpp index b9a657296..89e678c3f 100644 --- a/src/language/modules/MeshModule.cpp +++ b/src/language/modules/MeshModule.cpp @@ -9,7 +9,7 @@ #include <language/utils/TypeDescriptor.hpp> #include <mesh/CartesianMeshBuilder.hpp> #include <mesh/Connectivity.hpp> -#include <mesh/DiamondDualMeshBuilder.hpp> +#include <mesh/DiamondDualMeshManager.hpp> #include <mesh/GmshReader.hpp> #include <mesh/Mesh.hpp> #include <utils/Exceptions.hpp> @@ -184,9 +184,30 @@ MeshModule::MeshModule() std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const IMesh>( const std::shared_ptr<const IMesh>&)>>( - [](const std::shared_ptr<const IMesh>& p_mesh) -> std::shared_ptr<const IMesh> { - DiamondDualMeshBuilder builder{p_mesh}; - return builder.mesh(); + [](const std::shared_ptr<const IMesh>& i_mesh) -> std::shared_ptr<const IMesh> { + switch (i_mesh->dimension()) { + case 1: { + using MeshType = Mesh<Connectivity<1>>; + + std::shared_ptr p_mesh = std::dynamic_pointer_cast<const MeshType>(i_mesh); + return DiamondDualMeshManager::instance().getDiamondDualMesh(p_mesh); + } + case 2: { + using MeshType = Mesh<Connectivity<2>>; + + std::shared_ptr p_mesh = std::dynamic_pointer_cast<const MeshType>(i_mesh); + return DiamondDualMeshManager::instance().getDiamondDualMesh(p_mesh); + } + case 3: { + using MeshType = Mesh<Connectivity<3>>; + + std::shared_ptr p_mesh = std::dynamic_pointer_cast<const MeshType>(i_mesh); + return DiamondDualMeshManager::instance().getDiamondDualMesh(p_mesh); + } + default: { + throw UnexpectedError("invalid dimension"); + } + } } )); diff --git a/src/main.cpp b/src/main.cpp index 9b8530281..aad67d58a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,8 @@ #include <utils/PugsUtils.hpp> #include <language/PugsParser.hpp> +#include <mesh/DiamondDualConnectivityManager.hpp> +#include <mesh/DiamondDualMeshManager.hpp> #include <mesh/MeshDataManager.hpp> #include <mesh/SynchronizerManager.hpp> @@ -11,9 +13,13 @@ main(int argc, char* argv[]) SynchronizerManager::create(); MeshDataManager::create(); + DiamondDualConnectivityManager::create(); + DiamondDualMeshManager::create(); parser(filename); + DiamondDualMeshManager::destroy(); + DiamondDualConnectivityManager::destroy(); MeshDataManager::destroy(); SynchronizerManager::destroy(); finalize(); diff --git a/src/mesh/CMakeLists.txt b/src/mesh/CMakeLists.txt index 92c865c59..6c0088831 100644 --- a/src/mesh/CMakeLists.txt +++ b/src/mesh/CMakeLists.txt @@ -8,8 +8,11 @@ add_library( ConnectivityComputer.cpp ConnectivityDispatcher.cpp DiamondDualConnectivityBuilder.cpp + DiamondDualConnectivityManager.cpp DiamondDualMeshBuilder.cpp + DiamondDualMeshManager.cpp GmshReader.cpp + IConnectivity.cpp IMesh.cpp LogicalConnectivityBuilder.cpp MeshBuilderBase.cpp diff --git a/src/mesh/Connectivity.hpp b/src/mesh/Connectivity.hpp index 5a8881908..3bf5cd420 100644 --- a/src/mesh/Connectivity.hpp +++ b/src/mesh/Connectivity.hpp @@ -12,7 +12,6 @@ #include <mesh/RefId.hpp> #include <mesh/RefItemList.hpp> #include <mesh/SubItemValuePerItem.hpp> -#include <mesh/SynchronizerManager.hpp> #include <utils/CSRGraph.hpp> #include <utils/Exceptions.hpp> #include <utils/PugsAssert.hpp> @@ -651,11 +650,7 @@ class Connectivity final : public IConnectivity void _buildFrom(const ConnectivityDescriptor& descriptor); public: - ~Connectivity() - { - auto& manager = SynchronizerManager::instance(); - manager.deleteConnectivitySynchronizer(this); - } + ~Connectivity() = default; }; template <size_t Dim> diff --git a/src/mesh/DiamondDualConnectivityBuilder.hpp b/src/mesh/DiamondDualConnectivityBuilder.hpp index 670372df9..e0c18457a 100644 --- a/src/mesh/DiamondDualConnectivityBuilder.hpp +++ b/src/mesh/DiamondDualConnectivityBuilder.hpp @@ -18,8 +18,10 @@ class DiamondDualConnectivityBuilder : public ConnectivityBuilderBase template <size_t Dimension> void _buildDiamondConnectivityFrom(const IConnectivity&); - public: + friend class DiamondDualConnectivityManager; DiamondDualConnectivityBuilder(const IConnectivity&); + + public: ~DiamondDualConnectivityBuilder() = default; }; diff --git a/src/mesh/DiamondDualConnectivityManager.cpp b/src/mesh/DiamondDualConnectivityManager.cpp new file mode 100644 index 000000000..2f0ff4019 --- /dev/null +++ b/src/mesh/DiamondDualConnectivityManager.cpp @@ -0,0 +1,66 @@ +#include <utils/PugsAssert.hpp> + +#include <mesh/Connectivity.hpp> +#include <mesh/DiamondDualConnectivityBuilder.hpp> +#include <mesh/DiamondDualConnectivityManager.hpp> +#include <utils/Exceptions.hpp> + +#include <sstream> + +DiamondDualConnectivityManager* DiamondDualConnectivityManager::m_instance{nullptr}; + +void +DiamondDualConnectivityManager::create() +{ + Assert(m_instance == nullptr, "DiamondDualConnectivityManager is already created"); + m_instance = new DiamondDualConnectivityManager; +} + +void +DiamondDualConnectivityManager::destroy() +{ + Assert(m_instance != nullptr, "DiamondDualConnectivityManager was not created!"); + + if (m_instance->m_connectivity_to_diamond_dual_connectivity_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'; + } + throw UnexpectedError(error.str()); + } + delete m_instance; + m_instance = nullptr; +} + +void +DiamondDualConnectivityManager::deleteConnectivity(const IConnectivity* p_connectivity) +{ + m_connectivity_to_diamond_dual_connectivity_map.erase(p_connectivity); +} + +template <size_t Dimension> +std::shared_ptr<const Connectivity<Dimension>> +DiamondDualConnectivityManager::getDiamondDualConnectivity(const Connectivity<Dimension>& connectivity) +{ + 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); + } 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()); + } +} + +template std::shared_ptr<const Connectivity<1>> DiamondDualConnectivityManager::getDiamondDualConnectivity( + const Connectivity<1>& connectivity); + +template std::shared_ptr<const Connectivity<2>> DiamondDualConnectivityManager::getDiamondDualConnectivity( + const Connectivity<2>& connectivity); + +template std::shared_ptr<const Connectivity<3>> DiamondDualConnectivityManager::getDiamondDualConnectivity( + const Connectivity<3>& connectivity); diff --git a/src/mesh/DiamondDualConnectivityManager.hpp b/src/mesh/DiamondDualConnectivityManager.hpp new file mode 100644 index 000000000..6c45d6462 --- /dev/null +++ b/src/mesh/DiamondDualConnectivityManager.hpp @@ -0,0 +1,44 @@ +#ifndef DIAMOND_DUAL_CONNECTIVITY_MANAGER_HPP +#define DIAMOND_DUAL_CONNECTIVITY_MANAGER_HPP + +#include <mesh/IConnectivity.hpp> + +#include <memory> +#include <unordered_map> + +template <size_t Dimension> +class Connectivity; + +class DiamondDualConnectivityManager +{ + private: + std::unordered_map<const IConnectivity*, std::shared_ptr<const IConnectivity>> + m_connectivity_to_diamond_dual_connectivity_map; + + static DiamondDualConnectivityManager* m_instance; + + DiamondDualConnectivityManager(const DiamondDualConnectivityManager&) = delete; + DiamondDualConnectivityManager(DiamondDualConnectivityManager&&) = delete; + + DiamondDualConnectivityManager() = default; + ~DiamondDualConnectivityManager() = default; + + public: + static void create(); + static void destroy(); + + PUGS_INLINE + static DiamondDualConnectivityManager& + instance() + { + Assert(m_instance != nullptr, "DiamondDualConnectivityManager was not created!"); + return *m_instance; + } + + void deleteConnectivity(const IConnectivity*); + + template <size_t Dimension> + std::shared_ptr<const Connectivity<Dimension>> getDiamondDualConnectivity(const Connectivity<Dimension>&); +}; + +#endif // DIAMOND_DUAL_CONNECTIVITY_MANAGER_HPP diff --git a/src/mesh/DiamondDualMeshBuilder.cpp b/src/mesh/DiamondDualMeshBuilder.cpp index 2218541b3..3865414c1 100644 --- a/src/mesh/DiamondDualMeshBuilder.cpp +++ b/src/mesh/DiamondDualMeshBuilder.cpp @@ -1,10 +1,10 @@ #include <mesh/DiamondDualMeshBuilder.hpp> -#include <mesh/DiamondDualConnectivityBuilder.hpp> - #include <mesh/Connectivity.hpp> #include <mesh/ConnectivityDescriptor.hpp> #include <mesh/ConnectivityDispatcher.hpp> +#include <mesh/DiamondDualConnectivityBuilder.hpp> +#include <mesh/DiamondDualConnectivityManager.hpp> #include <mesh/ItemValueUtils.hpp> #include <mesh/Mesh.hpp> #include <mesh/MeshData.hpp> @@ -77,15 +77,19 @@ DiamondDualMeshBuilder::_buildDualDiamondMeshFrom(const Mesh<Connectivity<1>>& p DiamondDualMeshBuilder::DiamondDualMeshBuilder(const std::shared_ptr<const IMesh>& p_mesh) { + std::cout << "building DiamondDualMesh\n"; + switch (p_mesh->dimension()) { case 1: { using ConnectivityType = Connectivity<1>; using MeshType = Mesh<ConnectivityType>; std::shared_ptr mesh = std::dynamic_pointer_cast<const MeshType>(p_mesh); - DiamondDualConnectivityBuilder builder(mesh->connectivity()); - std::shared_ptr p_diamond_connectivity = std::dynamic_pointer_cast<const ConnectivityType>(builder.connectivity()); + DiamondDualConnectivityManager& manager = DiamondDualConnectivityManager::instance(); + + std::shared_ptr<const ConnectivityType> p_diamond_connectivity = + manager.getDiamondDualConnectivity(mesh->connectivity()); this->_buildDualDiamondMeshFrom(*mesh, p_diamond_connectivity); break; @@ -95,9 +99,11 @@ DiamondDualMeshBuilder::DiamondDualMeshBuilder(const std::shared_ptr<const IMesh using MeshType = Mesh<ConnectivityType>; std::shared_ptr mesh = std::dynamic_pointer_cast<const MeshType>(p_mesh); - DiamondDualConnectivityBuilder builder(mesh->connectivity()); - std::shared_ptr p_diamond_connectivity = std::dynamic_pointer_cast<const ConnectivityType>(builder.connectivity()); + DiamondDualConnectivityManager& manager = DiamondDualConnectivityManager::instance(); + + std::shared_ptr<const ConnectivityType> p_diamond_connectivity = + manager.getDiamondDualConnectivity(mesh->connectivity()); this->_buildDualDiamondMeshFrom(*mesh, p_diamond_connectivity); break; @@ -107,9 +113,11 @@ DiamondDualMeshBuilder::DiamondDualMeshBuilder(const std::shared_ptr<const IMesh using MeshType = Mesh<ConnectivityType>; std::shared_ptr mesh = std::dynamic_pointer_cast<const MeshType>(p_mesh); - DiamondDualConnectivityBuilder builder(mesh->connectivity()); - std::shared_ptr p_diamond_connectivity = std::dynamic_pointer_cast<const ConnectivityType>(builder.connectivity()); + DiamondDualConnectivityManager& manager = DiamondDualConnectivityManager::instance(); + + std::shared_ptr<const ConnectivityType> p_diamond_connectivity = + manager.getDiamondDualConnectivity(mesh->connectivity()); this->_buildDualDiamondMeshFrom(*mesh, p_diamond_connectivity); break; diff --git a/src/mesh/DiamondDualMeshBuilder.hpp b/src/mesh/DiamondDualMeshBuilder.hpp index ded3cfb0f..cdb0d7a1c 100644 --- a/src/mesh/DiamondDualMeshBuilder.hpp +++ b/src/mesh/DiamondDualMeshBuilder.hpp @@ -18,8 +18,10 @@ class DiamondDualMeshBuilder : public MeshBuilderBase void _buildDualDiamondMeshFrom(const Mesh<Connectivity<Dimension>>&, const std::shared_ptr<const Connectivity<Dimension>>&); - public: + friend class DiamondDualMeshManager; DiamondDualMeshBuilder(const std::shared_ptr<const IMesh>&); + + public: ~DiamondDualMeshBuilder() = default; }; diff --git a/src/mesh/DiamondDualMeshManager.cpp b/src/mesh/DiamondDualMeshManager.cpp new file mode 100644 index 000000000..061973675 --- /dev/null +++ b/src/mesh/DiamondDualMeshManager.cpp @@ -0,0 +1,65 @@ +#include <mesh/DiamondDualMeshManager.hpp> + +#include <mesh/Connectivity.hpp> +#include <mesh/DiamondDualMeshBuilder.hpp> +#include <mesh/Mesh.hpp> +#include <utils/Exceptions.hpp> +#include <utils/PugsAssert.hpp> + +#include <sstream> + +DiamondDualMeshManager* DiamondDualMeshManager::m_instance{nullptr}; + +void +DiamondDualMeshManager::create() +{ + Assert(m_instance == nullptr, "DiamondDualMeshManager is already created"); + m_instance = new DiamondDualMeshManager; +} + +void +DiamondDualMeshManager::destroy() +{ + Assert(m_instance != nullptr, "DiamondDualMeshManager was not created!"); + + if (m_instance->m_mesh_to_diamond_dual_mesh_map.size() > 0) { + std::stringstream error; + error << ": some meshes are still registered\n"; + for (const auto& i_mesh_data : m_instance->m_mesh_to_diamond_dual_mesh_map) { + error << " - mesh " << rang::fgB::magenta << i_mesh_data.first << rang::style::reset << '\n'; + } + throw UnexpectedError(error.str()); + } + delete m_instance; + m_instance = nullptr; +} + +void +DiamondDualMeshManager::deleteMesh(const IMesh* p_mesh) +{ + m_mesh_to_diamond_dual_mesh_map.erase(p_mesh); +} + +template <size_t Dimension> +std::shared_ptr<const Mesh<Connectivity<Dimension>>> +DiamondDualMeshManager::getDiamondDualMesh(std::shared_ptr<const Mesh<Connectivity<Dimension>>> mesh) +{ + const IMesh* p_mesh = mesh.get(); + + if (auto i_mesh_data = m_mesh_to_diamond_dual_mesh_map.find(p_mesh); + i_mesh_data != m_mesh_to_diamond_dual_mesh_map.end()) { + return std::dynamic_pointer_cast<const Mesh<Connectivity<Dimension>>>(i_mesh_data->second); + } else { + DiamondDualMeshBuilder builder{mesh}; + + m_mesh_to_diamond_dual_mesh_map[p_mesh] = builder.mesh(); + return std::dynamic_pointer_cast<const Mesh<Connectivity<Dimension>>>(builder.mesh()); + } +} + +template std::shared_ptr<const Mesh<Connectivity<1>>> DiamondDualMeshManager::getDiamondDualMesh( + std::shared_ptr<const Mesh<Connectivity<1>>>); +template std::shared_ptr<const Mesh<Connectivity<2>>> DiamondDualMeshManager::getDiamondDualMesh( + std::shared_ptr<const Mesh<Connectivity<2>>>); +template std::shared_ptr<const Mesh<Connectivity<3>>> DiamondDualMeshManager::getDiamondDualMesh( + std::shared_ptr<const Mesh<Connectivity<3>>>); diff --git a/src/mesh/DiamondDualMeshManager.hpp b/src/mesh/DiamondDualMeshManager.hpp new file mode 100644 index 000000000..9f802eb96 --- /dev/null +++ b/src/mesh/DiamondDualMeshManager.hpp @@ -0,0 +1,49 @@ +#ifndef DIAMOND_DUAL_MESH_MANAGER_HPP +#define DIAMOND_DUAL_MESH_MANAGER_HPP + +#include <mesh/IMesh.hpp> +#include <utils/PugsAssert.hpp> +#include <utils/PugsMacros.hpp> + +#include <memory> +#include <unordered_map> + +template <size_t Dimension> +class Connectivity; + +template <typename ConnectivityType> +class Mesh; + +class DiamondDualMeshManager +{ + private: + std::unordered_map<const IMesh*, std::shared_ptr<const IMesh>> m_mesh_to_diamond_dual_mesh_map; + + static DiamondDualMeshManager* m_instance; + + DiamondDualMeshManager(const DiamondDualMeshManager&) = delete; + DiamondDualMeshManager(DiamondDualMeshManager&&) = delete; + + DiamondDualMeshManager() = default; + ~DiamondDualMeshManager() = default; + + public: + static void create(); + static void destroy(); + + PUGS_INLINE + static DiamondDualMeshManager& + instance() + { + Assert(m_instance != nullptr, "DiamondDualMeshManager was not created!"); + return *m_instance; + } + + void deleteMesh(const IMesh*); + + template <size_t Dimension> + std::shared_ptr<const Mesh<Connectivity<Dimension>>> getDiamondDualMesh( + std::shared_ptr<const Mesh<Connectivity<Dimension>>>); +}; + +#endif // DIAMOND_DUAL_MESH_MANAGER_HPP diff --git a/src/mesh/IConnectivity.cpp b/src/mesh/IConnectivity.cpp new file mode 100644 index 000000000..48cf57d55 --- /dev/null +++ b/src/mesh/IConnectivity.cpp @@ -0,0 +1,10 @@ +#include <mesh/IConnectivity.hpp> + +#include <mesh/DiamondDualConnectivityManager.hpp> +#include <mesh/SynchronizerManager.hpp> + +IConnectivity::~IConnectivity() +{ + SynchronizerManager::instance().deleteConnectivitySynchronizer(this); + DiamondDualConnectivityManager::instance().deleteConnectivity(this); +} diff --git a/src/mesh/IConnectivity.hpp b/src/mesh/IConnectivity.hpp index 27be707cb..9bfb8e504 100644 --- a/src/mesh/IConnectivity.hpp +++ b/src/mesh/IConnectivity.hpp @@ -35,7 +35,7 @@ class IConnectivity : public std::enable_shared_from_this<IConnectivity> IConnectivity() = default; IConnectivity(IConnectivity&&) = delete; IConnectivity(const IConnectivity&) = delete; - ~IConnectivity() = default; + virtual ~IConnectivity(); }; template <> diff --git a/src/mesh/IMesh.cpp b/src/mesh/IMesh.cpp index cb2accc14..f315f4b74 100644 --- a/src/mesh/IMesh.cpp +++ b/src/mesh/IMesh.cpp @@ -1,8 +1,10 @@ #include <mesh/IMesh.hpp> +#include <mesh/DiamondDualMeshManager.hpp> #include <mesh/MeshDataManager.hpp> IMesh::~IMesh() { - MeshDataManager::instance().deleteMeshData(*this); + MeshDataManager::instance().deleteMeshData(this); + DiamondDualMeshManager::instance().deleteMesh(this); } diff --git a/src/mesh/MeshDataManager.cpp b/src/mesh/MeshDataManager.cpp index 281e7517a..8ca184a60 100644 --- a/src/mesh/MeshDataManager.cpp +++ b/src/mesh/MeshDataManager.cpp @@ -35,9 +35,9 @@ MeshDataManager::destroy() } void -MeshDataManager::deleteMeshData(const IMesh& mesh) +MeshDataManager::deleteMeshData(const IMesh* p_mesh) { - m_mesh_mesh_data_map.erase(&mesh); + m_mesh_mesh_data_map.erase(p_mesh); } template <size_t Dimension> diff --git a/src/mesh/MeshDataManager.hpp b/src/mesh/MeshDataManager.hpp index 31beecb1b..fd04101de 100644 --- a/src/mesh/MeshDataManager.hpp +++ b/src/mesh/MeshDataManager.hpp @@ -44,7 +44,7 @@ class MeshDataManager return *m_instance; } - void deleteMeshData(const IMesh&); + void deleteMeshData(const IMesh*); template <size_t Dimension> MeshData<Dimension>& getMeshData(const Mesh<Connectivity<Dimension>>&); -- GitLab