Skip to content
Snippets Groups Projects
Commit d5c677db authored by Norihiro Watanabe's avatar Norihiro Watanabe
Browse files

[Mesh] support searching boundary nodes in NodeSearch

parent bb0a63c0
No related branches found
No related tags found
No related merge requests found
...@@ -69,6 +69,63 @@ std::size_t NodeSearch::searchUnused() ...@@ -69,6 +69,63 @@ std::size_t NodeSearch::searchUnused()
return del_node_idx.size(); return del_node_idx.size();
} }
std::size_t NodeSearch::searchBoundaryNodes()
{
std::vector<std::size_t> vec_boundary_nodes;
if (_mesh.getDimension() == 1)
{
for (MeshLib::Node const* n : _mesh.getNodes())
if (n->getElements().size() == 1)
vec_boundary_nodes.push_back(n->getID());
}
else if (_mesh.getDimension() == 2)
{
for (MeshLib::Element const* elem : _mesh.getElements())
{
if (elem->getDimension() < _mesh.getDimension())
continue;
if (!elem->isBoundaryElement())
continue;
std::size_t const n_edges (elem->getNumberOfEdges());
for (std::size_t i=0; i<n_edges; ++i)
{
if (elem->getNeighbor(i) != nullptr)
continue;
std::unique_ptr<MeshLib::Element const> edge(elem->getEdge(i));
for (unsigned j=0; j<edge->getNumberOfNodes(); j++)
vec_boundary_nodes.push_back(edge->getNode(j)->getID());
}
}
}
else
{
for (MeshLib::Element const* elem : _mesh.getElements())
{
if (elem->getDimension() < _mesh.getDimension())
continue;
if (!elem->isBoundaryElement())
continue;
std::size_t const n_faces (elem->getNumberOfFaces());
for (std::size_t i=0; i<n_faces; ++i)
{
if (elem->getNeighbor(i) != nullptr)
continue;
std::unique_ptr<MeshLib::Element const> face(elem->getFace(i));
for (unsigned j=0; j<face->getNumberOfNodes(); j++)
vec_boundary_nodes.push_back(face->getNode(j)->getID());
}
}
}
std::sort(vec_boundary_nodes.begin(), vec_boundary_nodes.end());
vec_boundary_nodes.erase(std::unique(vec_boundary_nodes.begin(), vec_boundary_nodes.end()), vec_boundary_nodes.end());
this->updateUnion(vec_boundary_nodes);
return vec_boundary_nodes.size();
}
void NodeSearch::updateUnion(const std::vector<std::size_t> &vec) void NodeSearch::updateUnion(const std::vector<std::size_t> &vec)
{ {
std::vector<std::size_t> vec_temp(vec.size() + _marked_nodes.size()); std::vector<std::size_t> vec_temp(vec.size() + _marked_nodes.size());
......
...@@ -36,6 +36,9 @@ public: ...@@ -36,6 +36,9 @@ public:
/// Marks all unused nodes /// Marks all unused nodes
std::size_t searchUnused(); std::size_t searchUnused();
/// Marks all boundary nodes
std::size_t searchBoundaryNodes();
private: private:
/// Updates the vector of marked items with values from vec. /// Updates the vector of marked items with values from vec.
void updateUnion(const std::vector<std::size_t> &vec); void updateUnion(const std::vector<std::size_t> &vec);
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "MeshLib/Elements/Element.h" #include "MeshLib/Elements/Element.h"
#include "MeshLib/MeshSearch/NodeSearch.h" #include "MeshLib/MeshSearch/NodeSearch.h"
#include "MeshLib/MeshGenerators/RasterToMesh.h" #include "MeshLib/MeshGenerators/RasterToMesh.h"
#include "MeshLib/MeshGenerators/MeshGenerator.h"
#include "MeshLib/MeshEditing/DuplicateMeshComponents.h" #include "MeshLib/MeshEditing/DuplicateMeshComponents.h"
#include "GeoLib/Raster.h" #include "GeoLib/Raster.h"
...@@ -45,4 +46,61 @@ TEST(NodeSearch, UnusedNodes) ...@@ -45,4 +46,61 @@ TEST(NodeSearch, UnusedNodes)
} }
TEST(NodeSearch, BoundaryNodes1D)
{
std::unique_ptr<MeshLib::Mesh> mesh (MeshLib::MeshGenerator::generateLineMesh(5, 1.0));
MeshLib::NodeSearch ns(*mesh);
ns.searchBoundaryNodes();
std::vector<std::size_t> searched_nodes = ns.getSearchedNodeIDs();
ASSERT_EQ(2, searched_nodes.size());
ASSERT_EQ(0u, searched_nodes[0]);
ASSERT_EQ(5u, searched_nodes[1]);
}
TEST(NodeSearch, BoundaryNodes2D)
{
std::unique_ptr<MeshLib::Mesh> mesh (MeshLib::MeshGenerator::generateRegularQuadMesh(5, 5, 1.0, 1.0));
MeshLib::NodeSearch ns(*mesh);
ns.searchBoundaryNodes();
std::vector<std::size_t> searched_nodes = ns.getSearchedNodeIDs();
ASSERT_EQ(20, searched_nodes.size());
for (auto nodeid : searched_nodes)
{
auto &node = *mesh->getNode(nodeid);
bool isOnBnd = false;
for (unsigned i=0; i<mesh->getDimension(); i++)
{
if (node[i]==0.0 || node[i]==5.0)
{
isOnBnd = true;
break;
}
}
ASSERT_TRUE(isOnBnd);
}
}
TEST(NodeSearch, BoundaryNodes3D)
{
std::unique_ptr<MeshLib::Mesh> mesh (MeshLib::MeshGenerator::generateRegularHexMesh(5, 5, 5, 1.0, 1.0, 1.0));
MeshLib::NodeSearch ns(*mesh);
ns.searchBoundaryNodes();
std::vector<std::size_t> searched_nodes = ns.getSearchedNodeIDs();
ASSERT_EQ(152u, searched_nodes.size());
for (auto nodeid : searched_nodes)
{
auto &node = *mesh->getNode(nodeid);
bool isOnBnd = false;
for (unsigned i=0; i<mesh->getDimension(); i++)
{
if (node[i]==0.0 || node[i]==5.0)
{
isOnBnd = true;
break;
}
}
ASSERT_TRUE(isOnBnd);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment