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

Begin introduction of dual mesh builder

parent 4720e70c
No related branches found
No related tags found
1 merge request!125Rename DualConnectivityBuilder and MedianDualMeshBuilder's files
......@@ -166,6 +166,37 @@ MeshModule::MeshModule()
}
}
));
this->_addBuiltinFunction("dual", std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<const IMesh>(
const std::shared_ptr<const IMesh>&)>>(
[](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 DualMeshManager::instance().getDualMesh(p_mesh);
}
case 2: {
using MeshType = Mesh<Connectivity<2>>;
std::shared_ptr p_mesh = std::dynamic_pointer_cast<const MeshType>(i_mesh);
return DualMeshManager::instance().getDualMesh(p_mesh);
}
case 3: {
using MeshType = Mesh<Connectivity<3>>;
std::shared_ptr p_mesh = std::dynamic_pointer_cast<const MeshType>(i_mesh);
return DualMeshManager::instance().getDualMesh(p_mesh);
}
default: {
throw UnexpectedError("invalid dimension");
}
}
}
));
}
......
......@@ -9,7 +9,9 @@ add_library(
ConnectivityDispatcher.cpp
DiamondDualConnectivityBuilder.cpp
DiamondDualMeshBuilder.cpp
DualConnectivityBuilder.cpp
DualConnectivityManager.cpp
DualMeshBuilder.cpp
DualMeshManager.cpp
GmshReader.cpp
IConnectivity.cpp
......
#ifndef CONNECTIVITY_TO_DUAL_CONNECTIVITY_DATA_MAPPER_HPP
#define CONNECTIVITY_TO_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>
template <size_t Dimension>
class ConnectivityToDualConnectivityDataMapper : public IConnectivityToDualConnectivityDataMapper
{
private:
const IConnectivity* m_primal_connectivity;
const IConnectivity* m_dual_connectivity;
NodeIdToNodeIdMap m_primal_node_to_dual_node_map;
CellIdToNodeIdMap m_primal_cell_to_dual_node_map;
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];
});
}
ConnectivityToDualConnectivityDataMapper(const Connectivity<Dimension>& primal_connectivity,
const Connectivity<Dimension>& dual_connectivity,
const NodeIdToNodeIdMap& primal_node_to_dual_node_map,
const CellIdToNodeIdMap& primal_cell_to_dual_node_map,
const FaceIdToCellIdMap& primal_face_to_dual_cell_map)
: m_primal_connectivity{&primal_connectivity},
m_dual_connectivity{&dual_connectivity},
m_primal_node_to_dual_node_map{primal_node_to_dual_node_map},
m_primal_cell_to_dual_node_map{primal_cell_to_dual_node_map},
m_primal_face_to_dual_cell_map{primal_face_to_dual_cell_map}
{}
};
#endif // CONNECTIVITY_TO_DUAL_CONNECTIVITY_DATA_MAPPER_HPP
......@@ -2,7 +2,6 @@
#include <mesh/Connectivity.hpp>
#include <mesh/ConnectivityToDiamondDualConnectivityDataMapper.hpp>
#include <mesh/DiamondDualConnectivityBuilder.hpp>
#include <mesh/DualConnectivityManager.hpp>
#include <mesh/ItemValueUtils.hpp>
#include <mesh/Mesh.hpp>
......
This diff is collapsed.
#ifndef DUAL_CONNECTIVITY_BUILDER_HPP
#define DUAL_CONNECTIVITY_BUILDER_HPP
#include <mesh/ConnectivityBuilderBase.hpp>
#include <mesh/IConnectivityToDualConnectivityDataMapper.hpp>
#include <mesh/ItemIdToItemIdMap.hpp>
#include <memory>
template <size_t>
class Connectivity;
class ConnectivityDescriptor;
class DualConnectivityBuilder : public ConnectivityBuilderBase
{
private:
NodeIdToNodeIdMap m_primal_node_to_dual_node_map;
CellIdToNodeIdMap m_primal_cell_to_dual_node_map;
FaceIdToCellIdMap m_primal_face_to_dual_cell_map;
std::shared_ptr<IConnectivityToDualConnectivityDataMapper> m_mapper;
template <size_t Dimension>
void _buildConnectivityDescriptor(const Connectivity<Dimension>&, ConnectivityDescriptor&);
template <size_t Dimension>
void _buildConnectivityFrom(const IConnectivity&);
friend class DualConnectivityManager;
DualConnectivityBuilder(const IConnectivity&);
public:
std::shared_ptr<IConnectivityToDualConnectivityDataMapper>
mapper() const
{
return m_mapper;
}
~DualConnectivityBuilder() = default;
};
#endif // DUAL_CONNECTIVITY_BUILDER_HPP
......@@ -2,7 +2,9 @@
#include <mesh/Connectivity.hpp>
#include <mesh/ConnectivityToDiamondDualConnectivityDataMapper.hpp>
#include <mesh/ConnectivityToDualConnectivityDataMapper.hpp>
#include <mesh/DiamondDualConnectivityBuilder.hpp>
#include <mesh/DualConnectivityBuilder.hpp>
#include <mesh/DualConnectivityManager.hpp>
#include <utils/Exceptions.hpp>
......@@ -53,6 +55,16 @@ DualConnectivityManager::deleteConnectivity(const IConnectivity* p_connectivity)
} while (has_removed);
}
template <typename DualConnectivityBuilderType>
DualConnectivityManager::DualConnectivityInfo
DualConnectivityManager::_buildDualConnectivity(const Key& key, const IConnectivity& connectivity)
{
DualConnectivityBuilderType builder{connectivity};
DualConnectivityInfo connectivity_info{builder.connectivity(), builder.mapper()};
m_connectivity_to_dual_connectivity_info_map[key] = connectivity_info;
return connectivity_info;
}
DualConnectivityManager::DualConnectivityInfo
DualConnectivityManager::_getDualConnectivityInfo(const DualMeshType& type, const IConnectivity& connectivity)
{
......@@ -63,13 +75,17 @@ DualConnectivityManager::_getDualConnectivityInfo(const DualMeshType& type, cons
i_connectivity != m_connectivity_to_dual_connectivity_info_map.end()) {
return i_connectivity->second;
} else {
DiamondDualConnectivityBuilder builder{connectivity};
DualConnectivityInfo connectivity_info{builder.connectivity(), builder.mapper()};
m_connectivity_to_dual_connectivity_info_map[key] = connectivity_info;
return connectivity_info;
switch (type) {
case DualMeshType::Classic: {
return this->_buildDualConnectivity<DualConnectivityBuilder>(key, connectivity);
}
case DualMeshType::Diamond: {
return this->_buildDualConnectivity<DiamondDualConnectivityBuilder>(key, connectivity);
}
default: {
throw UnexpectedError("invalid dual mesh type");
}
}
}
}
......@@ -97,6 +113,30 @@ DualConnectivityManager::getConnectivityToDiamondDualConnectivityDataMapper(cons
}
}
template <size_t Dimension>
std::shared_ptr<const Connectivity<Dimension>>
DualConnectivityManager::getDualConnectivity(const Connectivity<Dimension>& connectivity)
{
return std::dynamic_pointer_cast<const Connectivity<Dimension>>(
this->_getDualConnectivityInfo(DualMeshType::Classic, connectivity).dualConnectivity());
}
template <size_t Dimension>
std::shared_ptr<const ConnectivityToDualConnectivityDataMapper<Dimension>>
DualConnectivityManager::getConnectivityToDualConnectivityDataMapper(const Connectivity<Dimension>& connectivity)
{
auto i_data_mapper =
this->_getDualConnectivityInfo(DualMeshType::Classic, connectivity).connectivityToDualConnectivityDataMapper();
auto data_mapper =
std::dynamic_pointer_cast<const ConnectivityToDualConnectivityDataMapper<Dimension>>(i_data_mapper);
if (data_mapper.use_count() > 0) {
return data_mapper;
} else {
throw UnexpectedError("invalid connectivity data mapper type");
}
}
template std::shared_ptr<const Connectivity<1>> DualConnectivityManager::getDiamondDualConnectivity(
const Connectivity<1>& connectivity);
......@@ -114,3 +154,21 @@ DualConnectivityManager::getConnectivityToDiamondDualConnectivityDataMapper(cons
template std::shared_ptr<const ConnectivityToDiamondDualConnectivityDataMapper<3>>
DualConnectivityManager::getConnectivityToDiamondDualConnectivityDataMapper(const Connectivity<3>&);
template std::shared_ptr<const Connectivity<1>> DualConnectivityManager::getDualConnectivity(
const Connectivity<1>& connectivity);
template std::shared_ptr<const Connectivity<2>> DualConnectivityManager::getDualConnectivity(
const Connectivity<2>& connectivity);
template std::shared_ptr<const Connectivity<3>> DualConnectivityManager::getDualConnectivity(
const Connectivity<3>& connectivity);
template std::shared_ptr<const ConnectivityToDualConnectivityDataMapper<1>>
DualConnectivityManager::getConnectivityToDualConnectivityDataMapper(const Connectivity<1>&);
template std::shared_ptr<const ConnectivityToDualConnectivityDataMapper<2>>
DualConnectivityManager::getConnectivityToDualConnectivityDataMapper(const Connectivity<2>&);
template std::shared_ptr<const ConnectivityToDualConnectivityDataMapper<3>>
DualConnectivityManager::getConnectivityToDualConnectivityDataMapper(const Connectivity<3>&);
......@@ -14,6 +14,9 @@ class Connectivity;
template <size_t Dimension>
class ConnectivityToDiamondDualConnectivityDataMapper;
template <size_t Dimension>
class ConnectivityToDualConnectivityDataMapper;
class DualConnectivityManager
{
private:
......@@ -55,8 +58,6 @@ class DualConnectivityManager
~DualConnectivityInfo() = default;
};
DualConnectivityInfo _getDualConnectivityInfo(const DualMeshType& type, const IConnectivity& connectivity);
using Key = std::pair<DualMeshType, const IConnectivity*>;
struct HashKey
{
......@@ -67,6 +68,11 @@ class DualConnectivityManager
}
};
template <typename DualConnectivityBuilderType>
DualConnectivityInfo _buildDualConnectivity(const Key& key, const IConnectivity& connectivity);
DualConnectivityInfo _getDualConnectivityInfo(const DualMeshType& type, const IConnectivity& connectivity);
std::unordered_map<Key, DualConnectivityInfo, HashKey> m_connectivity_to_dual_connectivity_info_map;
static DualConnectivityManager* m_instance;
......@@ -91,6 +97,13 @@ class DualConnectivityManager
void deleteConnectivity(const IConnectivity*);
template <size_t Dimension>
std::shared_ptr<const Connectivity<Dimension>> getDualConnectivity(const Connectivity<Dimension>&);
template <size_t Dimension>
std::shared_ptr<const ConnectivityToDualConnectivityDataMapper<Dimension>>
getConnectivityToDualConnectivityDataMapper(const Connectivity<Dimension>&);
template <size_t Dimension>
std::shared_ptr<const Connectivity<Dimension>> getDiamondDualConnectivity(const Connectivity<Dimension>&);
......
#include <mesh/DualMeshBuilder.hpp>
#include <mesh/Connectivity.hpp>
#include <mesh/ConnectivityToDualConnectivityDataMapper.hpp>
#include <mesh/DualConnectivityManager.hpp>
#include <mesh/ItemValueUtils.hpp>
#include <mesh/Mesh.hpp>
#include <mesh/MeshData.hpp>
#include <mesh/MeshDataManager.hpp>
template <size_t Dimension>
void
DualMeshBuilder::_buildDualMeshFrom(const std::shared_ptr<const IMesh>& p_i_mesh)
{
using ConnectivityType = Connectivity<Dimension>;
using MeshType = Mesh<Connectivity<Dimension>>;
std::shared_ptr p_primal_mesh = std::dynamic_pointer_cast<const MeshType>(p_i_mesh);
const MeshType& primal_mesh = *p_primal_mesh;
DualConnectivityManager& manager = DualConnectivityManager::instance();
std::shared_ptr<const ConnectivityType> p_dual_connectivity = manager.getDualConnectivity(primal_mesh.connectivity());
const ConnectivityType& dual_connectivity = *p_dual_connectivity;
const NodeValue<const TinyVector<Dimension>> primal_xr = primal_mesh.xr();
MeshData<Dimension>& primal_mesh_data = MeshDataManager::instance().getMeshData(primal_mesh);
const CellValue<const TinyVector<Dimension>> primal_xj = primal_mesh_data.xj();
std::shared_ptr connectivity_to_dual_connectivity_data_mapper =
manager.getConnectivityToDualConnectivityDataMapper(primal_mesh.connectivity());
NodeValue<TinyVector<Dimension>> dual_xr{dual_connectivity};
connectivity_to_dual_connectivity_data_mapper->toDualNode(primal_xr, primal_xj, dual_xr);
m_mesh = std::make_shared<MeshType>(p_dual_connectivity, dual_xr);
}
DualMeshBuilder::DualMeshBuilder(const std::shared_ptr<const IMesh>& p_mesh)
{
std::cout << "building DualMesh\n";
switch (p_mesh->dimension()) {
case 1: {
this->_buildDualMeshFrom<1>(p_mesh);
break;
}
case 2: {
this->_buildDualMeshFrom<2>(p_mesh);
break;
}
case 3: {
this->_buildDualMeshFrom<3>(p_mesh);
break;
}
default: {
throw UnexpectedError("invalid mesh dimension: " + std::to_string(p_mesh->dimension()));
}
}
}
#ifndef DUAL_MESH_BUILDER_HPP
#define DUAL_MESH_BUILDER_HPP
#include <mesh/MeshBuilderBase.hpp>
#include <memory>
class DualMeshBuilder : public MeshBuilderBase
{
private:
template <size_t Dimension>
void _buildDualMeshFrom(const std::shared_ptr<const IMesh>&);
friend class DualMeshManager;
DualMeshBuilder(const std::shared_ptr<const IMesh>&);
public:
~DualMeshBuilder() = default;
};
#endif // DUAL_MESH_BUILDER_HPP
......@@ -2,6 +2,7 @@
#include <mesh/Connectivity.hpp>
#include <mesh/DiamondDualMeshBuilder.hpp>
#include <mesh/DualMeshBuilder.hpp>
#include <mesh/Mesh.hpp>
#include <utils/Exceptions.hpp>
#include <utils/PugsAssert.hpp>
......@@ -52,6 +53,23 @@ DualMeshManager::deleteMesh(const IMesh* p_mesh)
} while (has_removed);
}
template <size_t Dimension>
std::shared_ptr<const Mesh<Connectivity<Dimension>>>
DualMeshManager::getDualMesh(std::shared_ptr<const Mesh<Connectivity<Dimension>>> mesh)
{
const IMesh* p_mesh = mesh.get();
auto key = std::make_pair(DualMeshType::Classic, 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 {
DualMeshBuilder builder{mesh};
m_mesh_to_dual_mesh_map[key] = builder.mesh();
return std::dynamic_pointer_cast<const Mesh<Connectivity<Dimension>>>(builder.mesh());
}
}
template <size_t Dimension>
std::shared_ptr<const Mesh<Connectivity<Dimension>>>
DualMeshManager::getDiamondDualMesh(std::shared_ptr<const Mesh<Connectivity<Dimension>>> mesh)
......@@ -69,6 +87,13 @@ DualMeshManager::getDiamondDualMesh(std::shared_ptr<const Mesh<Connectivity<Dime
}
}
template std::shared_ptr<const Mesh<Connectivity<1>>> DualMeshManager::getDualMesh(
std::shared_ptr<const Mesh<Connectivity<1>>>);
template std::shared_ptr<const Mesh<Connectivity<2>>> DualMeshManager::getDualMesh(
std::shared_ptr<const Mesh<Connectivity<2>>>);
template std::shared_ptr<const Mesh<Connectivity<3>>> DualMeshManager::getDualMesh(
std::shared_ptr<const Mesh<Connectivity<3>>>);
template std::shared_ptr<const Mesh<Connectivity<1>>> DualMeshManager::getDiamondDualMesh(
std::shared_ptr<const Mesh<Connectivity<1>>>);
template std::shared_ptr<const Mesh<Connectivity<2>>> DualMeshManager::getDiamondDualMesh(
......
......@@ -55,6 +55,10 @@ class DualMeshManager
template <size_t Dimension>
std::shared_ptr<const Mesh<Connectivity<Dimension>>> getDiamondDualMesh(
std::shared_ptr<const Mesh<Connectivity<Dimension>>>);
template <size_t Dimension>
std::shared_ptr<const Mesh<Connectivity<Dimension>>> getDualMesh(
std::shared_ptr<const Mesh<Connectivity<Dimension>>>);
};
#endif // DUAL_MESH_MANAGER_HPP
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment