OGS
NodeSearch.cpp
Go to the documentation of this file.
1
11#include "NodeSearch.h"
12
13#include <memory>
14#include <set>
15
17#include "MeshLib/Mesh.h"
18#include "MeshLib/Node.h"
19
20namespace MeshLib
21{
22NodeSearch::NodeSearch(const MeshLib::Mesh& mesh) : _mesh(mesh) {}
23
25 const std::vector<std::size_t>& elements)
26{
27 // Find out by how many elements a node would be removed.
28 //
29 // Note: If there are only few elements to be removed, using a different
30 // algorithm might be more memory efficient.
31 std::vector<std::size_t> node_marked_counts(_mesh.getNumberOfNodes(), 0);
32
33 for (std::size_t eid : elements)
34 {
35 auto* e = _mesh.getElement(eid);
36 for (unsigned i = 0; i < e->getNumberOfNodes(); i++)
37 {
38 node_marked_counts[getNodeIndex(*e, i)]++;
39 }
40 }
41
42 // Push back nodes which counts are equal to number of connected elements to
43 // that node.
44 std::vector<std::size_t> connected_nodes;
45 for (std::size_t i = 0; i < node_marked_counts.size(); i++)
46 {
47 if (node_marked_counts[i] ==
49 {
50 connected_nodes.push_back(i);
51 }
52 }
53
54 this->updateUnion(connected_nodes);
55 return connected_nodes.size();
56}
57
59{
60 const std::size_t nNodes(_mesh.getNumberOfNodes());
61 const std::vector<MeshLib::Node*>& nodes(_mesh.getNodes());
62 std::vector<std::size_t> del_node_idx;
63
64 for (unsigned i = 0; i < nNodes; ++i)
65 {
66 if (_mesh.getElementsConnectedToNode(*nodes[i]).empty())
67 {
68 del_node_idx.push_back(i);
69 }
70 }
71
72 this->updateUnion(del_node_idx);
73 return del_node_idx.size();
74}
75
77{
78 std::vector<std::size_t> vec_boundary_nodes;
79 if (_mesh.getDimension() == 1)
80 {
81 for (MeshLib::Node const* n : _mesh.getNodes())
82 {
83 if (_mesh.getElementsConnectedToNode(*n).size() == 1)
84 {
85 vec_boundary_nodes.push_back(n->getID());
86 }
87 }
88 }
89 else if (_mesh.getDimension() == 2)
90 {
91 for (MeshLib::Element const* elem : _mesh.getElements())
92 {
93 if (elem->getDimension() < _mesh.getDimension())
94 {
95 continue;
96 }
97 if (!elem->isBoundaryElement())
98 {
99 continue;
100 }
101
102 std::size_t const n_edges(elem->getNumberOfEdges());
103 for (std::size_t i = 0; i < n_edges; ++i)
104 {
105 if (elem->getNeighbor(i) != nullptr)
106 {
107 continue;
108 }
109 std::unique_ptr<MeshLib::Element const> edge(elem->getEdge(i));
110 for (unsigned j = 0; j < edge->getNumberOfNodes(); j++)
111 {
112 vec_boundary_nodes.push_back(edge->getNode(j)->getID());
113 }
114 }
115 }
116 }
117 else
118 {
119 for (MeshLib::Element const* elem : _mesh.getElements())
120 {
121 if (elem->getDimension() < _mesh.getDimension())
122 {
123 continue;
124 }
125 if (!elem->isBoundaryElement())
126 {
127 continue;
128 }
129
130 std::size_t const n_faces(elem->getNumberOfFaces());
131 for (std::size_t i = 0; i < n_faces; ++i)
132 {
133 if (elem->getNeighbor(i) != nullptr)
134 {
135 continue;
136 }
137 std::unique_ptr<MeshLib::Element const> face(elem->getFace(i));
138 for (unsigned j = 0; j < face->getNumberOfNodes(); j++)
139 {
140 vec_boundary_nodes.push_back(face->getNode(j)->getID());
141 }
142 }
143 }
144 }
145 std::sort(vec_boundary_nodes.begin(), vec_boundary_nodes.end());
146 vec_boundary_nodes.erase(
147 std::unique(vec_boundary_nodes.begin(), vec_boundary_nodes.end()),
148 vec_boundary_nodes.end());
149
150 this->updateUnion(vec_boundary_nodes);
151 return vec_boundary_nodes.size();
152}
153
154void NodeSearch::updateUnion(const std::vector<std::size_t>& vec)
155{
156 std::vector<std::size_t> vec_temp(vec.size() + _marked_nodes.size());
157 auto it = std::set_union(vec.begin(), vec.end(), _marked_nodes.begin(),
158 _marked_nodes.end(), vec_temp.begin());
159 vec_temp.resize(it - vec_temp.begin());
160 _marked_nodes.assign(vec_temp.begin(), vec_temp.end());
161}
162
163std::vector<Node*> getUniqueNodes(std::vector<Element*> const& elements)
164{
165 std::set<Node*> nodes_set;
166 for (auto e : elements)
167 {
168 Node* const* nodes = e->getNodes();
169 unsigned const nnodes = e->getNumberOfNodes();
170 nodes_set.insert(nodes, nodes + nnodes);
171 }
172
173 std::vector<Node*> nodes;
174 nodes.reserve(nodes_set.size());
175
176 std::move(nodes_set.cbegin(), nodes_set.cend(), std::back_inserter(nodes));
177
178 return nodes;
179}
180
181} // end namespace MeshLib
Definition of the Element class.
Definition of the Mesh class.
Definition of the Node class.
std::vector< Node * > const & getNodes() const
Get the nodes-vector for the mesh.
Definition Mesh.h:106
std::vector< Element * > const & getElements() const
Get the element-vector for the mesh.
Definition Mesh.h:109
unsigned getDimension() const
Returns the dimension of the mesh (determined by the maximum dimension over all elements).
Definition Mesh.h:88
const Node * getNode(std::size_t idx) const
Get the node with the given index.
Definition Mesh.h:91
const Element * getElement(std::size_t idx) const
Get the element with the given index.
Definition Mesh.h:94
std::size_t getNumberOfNodes() const
Get the number of nodes.
Definition Mesh.h:100
std::vector< Element const * > const & getElementsConnectedToNode(std::size_t node_id) const
Definition Mesh.cpp:256
std::size_t searchNodesConnectedToOnlyGivenElements(const std::vector< std::size_t > &elements)
std::vector< std::size_t > _marked_nodes
The vector of element indices that should be removed.
Definition NodeSearch.h:50
std::size_t searchBoundaryNodes()
Marks all boundary nodes.
const MeshLib::Mesh & _mesh
The mesh from which elements should be removed.
Definition NodeSearch.h:48
NodeSearch(const MeshLib::Mesh &mesh)
void updateUnion(const std::vector< std::size_t > &vec)
Updates the vector of marked items with values from vec.
std::size_t searchUnused()
Marks all unused nodes.
std::size_t getNodeIndex(Element const &element, unsigned const idx)
Definition Element.cpp:219
std::vector< Node * > getUniqueNodes(std::vector< Element * > const &elements)
Create a vector of unique nodes used by given elements.