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 Logger::getInstance().addError("No mesh was passed to ToMesh.").print();
58 return;
59 }
60
61 mesh->clear();
62
63 // check if level set is empty
64 if (levelSet->getNumberOfPoints() == 0) {
65 Logger::getInstance()
66 .addWarning("ToMesh: Level set is empty. No mesh will be created.")
67 .print();
68 return;
69 }
70
71 // LS data
72 std::vector<T> LSValues;
73 std::vector<T> subLS;
74 // point data
75 const auto &pointData = levelSet->getPointData();
77 using ScalarDataType = typename DomainType::PointDataType::ScalarDataType;
78 using VectorDataType = typename DomainType::PointDataType::VectorDataType;
79
80 // get all the data of the LS
81 std::vector<ScalarDataType> scalarData;
82 std::vector<VectorDataType> vectorData;
83 scalarData.resize(pointData.getScalarDataSize());
84 vectorData.resize(pointData.getVectorDataSize());
85
86 const T gridDelta = levelSet->getGrid().getGridDelta();
87
88 for (viennahrle::ConstSparseIterator<hrleDomainType> it(
89 levelSet->getDomain());
90 !it.isFinished(); ++it) {
91 if ((onlyDefined && !it.isDefined()) ||
92 (onlyActive && std::abs(it.getValue()) > 0.5))
93 continue;
94
95 if (!onlyDefined && !it.isDefined()) {
96 bool skipPoint = false;
97 for (unsigned i = 0; i < D; ++i) {
98 if (std::abs(it.getStartIndices(i)) > maxDomainExtent) {
99 skipPoint = true;
100 }
101 }
102 if (skipPoint) {
103 continue;
104 }
105 }
106
107 // insert vertex
108 std::array<unsigned, 1> vertex{};
109 vertex[0] = mesh->nodes.size();
110 mesh->insertNextVertex(vertex);
111
112 // insert corresponding node
113 Vec3D<T> node;
114 if (D == 2)
115 node[2] = 0.;
116 for (unsigned i = 0; i < D; ++i) {
117 node[i] = T(it.getStartIndices(i)) * gridDelta;
118 }
119 mesh->insertNextNode(node);
120
121 // insert LS value
122 if (it.isDefined()) {
123 LSValues.push_back(it.getDefinedValue());
124 } else {
125 LSValues.push_back((it.getValue() < 0) ? -1000 : 1000);
126 }
127 subLS.push_back(it.getSegmentId());
128
129 // add all saved LS data
130 for (unsigned i = 0; i < pointData.getScalarDataSize(); ++i) {
131 if (const auto dataPointer = pointData.getScalarData(i);
132 dataPointer != nullptr) {
133 const auto &currentData = *dataPointer;
134 scalarData[i].push_back(currentData[it.getPointId()]);
135 } else {
136 Logger::getInstance()
137 .addWarning("ToMesh: Tried to access out of bounds scalarData! "
138 "Ignoring.")
139 .print();
140 break;
141 }
142 }
143
144 for (unsigned i = 0; i < pointData.getVectorDataSize(); ++i) {
145 if (const auto dataPointer = pointData.getVectorData(i);
146 dataPointer != nullptr) {
147 const auto &currentData = *dataPointer;
148 vectorData[i].push_back(currentData[it.getPointId()]);
149 } else {
150 Logger::getInstance()
151 .addWarning("ToMesh: Tried to access out of bounds vectorData! "
152 "Ignoring.")
153 .print();
154 break;
155 }
156 }
157 }
158
159 mesh->cellData.insertNextScalarData(LSValues, "LSValues");
160 mesh->cellData.insertNextScalarData(subLS, "SegmentID");
161
162 // append all scalar and vector data
163 // just move it into the new structure, since we do not need it anymore
164 for (unsigned i = 0; i < scalarData.size(); ++i) {
165 mesh->cellData.insertNextScalarData(std::move(scalarData[i]),
166 pointData.getScalarDataLabel(i));
167 }
168
169 for (unsigned i = 0; i < vectorData.size(); ++i) {
170 mesh->cellData.insertNextVectorData(std::move(vectorData[i]),
171 pointData.getVectorDataLabel(i));
172 }
173 }
174};
175
176// add all template specialisations for this class
178
179} // namespace viennals
constexpr int D
Definition Epitaxy.cpp:9
double T
Definition Epitaxy.cpp:10
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:36