10#include <unordered_map>
13#include <vcPointData.hpp>
14#include <vcSmartPointer.hpp>
15#include <vcVectorType.hpp>
19using namespace viennacore;
25template <
class T =
double>
class Mesh {
29 std::vector<std::array<unsigned, 2>>
lines;
31 std::vector<std::array<unsigned, 4>>
tetras;
32 std::vector<std::array<unsigned, 8>>
hexas;
42 static auto New() {
return SmartPointer<Mesh>::New(); }
48 template <
int D, std::enable_if_t<D == 1,
int> = 0>
53 template <
int D, std::enable_if_t<D == 2,
int> = 0>
58 template <
int D, std::enable_if_t<D == 3,
int> = 0>
63 template <
int D, std::enable_if_t<D == 4,
int> = 0>
68 template <
int D, std::enable_if_t<D == 8,
int> = 0>
83 return cellData.getVectorData(label);
88 return cellData.getScalarData(label);
92 nodes.push_back(node);
93 return nodes.size() - 1;
102 lines.push_back(line);
103 return lines.size() - 1;
117 hexas.push_back(hexa);
118 return hexas.size() - 1;
127 lines.push_back(line);
128 return lines.size() - 1;
142 hexas.push_back(hexa);
143 return hexas.size() - 1;
155 if (
nodes.size() < 2)
159 std::size_t operator()(
const Vec3D<T> &node)
const {
160 std::size_t seed = 0;
161 for (
const T coordinate : node) {
162 seed ^= std::hash<T>{}(coordinate) + std::size_t(0x9e3779b9) +
163 (seed << 6) + (seed >> 2);
171 std::unordered_map<Vec3D<T>, unsigned, NodeHash> uniqueNodes;
172 uniqueNodes.reserve(
nodes.size());
173 std::vector<Vec3D<T>> newNodes;
174 newNodes.reserve(
nodes.size());
175 std::vector<unsigned> oldToNew(
nodes.size());
176 std::vector<unsigned> retainedIndices;
177 retainedIndices.reserve(
nodes.size());
179 for (std::size_t i = 0; i <
nodes.size(); ++i) {
180 const auto &node =
nodes[i];
181 const auto newId =
static_cast<unsigned>(newNodes.size());
183 if (!std::isnan(node[0]) && !std::isnan(node[1]) &&
184 !std::isnan(node[2])) {
185 const auto result = uniqueNodes.try_emplace(node, newId);
186 oldToNew[i] = result.first->second;
192 newNodes.push_back(node);
193 retainedIndices.push_back(
static_cast<unsigned>(i));
196 if (newNodes.size() ==
nodes.size())
200 const auto validateData = [
this](
const auto &arrays) {
201 for (
const auto &data : arrays) {
202 if (data.size() !=
nodes.size()) {
203 throw std::invalid_argument(
204 "Mesh::removeDuplicateNodes: point-data size must match the "
211 PointData<T> newPointData;
212 newPointData.translateFromData(
pointData, retainedIndices);
214 const auto remapElements = [&oldToNew](
auto &elements) {
215 for (
auto &element : elements) {
216 for (
auto &nodeId : element)
217 nodeId = oldToNew[nodeId];
221 remapElements(
lines);
224 remapElements(
hexas);
226 nodes = std::move(newNodes);
231 const unsigned numberOfOldNodes =
nodes.size();
237 const unsigned numberOfVertices =
vertices.size();
240 for (
unsigned i = numberOfVertices;
241 i < passedMesh.
vertices.size() + numberOfVertices; ++i) {
245 const unsigned numberOfLines =
lines.size();
247 for (
unsigned i = numberOfLines;
248 i < passedMesh.
lines.size() + numberOfLines; ++i) {
249 for (
unsigned d = 0; d < 2; ++d) {
250 lines[i][d] += numberOfOldNodes;
254 const unsigned numberOfTriangles =
triangles.size();
257 for (
unsigned i = numberOfTriangles;
258 i < passedMesh.
triangles.size() + numberOfTriangles; ++i) {
259 for (
unsigned d = 0; d < 3; ++d) {
264 const unsigned numberOfTetras =
tetras.size();
267 for (
unsigned i = numberOfTetras;
268 i < passedMesh.
tetras.size() + numberOfTetras; ++i) {
269 for (
unsigned d = 0; d < 4; ++d) {
270 tetras[i][d] += numberOfOldNodes;
274 const unsigned numberOfHexas =
hexas.size();
276 for (
unsigned i = numberOfHexas;
277 i < passedMesh.
hexas.size() + numberOfHexas; ++i) {
278 for (
unsigned d = 0; d < 8; ++d) {
279 hexas[i][d] += numberOfOldNodes;
290 for (
unsigned i = 0; i <
pointData.getScalarDataSize(); ++i) {
293 for (
unsigned i = 0; i <
pointData.getVectorDataSize(); ++i) {
297 for (
unsigned i = 0; i <
cellData.getScalarDataSize(); ++i) {
300 for (
unsigned i = 0; i <
cellData.getVectorDataSize(); ++i) {
319 std::cout <<
"Mesh:" << std::endl;
320 std::cout <<
"Number of Nodes: " <<
nodes.size() << std::endl;
322 std::cout <<
"Number of Vertices: " <<
vertices.size() << std::endl;
324 std::cout <<
"Number of Lines: " <<
lines.size() << std::endl;
326 std::cout <<
"Number of Triangles: " <<
triangles.size() << std::endl;
328 std::cout <<
"Number of Tetrahedrons: " <<
tetras.size() << std::endl;
330 std::cout <<
"Number of Hexas: " <<
hexas.size() << std::endl;
333 std::cout <<
"Scalar data:" << std::endl;
334 for (
unsigned i = 0; i <
pointData.getScalarDataSize(); ++i) {
335 std::cout <<
" \"" <<
pointData.getScalarDataLabel(i) <<
"\" of size "
336 <<
pointData.getScalarData(i)->size() << std::endl;
340 std::cout <<
"Vector data:" << std::endl;
341 for (
unsigned i = 0; i <
pointData.getVectorDataSize(); ++i) {
342 std::cout <<
" \"" <<
pointData.getVectorDataLabel(i) <<
"\" of size "
343 <<
pointData.getVectorData(i)->size() << std::endl;
348 if (
cellData.getScalarDataSize() > 0) {
349 std::cout <<
"Scalar data:" << std::endl;
350 for (
unsigned i = 0; i <
cellData.getScalarDataSize(); ++i) {
351 std::cout <<
" \"" <<
cellData.getScalarDataLabel(i) <<
"\" of size "
352 <<
cellData.getScalarData(i)->size() << std::endl;
355 if (
cellData.getVectorDataSize() > 0) {
356 std::cout <<
"Vector data:" << std::endl;
357 for (
unsigned i = 0; i <
cellData.getVectorDataSize(); ++i) {
358 std::cout <<
" \"" <<
cellData.getVectorDataLabel(i) <<
"\" of size "
359 <<
cellData.getVectorData(i)->size() << std::endl;
double T
Definition Epitaxy.cpp:13
This class holds an explicit mesh, which is always given in 3 dimensions. If it describes a 2D mesh,...
Definition lsMesh.hpp:25
PointData< T > pointData
Definition lsMesh.hpp:33
unsigned insertNextElement(const std::array< unsigned, 3 > &triangle)
Definition lsMesh.hpp:131
unsigned insertNextElement(const std::array< unsigned, 4 > &tetra)
Definition lsMesh.hpp:136
const PointData< T > & getPointData() const
Definition lsMesh.hpp:75
static constexpr const char * normalsLabel
Definition lsMesh.hpp:39
std::vector< std::array< unsigned, 8 > > hexas
Definition lsMesh.hpp:32
unsigned insertNextNode(const Vec3D< T > &node)
Definition lsMesh.hpp:91
void removeDuplicateNodes()
Remove exactly equal nodes, preserving first-occurrence order and the first node's scalar/vector poin...
Definition lsMesh.hpp:154
Vec3D< T > minimumExtent
Definition lsMesh.hpp:35
PointData< T > cellData
Definition lsMesh.hpp:34
std::vector< Vec3D< T > > & getNodes()
Definition lsMesh.hpp:46
std::vector< std::array< unsigned, 1 > > vertices
Definition lsMesh.hpp:28
static auto New()
Definition lsMesh.hpp:42
std::vector< std::array< unsigned, 2 > > lines
Definition lsMesh.hpp:29
unsigned insertNextTriangle(const std::array< unsigned, 3 > &triangle)
Definition lsMesh.hpp:106
std::vector< T > * getMaterialIds(const char *label=materialIdsLabel)
Definition lsMesh.hpp:87
unsigned insertNextHexa(const std::array< unsigned, 8 > &hexa)
Definition lsMesh.hpp:116
void print()
Definition lsMesh.hpp:318
Vec3D< T > maximumExtent
Definition lsMesh.hpp:36
std::vector< std::array< unsigned, 4 > > tetras
Definition lsMesh.hpp:31
std::vector< Vec3D< T > > nodes
Definition lsMesh.hpp:27
unsigned insertNextTetra(const std::array< unsigned, 4 > &tetra)
Definition lsMesh.hpp:111
void clear()
Definition lsMesh.hpp:305
const PointData< T > & getCellData() const
Definition lsMesh.hpp:79
std::vector< Vec3D< T > > * getNormals(const char *label=normalsLabel)
Definition lsMesh.hpp:82
unsigned insertNextElement(const std::array< unsigned, 1 > &vertex)
Definition lsMesh.hpp:121
static constexpr const char * materialIdsLabel
Definition lsMesh.hpp:38
PointData< T > & getPointData()
Definition lsMesh.hpp:73
void append(const Mesh< T > &passedMesh)
Definition lsMesh.hpp:230
PointData< T > & getCellData()
Definition lsMesh.hpp:77
const std::vector< Vec3D< T > > & getNodes() const
Definition lsMesh.hpp:44
unsigned insertNextElement(const std::array< unsigned, 2 > &line)
Definition lsMesh.hpp:126
std::vector< std::array< unsigned, 3 > > triangles
Definition lsMesh.hpp:30
unsigned insertNextVertex(const std::array< unsigned, 1 > &vertex)
Definition lsMesh.hpp:96
unsigned insertNextElement(const std::array< unsigned, 8 > &hexa)
Definition lsMesh.hpp:141
unsigned insertNextLine(const std::array< unsigned, 2 > &line)
Definition lsMesh.hpp:101
std::vector< std::array< unsigned, D > > & getElements()
Definition lsMesh.hpp:49
Definition lsAdvect.hpp:41
PRECOMPILE_PRECISION(Extrude)