ViennaLS
Loading...
Searching...
No Matches
lsToMesh.hpp
Go to the documentation of this file.
1#pragma once
2
4
5#include <vector>
6
7#include <hrleSparseIterator.hpp>
8#include <lsDomain.hpp>
9#include <lsMesh.hpp>
10
11namespace viennals {
12
13using namespace viennacore;
14
19template <class T, int D> class ToMesh {
20 typedef typename Domain<T, D>::DomainType hrleDomainType;
21
22 SmartPointer<Domain<T, D>> levelSet = nullptr;
23 SmartPointer<Mesh<T>> mesh = nullptr;
24 bool onlyDefined = true;
25 bool onlyActive = false;
26 static constexpr long long maxDomainExtent = 1e6;
27
28public:
29 ToMesh() = default;
30
31 ToMesh(const SmartPointer<Domain<T, D>> passedLevelSet,
32 SmartPointer<Mesh<T>> passedMesh, bool passedOnlyDefined = true,
33 bool passedOnlyActive = false)
34 : levelSet(passedLevelSet), mesh(passedMesh),
35 onlyDefined(passedOnlyDefined), onlyActive(passedOnlyActive) {}
36
37 void setLevelSet(SmartPointer<Domain<T, D>> passedlsDomain) {
38 levelSet = passedlsDomain;
39 }
40
41 void setMesh(SmartPointer<Mesh<T>> passedMesh) { mesh = passedMesh; }
42
43 void setOnlyDefined(bool passedOnlyDefined) {
44 onlyDefined = passedOnlyDefined;
45 }
46
47 void setOnlyActive(bool passedOnlyActive) { onlyActive = passedOnlyActive; }
48
49 void apply() {
50 if (levelSet == nullptr) {
51 Logger::getInstance()
52 .addError("No level set was passed to ToMesh.")
53 .print();
54 return;
55 }
56 if (mesh == nullptr) {
57 VIENNACORE_LOG_ERROR("No mesh was passed to ToMesh.");
58 return;
59 }
60
61 mesh->clear();
62
63 // check if level set is empty
64 if (levelSet->getNumberOfPoints() == 0) {
65 VIENNACORE_LOG_WARNING(
66 "ToMesh: Level set is empty. No mesh will be created.");
67 return;
68 }
69
70 // LS data
71 std::vector<T> LSValues;
72 std::vector<T> subLS;
73 // point data
74 const auto &pointData = levelSet->getPointData();
76 using ScalarDataType = typename DomainType::PointDataType::ScalarDataType;
77 using VectorDataType = typename DomainType::PointDataType::VectorDataType;
78
79 // get all the data of the LS
80 std::vector<ScalarDataType> scalarData;
81 std::vector<VectorDataType> vectorData;
82 scalarData.resize(pointData.getScalarDataSize());
83 vectorData.resize(pointData.getVectorDataSize());
84
85 const T gridDelta = levelSet->getGrid().getGridDelta();
86
87 for (viennahrle::ConstSparseIterator<hrleDomainType> it(
88 levelSet->getDomain());
89 !it.isFinished(); ++it) {
90 if ((onlyDefined && !it.isDefined()) ||
91 (onlyActive && std::abs(it.getValue()) > 0.5))
92 continue;
93
94 if (!onlyDefined && !it.isDefined()) {
95 bool skipPoint = false;
96 for (unsigned i = 0; i < D; ++i) {
97 if (std::abs(it.getStartIndices(i)) > maxDomainExtent) {
98 skipPoint = true;
99 }
100 }
101 if (skipPoint) {
102 continue;
103 }
104 }
105
106 // insert vertex
107 std::array<unsigned, 1> vertex{};
108 vertex[0] = mesh->nodes.size();
109 mesh->insertNextVertex(vertex);
110
111 // insert corresponding node
112 Vec3D<T> node;
113 if (D == 2)
114 node[2] = 0.;
115 for (unsigned i = 0; i < D; ++i) {
116 node[i] = T(it.getStartIndices(i)) * gridDelta;
117 }
118 mesh->insertNextNode(node);
119
120 // insert LS value
121 if (it.isDefined()) {
122 LSValues.push_back(it.getDefinedValue());
123 } else {
124 LSValues.push_back((it.getValue() < 0) ? -1000 : 1000);
125 }
126 subLS.push_back(it.getSegmentId());
127
128 // add all saved LS data
129 for (unsigned i = 0; i < pointData.getScalarDataSize(); ++i) {
130 if (const auto dataPointer = pointData.getScalarData(i);
131 dataPointer != nullptr) {
132 const auto &currentData = *dataPointer;
133 scalarData[i].push_back(currentData[it.getPointId()]);
134 } else {
135 VIENNACORE_LOG_WARNING(
136 "ToMesh: Tried to access out of bounds scalarData! Ignoring.");
137 break;
138 }
139 }
140
141 for (unsigned i = 0; i < pointData.getVectorDataSize(); ++i) {
142 if (const auto dataPointer = pointData.getVectorData(i);
143 dataPointer != nullptr) {
144 const auto &currentData = *dataPointer;
145 vectorData[i].push_back(currentData[it.getPointId()]);
146 } else {
147 VIENNACORE_LOG_WARNING(
148 "ToMesh: Tried to access out of bounds vectorData! Ignoring.");
149 break;
150 }
151 }
152 }
153
154 mesh->cellData.insertNextScalarData(LSValues, "LSValues");
155 mesh->cellData.insertNextScalarData(subLS, "SegmentID");
156
157 // append all scalar and vector data
158 // just move it into the new structure, since we do not need it anymore
159 for (unsigned i = 0; i < scalarData.size(); ++i) {
160 mesh->cellData.insertNextScalarData(std::move(scalarData[i]),
161 pointData.getScalarDataLabel(i));
162 }
163
164 for (unsigned i = 0; i < vectorData.size(); ++i) {
165 mesh->cellData.insertNextVectorData(std::move(vectorData[i]),
166 pointData.getVectorDataLabel(i));
167 }
168 }
169};
170
171// add all template specialisations for this class
173
174} // namespace viennals
constexpr int D
Definition Epitaxy.cpp:11
double T
Definition Epitaxy.cpp:12
Class containing all information about the level set, including the dimensions of the domain,...
Definition lsDomain.hpp:27
viennahrle::Domain< T, D > DomainType
Definition lsDomain.hpp:32
This class holds an explicit mesh, which is always given in 3 dimensions. If it describes a 2D mesh,...
Definition lsMesh.hpp:22
void setOnlyDefined(bool passedOnlyDefined)
Definition lsToMesh.hpp:43
void setLevelSet(SmartPointer< Domain< T, D > > passedlsDomain)
Definition lsToMesh.hpp:37
void apply()
Definition lsToMesh.hpp:49
void setOnlyActive(bool passedOnlyActive)
Definition lsToMesh.hpp:47
ToMesh()=default
void setMesh(SmartPointer< Mesh< T > > passedMesh)
Definition lsToMesh.hpp:41
ToMesh(const SmartPointer< Domain< T, D > > passedLevelSet, SmartPointer< Mesh< T > > passedMesh, bool passedOnlyDefined=true, bool passedOnlyActive=false)
Definition lsToMesh.hpp:31
#define PRECOMPILE_PRECISION_DIMENSION(className)
Definition lsPreCompileMacros.hpp:24
Definition lsAdvect.hpp:37