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

Improve support for other dual mesh and dual connectivity types

parent 91c65b8e
Branches
Tags
1 merge request!125Rename DualConnectivityBuilder and MedianDualMeshBuilder's files
......@@ -2,23 +2,14 @@
#define CONNECTIVITY_TO_DIAMOND_DUAL_CONNECTIVITY_DATA_MAPPER_HPP
#include <mesh/Connectivity.hpp>
#include <mesh/IConnectivityToDualConnectivityDataMapper.hpp>
#include <mesh/ItemIdToItemIdMap.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
class ConnectivityToDiamondDualConnectivityDataMapper : public IConnectivityToDualConnectivityDataMapper
{
private:
const IConnectivity* m_primal_connectivity;
......
......@@ -2,6 +2,7 @@
#define DIAMOND_DUAL_CONNECTIVITY_BUILDER_HPP
#include <mesh/ConnectivityBuilderBase.hpp>
#include <mesh/IConnectivityToDualConnectivityDataMapper.hpp>
#include <mesh/ItemIdToItemIdMap.hpp>
#include <memory>
......@@ -10,8 +11,6 @@ template <size_t>
class Connectivity;
class ConnectivityDescriptor;
class IConnectivityToDiamondDualConnectivityDataMapper;
class DiamondDualConnectivityBuilder : public ConnectivityBuilderBase
{
private:
......@@ -19,7 +18,7 @@ class DiamondDualConnectivityBuilder : public ConnectivityBuilderBase
CellIdToNodeIdMap m_primal_cell_to_dual_node_map;
FaceIdToCellIdMap m_primal_face_to_dual_cell_map;
std::shared_ptr<IConnectivityToDiamondDualConnectivityDataMapper> m_mapper;
std::shared_ptr<IConnectivityToDualConnectivityDataMapper> m_mapper;
template <size_t Dimension>
void _buildDiamondConnectivityDescriptor(const Connectivity<Dimension>&, ConnectivityDescriptor&);
......@@ -31,7 +30,7 @@ class DiamondDualConnectivityBuilder : public ConnectivityBuilderBase
DiamondDualConnectivityBuilder(const IConnectivity&);
public:
std::shared_ptr<IConnectivityToDiamondDualConnectivityDataMapper>
std::shared_ptr<IConnectivityToDualConnectivityDataMapper>
mapper() const
{
return m_mapper;
......
......@@ -22,12 +22,13 @@ DualConnectivityManager::destroy()
{
Assert(m_instance != nullptr, "DualConnectivityManager was not created!");
if (m_instance->m_connectivity_to_diamond_dual_connectivity_info_map.size() > 0) {
if (m_instance->m_connectivity_to_dual_connectivity_info_map.size() > 0) {
std::stringstream error;
error << ": some connectivities are still registered\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';
for (const auto& [key, diamond_dual_connectivity_info] : m_instance->m_connectivity_to_dual_connectivity_info_map) {
error << " - connectivity " << rang::fgB::magenta << key.second << rang::style::reset << ": " << name(key.first)
<< " dual connectivity of " << rang::fgB::yellow << diamond_dual_connectivity_info.dualConnectivity().get()
<< rang::style::reset << '\n';
}
throw UnexpectedError(error.str());
}
......@@ -38,23 +39,35 @@ DualConnectivityManager::destroy()
void
DualConnectivityManager::deleteConnectivity(const IConnectivity* p_connectivity)
{
m_connectivity_to_diamond_dual_connectivity_info_map.erase(p_connectivity);
bool has_removed = false;
do {
has_removed = false;
for (const auto& [key, dual_connectivity] : m_connectivity_to_dual_connectivity_info_map) {
const auto& [type, p_parent_connectivity] = key;
if (p_connectivity == p_parent_connectivity) {
m_connectivity_to_dual_connectivity_info_map.erase(key);
has_removed = true;
break;
}
}
} while (has_removed);
}
DualConnectivityManager::DiamondDualConnectivityInfo
DualConnectivityManager::_getDiamondDualConnectivityInfo(const IConnectivity& connectivity)
DualConnectivityManager::DualConnectivityInfo
DualConnectivityManager::_getDualConnectivityInfo(const DualMeshType& type, const IConnectivity& 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 key = std::make_pair(type, p_connectivity);
if (auto i_connectivity = m_connectivity_to_dual_connectivity_info_map.find(key);
i_connectivity != m_connectivity_to_dual_connectivity_info_map.end()) {
return i_connectivity->second;
} else {
DiamondDualConnectivityBuilder builder{connectivity};
DiamondDualConnectivityInfo connectivity_info{builder.connectivity(), builder.mapper()};
DualConnectivityInfo connectivity_info{builder.connectivity(), builder.mapper()};
m_connectivity_to_diamond_dual_connectivity_info_map[p_connectivity] = connectivity_info;
m_connectivity_to_dual_connectivity_info_map[key] = connectivity_info;
return connectivity_info;
}
......@@ -65,15 +78,23 @@ std::shared_ptr<const Connectivity<Dimension>>
DualConnectivityManager::getDiamondDualConnectivity(const Connectivity<Dimension>& connectivity)
{
return std::dynamic_pointer_cast<const Connectivity<Dimension>>(
this->_getDiamondDualConnectivityInfo(connectivity).diamondDualConnectivity());
this->_getDualConnectivityInfo(DualMeshType::Diamond, connectivity).dualConnectivity());
}
template <size_t Dimension>
std::shared_ptr<const ConnectivityToDiamondDualConnectivityDataMapper<Dimension>>
DualConnectivityManager::getConnectivityToDiamondDualConnectivityDataMapper(const Connectivity<Dimension>& connectivity)
{
return std::dynamic_pointer_cast<const ConnectivityToDiamondDualConnectivityDataMapper<Dimension>>(
this->_getDiamondDualConnectivityInfo(connectivity).connectivityToDiamondDualConnectivityDataMapper());
auto i_data_mapper =
this->_getDualConnectivityInfo(DualMeshType::Diamond, connectivity).connectivityToDualConnectivityDataMapper();
auto diamond_data_mapper =
std::dynamic_pointer_cast<const ConnectivityToDiamondDualConnectivityDataMapper<Dimension>>(i_data_mapper);
if (diamond_data_mapper.use_count() > 0) {
return diamond_data_mapper;
} else {
throw UnexpectedError("invalid connectivity data mapper type");
}
}
template std::shared_ptr<const Connectivity<1>> DualConnectivityManager::getDiamondDualConnectivity(
......
#ifndef DUAL_CONNECTIVITY_MANAGER_HPP
#define DUAL_CONNECTIVITY_MANAGER_HPP
#include <mesh/DualMeshType.hpp>
#include <mesh/IConnectivity.hpp>
#include <mesh/IConnectivityToDualConnectivityDataMapper.hpp>
#include <memory>
#include <unordered_map>
......@@ -9,57 +11,63 @@
template <size_t Dimension>
class Connectivity;
class IConnectivityToDiamondDualConnectivityDataMapper;
template <size_t Dimension>
class ConnectivityToDiamondDualConnectivityDataMapper;
class DualConnectivityManager
{
private:
class DiamondDualConnectivityInfo
class DualConnectivityInfo
{
private:
std::shared_ptr<const IConnectivity> m_diamond_dual_connectivity;
std::shared_ptr<const IConnectivityToDiamondDualConnectivityDataMapper>
m_connectivity_to_diamond_dual_connectivity_data_mapper;
std::shared_ptr<const IConnectivity> m_dual_connectivity;
std::shared_ptr<const IConnectivityToDualConnectivityDataMapper> m_connectivity_to_dual_connectivity_data_mapper;
public:
PUGS_INLINE
std::shared_ptr<const IConnectivity>
diamondDualConnectivity() const
dualConnectivity() const
{
return m_diamond_dual_connectivity;
return m_dual_connectivity;
}
PUGS_INLINE
std::shared_ptr<const IConnectivityToDiamondDualConnectivityDataMapper>
connectivityToDiamondDualConnectivityDataMapper()
std::shared_ptr<const IConnectivityToDualConnectivityDataMapper>
connectivityToDualConnectivityDataMapper()
{
return m_connectivity_to_diamond_dual_connectivity_data_mapper;
return m_connectivity_to_dual_connectivity_data_mapper;
}
DiamondDualConnectivityInfo& operator=(const DiamondDualConnectivityInfo&) = default;
DiamondDualConnectivityInfo& operator=(DiamondDualConnectivityInfo&&) = default;
DualConnectivityInfo& operator=(const DualConnectivityInfo&) = default;
DualConnectivityInfo& operator=(DualConnectivityInfo&&) = default;
DiamondDualConnectivityInfo() = default;
DiamondDualConnectivityInfo(const DiamondDualConnectivityInfo&) = default;
DiamondDualConnectivityInfo(DiamondDualConnectivityInfo&&) = default;
DualConnectivityInfo() = default;
DualConnectivityInfo(const DualConnectivityInfo&) = default;
DualConnectivityInfo(DualConnectivityInfo&&) = 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}
DualConnectivityInfo(const std::shared_ptr<const IConnectivity>& dual_connectivity,
const std::shared_ptr<const IConnectivityToDualConnectivityDataMapper>&
connectivity_to_dual_connectivity_data_mapper)
: m_dual_connectivity{dual_connectivity},
m_connectivity_to_dual_connectivity_data_mapper{connectivity_to_dual_connectivity_data_mapper}
{}
~DiamondDualConnectivityInfo() = default;
~DualConnectivityInfo() = default;
};
DiamondDualConnectivityInfo _getDiamondDualConnectivityInfo(const IConnectivity& connectivity);
DualConnectivityInfo _getDualConnectivityInfo(const DualMeshType& type, const IConnectivity& connectivity);
using Key = std::pair<DualMeshType, const IConnectivity*>;
struct HashKey
{
size_t
operator()(const Key& key) const
{
return (std::hash<typename Key::first_type>()(key.first)) ^ (std::hash<typename Key::second_type>()(key.second));
}
};
std::unordered_map<const IConnectivity*, DiamondDualConnectivityInfo>
m_connectivity_to_diamond_dual_connectivity_info_map;
std::unordered_map<Key, DualConnectivityInfo, HashKey> m_connectivity_to_dual_connectivity_info_map;
static DualConnectivityManager* m_instance;
......
......@@ -22,11 +22,12 @@ DualMeshManager::destroy()
{
Assert(m_instance != nullptr, "DualMeshManager was not created!");
if (m_instance->m_mesh_to_diamond_dual_mesh_map.size() > 0) {
if (m_instance->m_mesh_to_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';
for (const auto& [key, parent_mesh] : m_instance->m_mesh_to_dual_mesh_map) {
error << " - mesh " << rang::fgB::magenta << key.second << rang::style::reset << ": " << name(key.first)
<< " dual mesh of " << rang::fgB::yellow << parent_mesh.get() << rang::style::reset << '\n';
}
throw UnexpectedError(error.str());
}
......@@ -37,7 +38,18 @@ DualMeshManager::destroy()
void
DualMeshManager::deleteMesh(const IMesh* p_mesh)
{
m_mesh_to_diamond_dual_mesh_map.erase(p_mesh);
bool has_removed = false;
do {
has_removed = false;
for (const auto& [key, dual_mesh] : m_mesh_to_dual_mesh_map) {
const auto& [type, p_parent_mesh] = key;
if (p_mesh == p_parent_mesh) {
m_mesh_to_dual_mesh_map.erase(key);
has_removed = true;
break;
}
}
} while (has_removed);
}
template <size_t Dimension>
......@@ -46,13 +58,13 @@ DualMeshManager::getDiamondDualMesh(std::shared_ptr<const Mesh<Connectivity<Dime
{
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()) {
auto key = std::make_pair(DualMeshType::Diamond, p_mesh);
if (auto i_mesh_data = m_mesh_to_dual_mesh_map.find(key); i_mesh_data != m_mesh_to_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();
m_mesh_to_dual_mesh_map[key] = builder.mesh();
return std::dynamic_pointer_cast<const Mesh<Connectivity<Dimension>>>(builder.mesh());
}
}
......
#ifndef DUAL_MESH_MANAGER_HPP
#define DUAL_MESH_MANAGER_HPP
#include <mesh/DualMeshType.hpp>
#include <mesh/IMesh.hpp>
#include <utils/PugsAssert.hpp>
#include <utils/PugsMacros.hpp>
......@@ -14,16 +15,20 @@ class Connectivity;
template <typename ConnectivityType>
class Mesh;
enum class DualMeshType
{
Diamond,
Classic
};
class DualMeshManager
{
private:
std::unordered_map<const IMesh*, std::shared_ptr<const IMesh>> m_mesh_to_diamond_dual_mesh_map;
using Key = std::pair<DualMeshType, const IMesh*>;
struct HashKey
{
size_t
operator()(const Key& key) const
{
return (std::hash<typename Key::first_type>()(key.first)) ^ (std::hash<typename Key::second_type>()(key.second));
}
};
std::unordered_map<Key, std::shared_ptr<const IMesh>, HashKey> m_mesh_to_dual_mesh_map;
static DualMeshManager* m_instance;
......
#ifndef DUAL_MESH_TYPE_HPP
#define DUAL_MESH_TYPE_HPP
#include <utils/Exceptions.hpp>
#include <utils/PugsMacros.hpp>
#include <string>
enum class DualMeshType
{
Classic,
Diamond
};
PUGS_INLINE
std::string
name(DualMeshType type)
{
switch (type) {
case DualMeshType::Classic: {
return "classic";
}
case DualMeshType::Diamond: {
return "diamond";
}
default: {
throw UnexpectedError("unexpected dual mesh type");
}
}
}
#endif // DUAL_MESH_TYPE_HPP
#ifndef I_CONNECTIVITY_TO_DUAL_CONNECTIVITY_DATA_MAPPER_HPP
#define I_CONNECTIVITY_TO_DUAL_CONNECTIVITY_DATA_MAPPER_HPP
class IConnectivityToDualConnectivityDataMapper
{
public:
IConnectivityToDualConnectivityDataMapper(const IConnectivityToDualConnectivityDataMapper&) = delete;
IConnectivityToDualConnectivityDataMapper(IConnectivityToDualConnectivityDataMapper&&) = delete;
IConnectivityToDualConnectivityDataMapper() = default;
virtual ~IConnectivityToDualConnectivityDataMapper() = default;
};
#endif // I_CONNECTIVITY_TO_DUAL_CONNECTIVITY_DATA_MAPPER_HPP
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment