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