Skip to content
Snippets Groups Projects
Commit fb8866f9 authored by Stéphane Del Pino's avatar Stéphane Del Pino
Browse files

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.
parent 39e06090
Branches
Tags
1 merge request!42Feature/diamond dual mesh manager
Showing
with 298 additions and 25 deletions
......@@ -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");
}
}
}
));
......
#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();
......
......@@ -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
......
......@@ -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>
......
......@@ -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;
};
......
#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);
#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
#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;
......
......@@ -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;
};
......
#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>>>);
#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
#include <mesh/IConnectivity.hpp>
#include <mesh/DiamondDualConnectivityManager.hpp>
#include <mesh/SynchronizerManager.hpp>
IConnectivity::~IConnectivity()
{
SynchronizerManager::instance().deleteConnectivitySynchronizer(this);
DiamondDualConnectivityManager::instance().deleteConnectivity(this);
}
......@@ -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 <>
......
#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);
}
......@@ -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>
......
......@@ -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>>&);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment