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