ViennaLS
Loading...
Searching...
No Matches
lsMesh.hpp
Go to the documentation of this file.
1#pragma once
2
4
5#include <array>
6#include <iostream>
7#include <vector>
8
9#include <lsPointData.hpp>
10
11#include <vcSmartPointer.hpp>
12#include <vcVectorType.hpp>
13
14namespace viennals {
15
16using namespace viennacore;
17
22template <class T = double> class Mesh {
23public:
24 std::vector<Vec3D<T>> nodes;
25 std::vector<std::array<unsigned, 1>> vertices;
26 std::vector<std::array<unsigned, 2>> lines;
27 std::vector<std::array<unsigned, 3>> triangles;
28 std::vector<std::array<unsigned, 4>> tetras;
29 std::vector<std::array<unsigned, 8>> hexas;
32 Vec3D<T> minimumExtent;
33 Vec3D<T> maximumExtent;
34
35private:
36 // iterator typedef
37 using VectorIt = typename PointData<T>::VectorDataType::iterator;
38 // find function to avoid including the whole algorithm header
39 static VectorIt find(VectorIt first, VectorIt last, const Vec3D<T> &value) {
40 for (; first != last; ++first) {
41 if (*first == value) {
42 return first;
43 }
44 }
45 return last;
46 }
47
48 // helper function for duplicate removal
49 template <class ElementType>
50 static void replaceNode(ElementType &elements,
51 std::pair<unsigned, unsigned> node) {
52 for (unsigned i = 0; i < elements.size(); ++i) {
53 for (unsigned j = 0; j < elements[i].size(); ++j) {
54 if (elements[i][j] == node.first) {
55 elements[i][j] = node.second;
56 }
57 }
58 }
59 };
60
61public:
62 // Convenience function to create a new mesh smart pointer.
63 static auto New() { return SmartPointer<Mesh>::New(); }
64
65 const std::vector<Vec3D<T>> &getNodes() const { return nodes; }
66
67 std::vector<Vec3D<T>> &getNodes() { return nodes; }
68
69 template <int D, std::enable_if_t<D == 1, int> = 0>
70 std::vector<std::array<unsigned, D>> &getElements() {
71 return vertices;
72 }
73
74 template <int D, std::enable_if_t<D == 2, int> = 0>
75 std::vector<std::array<unsigned, D>> &getElements() {
76 return lines;
77 }
78
79 template <int D, std::enable_if_t<D == 3, int> = 0>
80 std::vector<std::array<unsigned, D>> &getElements() {
81 return triangles;
82 }
83
84 template <int D, std::enable_if_t<D == 4, int> = 0>
85 std::vector<std::array<unsigned, D>> &getElements() {
86 return tetras;
87 }
88
89 template <int D, std::enable_if_t<D == 8, int> = 0>
90 std::vector<std::array<unsigned, D>> &getElements() {
91 return hexas;
92 }
93
95
96 const PointData<T> &getPointData() const { return pointData; }
97
99
100 const PointData<T> &getCellData() const { return cellData; }
101
102 unsigned insertNextNode(const Vec3D<T> &node) {
103 nodes.push_back(node);
104 return nodes.size() - 1;
105 }
106
107 unsigned insertNextVertex(const std::array<unsigned, 1> &vertex) {
108 vertices.push_back(vertex);
109 return vertices.size() - 1;
110 }
111
112 unsigned insertNextLine(const std::array<unsigned, 2> &line) {
113 lines.push_back(line);
114 return lines.size() - 1;
115 }
116
117 unsigned insertNextTriangle(const std::array<unsigned, 3> &triangle) {
118 triangles.push_back(triangle);
119 return triangles.size() - 1;
120 }
121
122 unsigned insertNextTetra(const std::array<unsigned, 4> &tetra) {
123 tetras.push_back(tetra);
124 return tetras.size() - 1;
125 }
126
127 unsigned insertNextHexa(const std::array<unsigned, 8> &hexa) {
128 hexas.push_back(hexa);
129 return hexas.size() - 1;
130 }
131
132 unsigned insertNextElement(const std::array<unsigned, 1> &vertex) {
133 vertices.push_back(vertex);
134 return vertices.size() - 1;
135 }
136
137 unsigned insertNextElement(const std::array<unsigned, 2> &line) {
138 lines.push_back(line);
139 return lines.size() - 1;
140 }
141
142 unsigned insertNextElement(const std::array<unsigned, 3> &triangle) {
143 triangles.push_back(triangle);
144 return triangles.size() - 1;
145 }
146
147 unsigned insertNextElement(const std::array<unsigned, 4> &tetra) {
148 tetras.push_back(tetra);
149 return tetras.size() - 1;
150 }
151
152 unsigned insertNextElement(const std::array<unsigned, 8> &hexa) {
153 hexas.push_back(hexa);
154 return hexas.size() - 1;
155 }
156
158 std::vector<Vec3D<T>> newNodes;
159 // can just push first point since it cannot be duplicate
160 newNodes.push_back(nodes[0]);
161 // now check for duplicates
162 // pair of oldId <-> newId
163 std::vector<std::pair<unsigned, unsigned>> duplicates;
164 bool adjusted = false;
165 for (unsigned i = 1; i < nodes.size(); ++i) {
166 auto it = find(newNodes.begin(), newNodes.end(), nodes[i]);
167 if (it != newNodes.end()) {
168 adjusted = true;
169 // if duplicate point, save it to be replaced
170 unsigned nodeId = std::distance(newNodes.begin(), it);
171 duplicates.emplace_back(i, nodeId);
172 } else {
173 if (adjusted)
174 duplicates.push_back(std::make_pair(i, newNodes.size()));
175 newNodes.push_back(nodes[i]);
176 }
177 }
178 nodes = newNodes;
179
180 // now replace in vertices
181 // TODO also need to shift down all other nodes
182 for (auto &duplicate : duplicates) {
183 replaceNode(vertices, duplicate);
184 replaceNode(lines, duplicate);
185 replaceNode(triangles, duplicate);
186 replaceNode(tetras, duplicate);
187 replaceNode(hexas, duplicate);
188 }
189 }
190
191 void append(const Mesh<T> &passedMesh) {
192 const unsigned numberOfOldNodes = nodes.size();
193
194 // append new nodes
195 nodes.insert(nodes.end(), passedMesh.nodes.begin(), passedMesh.nodes.end());
196
197 // go through all elements and increase node IDs to match new IDS
198 const unsigned numberOfVertices = vertices.size();
199 vertices.insert(vertices.end(), passedMesh.vertices.begin(),
200 passedMesh.vertices.end());
201 for (unsigned i = numberOfVertices;
202 i < passedMesh.vertices.size() + numberOfVertices; ++i) {
203 vertices[i][0] += numberOfOldNodes;
204 }
205
206 const unsigned numberOfLines = lines.size();
207 lines.insert(lines.end(), passedMesh.lines.begin(), passedMesh.lines.end());
208 for (unsigned i = numberOfLines;
209 i < passedMesh.lines.size() + numberOfLines; ++i) {
210 for (unsigned d = 0; d < 2; ++d) {
211 lines[i][d] += numberOfOldNodes;
212 }
213 }
214
215 const unsigned numberOfTriangles = triangles.size();
216 triangles.insert(triangles.end(), passedMesh.triangles.begin(),
217 passedMesh.triangles.end());
218 for (unsigned i = numberOfTriangles;
219 i < passedMesh.triangles.size() + numberOfTriangles; ++i) {
220 for (unsigned d = 0; d < 3; ++d) {
221 triangles[i][d] += numberOfOldNodes;
222 }
223 }
224
225 const unsigned numberOfTetras = tetras.size();
226 tetras.insert(tetras.end(), passedMesh.tetras.begin(),
227 passedMesh.tetras.end());
228 for (unsigned i = numberOfTetras;
229 i < passedMesh.tetras.size() + numberOfTetras; ++i) {
230 for (unsigned d = 0; d < 4; ++d) {
231 tetras[i][d] += numberOfOldNodes;
232 }
233 }
234
235 const unsigned numberOfHexas = hexas.size();
236 hexas.insert(hexas.end(), passedMesh.hexas.begin(), passedMesh.hexas.end());
237 for (unsigned i = numberOfHexas;
238 i < passedMesh.hexas.size() + numberOfHexas; ++i) {
239 for (unsigned d = 0; d < 8; ++d) {
240 hexas[i][d] += numberOfOldNodes;
241 }
242 }
243
244 // Append data
245 // TODO need to adjust lsVTKWriter to deal with different data correctly
246 // currently this only works for vertex only meshes
247 pointData.append(passedMesh.pointData);
248 cellData.append(passedMesh.cellData);
249
250 // if(lsPointData<T>::scalarData.size() < nodes.size())
251 for (unsigned i = 0; i < pointData.getScalarDataSize(); ++i) {
252 pointData.getScalarData(i)->resize(vertices.size());
253 }
254 for (unsigned i = 0; i < pointData.getVectorDataSize(); ++i) {
255 pointData.getVectorData(i)->resize(vertices.size());
256 }
257
258 for (unsigned i = 0; i < cellData.getScalarDataSize(); ++i) {
259 cellData.getScalarData(i)->resize(vertices.size());
260 }
261 for (unsigned i = 0; i < cellData.getVectorDataSize(); ++i) {
262 cellData.getVectorData(i)->resize(vertices.size());
263 }
264 }
265
266 void clear() {
267 nodes.clear();
268 vertices.clear();
269 lines.clear();
270 triangles.clear();
271 tetras.clear();
272 hexas.clear();
273 pointData.clear();
274 cellData.clear();
275 }
276
277 void print() {
278 std::cout << "Mesh:" << std::endl;
279 std::cout << "Number of Nodes: " << nodes.size() << std::endl;
280 if (!vertices.empty())
281 std::cout << "Number of Vertices: " << vertices.size() << std::endl;
282 if (!lines.empty())
283 std::cout << "Number of Lines: " << lines.size() << std::endl;
284 if (!triangles.empty())
285 std::cout << "Number of Triangles: " << triangles.size() << std::endl;
286 if (!tetras.empty())
287 std::cout << "Number of Tetrahedrons: " << tetras.size() << std::endl;
288 if (!hexas.empty())
289 std::cout << "Number of Hexas: " << hexas.size() << std::endl;
290 // pointData
291 if (pointData.getScalarDataSize() > 0) {
292 std::cout << "Scalar data:" << std::endl;
293 for (unsigned i = 0; i < pointData.getScalarDataSize(); ++i) {
294 std::cout << " \"" << pointData.getScalarDataLabel(i) << "\" of size "
295 << pointData.getScalarData(i)->size() << std::endl;
296 }
297 }
298 if (pointData.getVectorDataSize() > 0) {
299 std::cout << "Vector data:" << std::endl;
300 for (unsigned i = 0; i < pointData.getVectorDataSize(); ++i) {
301 std::cout << " \"" << pointData.getVectorDataLabel(i) << "\" of size "
302 << pointData.getVectorData(i)->size() << std::endl;
303 }
304 }
305
306 // cellData
307 if (cellData.getScalarDataSize() > 0) {
308 std::cout << "Scalar data:" << std::endl;
309 for (unsigned i = 0; i < cellData.getScalarDataSize(); ++i) {
310 std::cout << " \"" << cellData.getScalarDataLabel(i) << "\" of size "
311 << cellData.getScalarData(i)->size() << std::endl;
312 }
313 }
314 if (cellData.getVectorDataSize() > 0) {
315 std::cout << "Vector data:" << std::endl;
316 for (unsigned i = 0; i < cellData.getVectorDataSize(); ++i) {
317 std::cout << " \"" << cellData.getVectorDataLabel(i) << "\" of size "
318 << cellData.getVectorData(i)->size() << std::endl;
319 }
320 }
321 }
322};
323
324// add all template specialisations for this class
326
327} // namespace viennals
This class holds an explicit mesh, which is always given in 3 dimensions. If it describes a 2D mesh,...
Definition lsMesh.hpp:22
PointData< T > pointData
Definition lsMesh.hpp:30
unsigned insertNextElement(const std::array< unsigned, 3 > &triangle)
Definition lsMesh.hpp:142
unsigned insertNextElement(const std::array< unsigned, 4 > &tetra)
Definition lsMesh.hpp:147
const PointData< T > & getPointData() const
Definition lsMesh.hpp:96
std::vector< std::array< unsigned, 8 > > hexas
Definition lsMesh.hpp:29
unsigned insertNextNode(const Vec3D< T > &node)
Definition lsMesh.hpp:102
void removeDuplicateNodes()
Definition lsMesh.hpp:157
Vec3D< T > minimumExtent
Definition lsMesh.hpp:32
PointData< T > cellData
Definition lsMesh.hpp:31
std::vector< Vec3D< T > > & getNodes()
Definition lsMesh.hpp:67
std::vector< std::array< unsigned, 1 > > vertices
Definition lsMesh.hpp:25
static auto New()
Definition lsMesh.hpp:63
std::vector< std::array< unsigned, 2 > > lines
Definition lsMesh.hpp:26
unsigned insertNextTriangle(const std::array< unsigned, 3 > &triangle)
Definition lsMesh.hpp:117
unsigned insertNextHexa(const std::array< unsigned, 8 > &hexa)
Definition lsMesh.hpp:127
void print()
Definition lsMesh.hpp:277
Vec3D< T > maximumExtent
Definition lsMesh.hpp:33
std::vector< std::array< unsigned, 4 > > tetras
Definition lsMesh.hpp:28
std::vector< Vec3D< T > > nodes
Definition lsMesh.hpp:24
unsigned insertNextTetra(const std::array< unsigned, 4 > &tetra)
Definition lsMesh.hpp:122
void clear()
Definition lsMesh.hpp:266
const PointData< T > & getCellData() const
Definition lsMesh.hpp:100
unsigned insertNextElement(const std::array< unsigned, 1 > &vertex)
Definition lsMesh.hpp:132
PointData< T > & getPointData()
Definition lsMesh.hpp:94
void append(const Mesh< T > &passedMesh)
Definition lsMesh.hpp:191
PointData< T > & getCellData()
Definition lsMesh.hpp:98
const std::vector< Vec3D< T > > & getNodes() const
Definition lsMesh.hpp:65
unsigned insertNextElement(const std::array< unsigned, 2 > &line)
Definition lsMesh.hpp:137
std::vector< std::array< unsigned, 3 > > triangles
Definition lsMesh.hpp:27
unsigned insertNextVertex(const std::array< unsigned, 1 > &vertex)
Definition lsMesh.hpp:107
unsigned insertNextElement(const std::array< unsigned, 8 > &hexa)
Definition lsMesh.hpp:152
unsigned insertNextLine(const std::array< unsigned, 2 > &line)
Definition lsMesh.hpp:112
std::vector< std::array< unsigned, D > > & getElements()
Definition lsMesh.hpp:70
This class holds data associated with points in space.
Definition lsPointData.hpp:21
#define PRECOMPILE_PRECISION(className)
Definition lsPreCompileMacros.hpp:30
Definition lsAdvect.hpp:36