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

Add a set of functions to check if items are on the domain boundary

isBoundaryFace(), isBoundaryEdge() and isBoundaryNode() which returns
boolean ItemValue's

Also add a template version isBoundary<item_type>() to ease generic
programming.
parent 46c4d948
No related branches found
No related tags found
1 merge request!132Reduce memory use and allocations for some connectivity descriptors
#include <mesh/Connectivity.hpp>
#include <mesh/ConnectivityDescriptor.hpp>
#include <mesh/ItemValueUtils.hpp>
#include <utils/Messenger.hpp>
#include <map>
......@@ -152,6 +153,91 @@ Connectivity<Dimension>::_buildFrom(const ConnectivityDescriptor& descriptor)
}
}
template <size_t Dimension>
void
Connectivity<Dimension>::_buildIsBoundaryFace() const
{
Array<bool> is_face_boundary_array(this->numberOfFaces());
WeakFaceValue<bool> is_boundary_face(*this, is_face_boundary_array);
const auto& face_to_cell_matrix = this->faceToCellMatrix();
const auto& face_is_owned = this->faceIsOwned();
parallel_for(
this->numberOfFaces(), PUGS_LAMBDA(const FaceId face_id) {
is_boundary_face[face_id] = face_is_owned[face_id] and (face_to_cell_matrix[face_id].size() == 1);
});
synchronize(is_boundary_face);
const_cast<WeakFaceValue<const bool>&>(m_is_boundary_face) = is_boundary_face;
if constexpr (Dimension <= 2) {
const_cast<WeakEdgeValue<const bool>&>(m_is_boundary_edge) = WeakEdgeValue<bool>(*this, is_face_boundary_array);
if constexpr (Dimension == 1) {
const_cast<WeakNodeValue<const bool>&>(m_is_boundary_node) = WeakNodeValue<bool>(*this, is_face_boundary_array);
} else {
static_assert(Dimension == 2, "unexpected dimension");
}
}
}
template <size_t Dimension>
void
Connectivity<Dimension>::_buildIsBoundaryEdge() const
{
if constexpr (Dimension < 3) {
this->_buildIsBoundaryFace();
} else {
auto is_boundary_face = this->isBoundaryFace();
WeakEdgeValue<bool> is_boundary_edge(*this);
is_boundary_edge.fill(false);
const auto& face_to_edge_matrix = this->faceToEdgeMatrix();
for (FaceId face_id = 0; face_id < this->numberOfFaces(); ++face_id) {
if (is_boundary_face[face_id]) {
auto face_edge = face_to_edge_matrix[face_id];
for (size_t i_edge = 0; i_edge < face_edge.size(); ++i_edge) {
is_boundary_edge[face_edge[i_edge]] = true;
}
}
}
synchronize(is_boundary_edge);
const_cast<WeakEdgeValue<const bool>&>(m_is_boundary_edge) = is_boundary_edge;
}
}
template <size_t Dimension>
void
Connectivity<Dimension>::_buildIsBoundaryNode() const
{
if constexpr (Dimension == 1) {
this->_buildIsBoundaryFace();
} else {
auto is_boundary_face = this->isBoundaryFace();
WeakNodeValue<bool> is_boundary_node(*this);
is_boundary_node.fill(false);
const auto& face_to_node_matrix = this->faceToNodeMatrix();
for (FaceId face_id = 0; face_id < this->numberOfFaces(); ++face_id) {
if (is_boundary_face[face_id]) {
auto face_nodes = face_to_node_matrix[face_id];
for (size_t i_node = 0; i_node < face_nodes.size(); ++i_node) {
is_boundary_node[face_nodes[i_node]] = true;
}
}
}
synchronize(is_boundary_node);
const_cast<WeakNodeValue<const bool>&>(m_is_boundary_node) = is_boundary_node;
}
}
template void Connectivity<1>::_buildIsBoundaryFace() const;
template void Connectivity<2>::_buildIsBoundaryFace() const;
template void Connectivity<3>::_buildIsBoundaryFace() const;
template void Connectivity<1>::_buildIsBoundaryEdge() const;
template void Connectivity<2>::_buildIsBoundaryEdge() const;
template void Connectivity<3>::_buildIsBoundaryEdge() const;
template void Connectivity<1>::_buildIsBoundaryNode() const;
template void Connectivity<2>::_buildIsBoundaryNode() const;
template void Connectivity<3>::_buildIsBoundaryNode() const;
template Connectivity<1>::Connectivity();
template Connectivity<2>::Connectivity();
template Connectivity<3>::Connectivity();
......
......@@ -62,19 +62,22 @@ class Connectivity final : public IConnectivity
WeakFaceValue<const int> m_face_owner;
WeakFaceValue<const bool> m_face_is_owned;
WeakFaceValue<const bool> m_is_boundary_face;
WeakEdgeValue<const int> m_edge_owner;
WeakEdgeValue<const bool> m_edge_is_owned;
WeakEdgeValue<const bool> m_is_boundary_edge;
WeakNodeValue<const int> m_node_owner;
WeakNodeValue<const bool> m_node_is_owned;
WeakNodeValue<const bool> m_is_boundary_node;
WeakFaceValuePerCell<const bool> m_cell_face_is_reversed;
WeakEdgeValuePerFace<const bool> m_face_edge_is_reversed;
WeakNodeValuePerCell<const unsigned short> m_cell_local_numbers_in_their_nodes;
WeakEdgeValuePerCell<const unsigned short> m_cell_local_numbers_in_their_edges;
WeakFaceValuePerCell<const unsigned short> m_cell_local_numbers_in_their_faces;
WeakEdgeValuePerCell<const unsigned short> m_cell_local_numbers_in_their_edges;
WeakCellValuePerFace<const unsigned short> m_face_local_numbers_in_their_cells;
WeakEdgeValuePerFace<const unsigned short> m_face_local_numbers_in_their_edges;
......@@ -85,8 +88,8 @@ class Connectivity final : public IConnectivity
WeakNodeValuePerEdge<const unsigned short> m_edge_local_numbers_in_their_nodes;
WeakCellValuePerNode<const unsigned short> m_node_local_numbers_in_their_cells;
WeakEdgeValuePerNode<const unsigned short> m_node_local_numbers_in_their_edges;
WeakFaceValuePerNode<const unsigned short> m_node_local_numbers_in_their_faces;
WeakEdgeValuePerNode<const unsigned short> m_node_local_numbers_in_their_edges;
ConnectivityComputer m_connectivity_computer;
......@@ -99,6 +102,10 @@ class Connectivity final : public IConnectivity
void _computeCellFaceAndFaceNodeConnectivities();
void _buildIsBoundaryFace() const;
void _buildIsBoundaryEdge() const;
void _buildIsBoundaryNode() const;
template <typename SubItemValuePerItemType>
PUGS_INLINE const SubItemValuePerItemType&
_lazzyBuildItemNumberInTheirChild(const SubItemValuePerItemType& sub_item_value_per_item) const
......@@ -268,6 +275,52 @@ class Connectivity final : public IConnectivity
}
}
PUGS_INLINE
const auto&
isBoundaryFace() const
{
if (not m_is_boundary_face.isBuilt()) {
this->_buildIsBoundaryFace();
}
return m_is_boundary_face;
}
PUGS_INLINE
const auto&
isBoundaryEdge() const
{
if (not m_is_boundary_edge.isBuilt()) {
this->_buildIsBoundaryEdge();
}
return m_is_boundary_edge;
}
PUGS_INLINE
const auto&
isBoundaryNode() const
{
if (not m_is_boundary_node.isBuilt()) {
this->_buildIsBoundaryNode();
}
return m_is_boundary_node;
}
template <ItemType item_type>
PUGS_INLINE const auto&
isBoundary() const
{
if constexpr (item_type == ItemType::face) {
return isBoundaryFace();
} else if constexpr (item_type == ItemType::edge) {
return isBoundaryEdge();
} else if constexpr (item_type == ItemType::node) {
return isBoundaryNode();
} else {
static_assert(item_type != ItemType::cell, "cell boundary makes no sense");
static_assert(is_false_item_type_v<item_type>, "unknown ItemType");
}
}
PUGS_INLINE
const bool&
isConnectivityMatrixBuilt(ItemType item_type_0, ItemType item_type_1) const
......
......@@ -156,6 +156,7 @@ add_executable (unit_tests
add_executable (mpi_unit_tests
mpi_test_main.cpp
test_Connectivity.cpp
test_DiscreteFunctionInterpoler.cpp
test_DiscreteFunctionP0.cpp
test_DiscreteFunctionP0Vector.cpp
......
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment