59 .addWarning(
"No grid has been set in FromVolumeMesh.")
63 if (mesh ==
nullptr) {
65 .addWarning(
"No mesh was passed to FromVolumeMesh.")
71 std::vector<int> materialInts;
73 mesh->cellData.getScalarData(
"Material",
true);
74 if (materialData !=
nullptr) {
77 std::vector<int>(materialData->begin(), materialData->end());
78 std::sort(materialInts.begin(), materialInts.end());
79 auto it = std::unique(materialInts.begin(), materialInts.end());
80 materialInts.erase(it, materialInts.end());
83 materialInts.push_back(0);
87 typedef std::map<VectorType<unsigned int, D>, std::pair<int, int>>
89 triangleMapType surfaceElements;
91 unsigned numberOfElements =
92 (
D == 3) ? mesh->tetras.size() : mesh->triangles.size();
93 for (
unsigned int i = 0; i < numberOfElements; ++i) {
94 for (
int j = 0; j <
D + 1; j++) {
95 VectorType<unsigned int, D> currentSurfaceElement;
96 for (
int k = 0; k <
D; k++) {
97 currentSurfaceElement[k] =
98 mesh->template getElements<D + 1>()[i][(j + k) % (
D + 1)];
127 std::sort(currentSurfaceElement.begin(), currentSurfaceElement.end());
129 Vec3D<T> currentElementPoints[
D + 1];
130 for (
int k = 0; k <
D; k++) {
131 currentElementPoints[k] = mesh->nodes[currentSurfaceElement[k]];
135 currentElementPoints[
D] =
136 mesh->nodes[mesh->template getElements<D + 1>()[i]
137 [(j +
D) % (
D + 1)]];
139 typename triangleMapType::iterator it =
140 surfaceElements.lower_bound(currentSurfaceElement);
141 if ((it != surfaceElements.end()) &&
142 (it->first == currentSurfaceElement)) {
143 if (Orientation(currentElementPoints)) {
144 if (it->second.second != materialInts.back() + 1) {
145 Logger::getInstance()
147 "Coinciding surface elements with same orientation in "
153 (materialData ==
nullptr) ? 0 : (*materialData)[i];
155 if (it->second.first != materialInts.back() + 1) {
156 Logger::getInstance()
158 "Coinciding surface elements with same orientation in "
164 (materialData ==
nullptr) ? 0 : (*materialData)[i];
167 if (it->second.first == it->second.second)
168 surfaceElements.erase(it);
171 if (Orientation(currentElementPoints)) {
172 surfaceElements.insert(
173 it, std::make_pair(currentSurfaceElement,
174 std::make_pair(materialInts.back() + 1,
175 (materialData ==
nullptr)
177 : (*materialData)[i])));
179 surfaceElements.insert(
180 it, std::make_pair(currentSurfaceElement,
181 std::make_pair((materialData ==
nullptr)
183 : (*materialData)[i],
184 materialInts.back() + 1)));
194 for (
unsigned i = 0; i < materialInts.size(); ++i) {
195 auto ls = LevelSetType::New(grid);
196 levelSets.push_back(
ls);
200 auto levelSetIterator = levelSets.begin();
201 for (
int &materialInt : materialInts) {
202 auto currentSurface = SmartPointer<Mesh<T>>::New();
203 auto &meshElements = currentSurface->template getElements<D>();
204 for (
auto it = surfaceElements.begin(); it != surfaceElements.end();
206 if ((materialInt >= it->second.first) &&
207 (materialInt < it->second.second)) {
208 std::array<unsigned, D> element{it->first[0], it->first[1]};
209 if constexpr (
D == 3)
210 element[2] = it->first[2];
211 meshElements.push_back(element);
212 }
else if ((materialInt >= it->second.second) &&
213 (materialInt < it->second.first)) {
215 std::array<unsigned, D> element{it->first[1], it->first[0]};
216 if constexpr (
D == 3)
217 element[2] = it->first[2];
218 meshElements.push_back(element);
223 constexpr unsigned int undefined_node =
224 std::numeric_limits<unsigned int>::max();
225 std::vector<unsigned int> nodeReplacements(mesh->nodes.size(),
227 unsigned int NodeCounter = 0;
229 for (
unsigned int k = 0; k < meshElements.size(); ++k) {
230 for (
int h = 0; h <
D; h++) {
231 unsigned int origin_node = meshElements[k][h];
232 if (nodeReplacements[origin_node] == undefined_node) {
233 nodeReplacements[origin_node] = NodeCounter++;
234 currentSurface->nodes.push_back(mesh->nodes[origin_node]);
236 meshElements[k][h] = nodeReplacements[origin_node];
242 removeBoundaryTriangles)