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