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(){};
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 .addWarning("No level set was passed to ToMesh.")
53 .print();
54 return;
55 }
56 if (mesh == nullptr) {
57 Logger::getInstance().addWarning("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 return;
66 }
67
68 // LS data
69 std::vector<T> LSValues;
70 std::vector<T> subLS;
71 // point data
72 const auto &pointData = levelSet->getPointData();
73 using DomainType = Domain<T, D>;
74 using ScalarDataType = typename DomainType::PointDataType::ScalarDataType;
75 using VectorDataType = typename DomainType::PointDataType::VectorDataType;
76
77 // get all the data of the LS
78 std::vector<ScalarDataType> scalarData;
79 std::vector<VectorDataType> vectorData;
80 scalarData.resize(pointData.getScalarDataSize());
81 vectorData.resize(pointData.getVectorDataSize());
82
83 const T gridDelta = levelSet->getGrid().getGridDelta();
84
85 for (hrleConstSparseIterator<hrleDomainType> it(levelSet->getDomain());
86 !it.isFinished(); ++it) {
87 if ((onlyDefined && !it.isDefined()) ||
88 (onlyActive && std::abs(it.getValue()) > 0.5))
89 continue;
90
91 if (!onlyDefined && !it.isDefined()) {
92 bool skipPoint = false;
93 for (unsigned i = 0; i < D; ++i) {
94 if (std::abs(it.getStartIndices(i)) > maxDomainExtent) {
95 skipPoint = true;
96 }
97 }
98 if (skipPoint) {
99 continue;
100 }
101 }
102
103 // insert vertex
104 std::array<unsigned, 1> vertex;
105 vertex[0] = mesh->nodes.size();
106 mesh->insertNextVertex(vertex);
107
108 // insert corresponding node
109 std::array<T, 3> node;
110 if (D == 2)
111 node[2] = 0.;
112 for (unsigned i = 0; i < D; ++i) {
113 node[i] = T(it.getStartIndices(i)) * gridDelta;
114 }
115 mesh->insertNextNode(node);
116
117 // insert LS value
118 if (it.isDefined()) {
119 LSValues.push_back(it.getDefinedValue());
120 } else {
121 LSValues.push_back((it.getValue() < 0) ? -1000 : 1000);
122 }
123 subLS.push_back(it.getSegmentId());
124
125 // add all saved LS data
126 for (unsigned i = 0; i < pointData.getScalarDataSize(); ++i) {
127 if (const auto dataPointer = pointData.getScalarData(i);
128 dataPointer != nullptr) {
129 const auto &currentData = *dataPointer;
130 scalarData[i].push_back(currentData[it.getPointId()]);
131 } else {
132 Logger::getInstance()
133 .addWarning("ToMesh: Tried to access out of bounds scalarData! "
134 "Ignoring.")
135 .print();
136 break;
137 }
138 }
139
140 for (unsigned i = 0; i < pointData.getVectorDataSize(); ++i) {
141 if (const auto dataPointer = pointData.getVectorData(i);
142 dataPointer != nullptr) {
143 const auto &currentData = *dataPointer;
144 vectorData[i].push_back(currentData[it.getPointId()]);
145 } else {
146 Logger::getInstance()
147 .addWarning("ToMesh: Tried to access out of bounds vectorData! "
148 "Ignoring.")
149 .print();
150 break;
151 }
152 }
153 }
154
155 mesh->cellData.insertNextScalarData(LSValues, "LSValues");
156 mesh->cellData.insertNextScalarData(subLS, "SegmentID");
157
158 // append all scalar and vector data
159 // just move it into the new structure, since we do not need it anymore
160 for (unsigned i = 0; i < scalarData.size(); ++i) {
161 mesh->cellData.insertNextScalarData(std::move(scalarData[i]),
162 pointData.getScalarDataLabel(i));
163 }
164
165 for (unsigned i = 0; i < vectorData.size(); ++i) {
166 mesh->cellData.insertNextVectorData(std::move(vectorData[i]),
167 pointData.getVectorDataLabel(i));
168 }
169 }
170};
171
172// add all template specialisations for this class
174
175} // namespace viennals
Class containing all information about the level set, including the dimensions of the domain,...
Definition lsDomain.hpp:28
hrleDomain< T, D > DomainType
Definition lsDomain.hpp:33
This class holds an explicit mesh, which is always given in 3 dimensions. If it describes a 2D mesh,...
Definition lsMesh.hpp:21
Extract the regular grid, on which the level set values are defined, to an explicit Mesh<>....
Definition lsToMesh.hpp:19
void setOnlyDefined(bool passedOnlyDefined)
Definition lsToMesh.hpp:43
ToMesh()
Definition lsToMesh.hpp:29
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
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:46
constexpr int D
Definition pyWrap.cpp:65
double T
Definition pyWrap.cpp:63