FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
meshhexer.cpp
1// FEAT3: Finite Element Analysis Toolbox, Version 3
2// Copyright (C) 2010 by Stefan Turek & the FEAT group
3// FEAT3 is released under the GNU General Public License version 3,
4// see the file 'copyright.txt' in the top level directory for details.
5
7
8#ifdef FEAT_HAVE_MESHHEXER
9
10#include <kernel/geometry/adaptive_mesh.hpp>
11#include <kernel/geometry/conformal_mesh.hpp>
12#include <kernel/geometry/meshhexer.hpp>
13#include <kernel/geometry/subdivision_levels.hpp>
14#include <kernel/shape.hpp>
16
17#include <meshhexer/meshhexer.hpp>
18#include <meshhexer/types.hpp>
19
20namespace FEAT::Geometry
21{
22 MeshHexerSurfaceMesh::~MeshHexerSurfaceMesh()
23 {
24 delete static_cast<MeshHexer::SurfaceMesh*>(_surface_mesh);
25 }
26
28 {
29 return static_cast<MeshHexer::SurfaceMesh*>(_surface_mesh)->is_closed();
30 }
31
33 {
34 return static_cast<MeshHexer::SurfaceMesh*>(_surface_mesh)->is_wound_consistently();
35 }
36
38 {
39 return static_cast<MeshHexer::SurfaceMesh*>(_surface_mesh)->is_outward_oriented();
40 }
41
43 {
44 return static_cast<MeshHexer::SurfaceMesh*>(_surface_mesh)->minimal_aspect_ratio();
45 }
46
48 {
49 return static_cast<MeshHexer::SurfaceMesh*>(_surface_mesh)->maximal_aspect_ratio();
50 }
51
52 std::vector<Gap> MeshHexerSurfaceMesh::gaps()
53 {
54 std::vector<MeshHexer::Gap> gaps = static_cast<MeshHexer::SurfaceMesh*>(_surface_mesh)->gaps();
55
56 // Convert to FEAT type
57 std::vector<Gap> result;
58 result.reserve(gaps.size());
59 for(const auto gap : gaps)
60 {
61 result.emplace_back(gap.diameter, gap.confidence);
62 }
63
64 return result;
65 }
66
68 {
69 MeshHexer::Gap gap = static_cast<MeshHexer::SurfaceMesh*>(_surface_mesh)->min_gap();
70 return {gap.diameter, gap.confidence};
71 }
72
73 template<typename DataType_>
74 ConformalMesh<Shape::Hexahedron, 3, DataType_> MeshHexerSurfaceMesh::fbm_mesh(
75 DataType_ x_min,
76 DataType_ y_min,
77 DataType_ z_min,
78 DataType_ x_max,
79 DataType_ y_max,
80 DataType_ z_max,
81 std::uint64_t levels)
82 {
83 using AdaptiveMeshType = AdaptiveMesh<SchneidersTemplates, Shape::Hexahedron, 3, DataType_>;
84
85 auto data = prepare_fbm_mesh<DataType_>(x_min, y_min, z_min, x_max, y_max, z_max, levels);
86
87 AdaptiveMeshType amesh(data.first);
88 amesh.adapt(data.second, AdaptiveMeshType::ImportBehaviour::All);
89
90 return amesh.to_conformal_mesh(Layer{amesh.num_layers() - 1});
91 }
92
93 template<typename DataType_>
94 ConformalMesh<Shape::Hexahedron, 3, DataType_> MeshHexerSurfaceMesh::fbm_mesh(std::uint64_t levels)
95 {
96 const MeshHexer::BoundingBox bb = static_cast<MeshHexer::SurfaceMesh*>(_surface_mesh)->bounding_box();
97 return fbm_mesh<DataType_>(
98 DataType_(bb.min.x),
99 DataType_(bb.min.y),
100 DataType_(bb.min.z),
101 DataType_(bb.max.x),
102 DataType_(bb.max.y),
103 DataType_(bb.max.z),
104 levels);
105 }
106
107 template<typename DataType_>
108 std::pair<ConformalMesh<Shape::Hexahedron, 3, DataType_>, SubdivisionLevels> MeshHexerSurfaceMesh::prepare_fbm_mesh(
109 DataType_ x_min,
110 DataType_ y_min,
111 DataType_ z_min,
112 DataType_ x_max,
113 DataType_ y_max,
114 DataType_ z_max,
115 std::uint64_t levels)
116 {
117 using MeshType = ConformalMesh<Shape::Hexahedron, 3, DataType_>;
118 using VertexType = typename MeshType::VertexType;
119
120 MeshHexer::BoundingBox bb{
121 {double(x_min), double(y_min), double(z_min)},
122 {double(x_max), double(y_max), double(z_max)}};
123 MeshHexer::FBMMeshSettings settings{bb, levels};
124
125 MeshHexer::VolumeMesh vmesh = static_cast<MeshHexer::SurfaceMesh*>(_surface_mesh)->fbm_mesh(settings);
126
127 SubdivisionLevels sdls(vmesh.num_vertices());
128 for(Index i(0); i < vmesh.num_vertices(); i++)
129 {
130 sdls[i] = vmesh.subdivision_level(i);
131 }
132
133 std::array<Index, 4> size{vmesh.num_vertices(), vmesh.num_edges(), vmesh.num_faces(), vmesh.num_cells()};
134 ConformalMesh<Shape::Hexahedron, 3, DataType_> mesh(size.data());
135
136 // Copy vertices
137 {
138 auto& vertices = mesh.get_vertex_set();
139 for(Index i(0); i < vmesh.num_vertices(); i++)
140 {
141 MeshHexer::Point p = vmesh.vertex(i);
142 vertices[i] = VertexType{p.x, p.y, p.z};
143 }
144 }
145
146 // Copy edges
147 {
148 auto& v_at_e = mesh.template get_index_set<1, 0>();
149 for(Index i(0); i < vmesh.num_edges(); i++)
150 {
151 v_at_e(i, 0) = vmesh.edge(i, 0);
152 v_at_e(i, 1) = vmesh.edge(i, 1);
153 }
154 }
155
156 // Copy faces
157 {
158 auto& v_at_f = mesh.template get_index_set<2, 0>();
159 for(Index i(0); i < vmesh.num_faces(); i++)
160 {
161 for(int j(0); j < 4; j++)
162 {
163 v_at_f(i, j) = vmesh.face(i, std::size_t(j));
164 }
165 }
166 }
167
168 // Copy cells
169 {
170 auto& v_at_c = mesh.template get_index_set<3, 0>();
171 for(Index i(0); i < vmesh.num_cells(); i++)
172 {
173 for(int j(0); j < 8; j++)
174 {
175 v_at_c(i, j) = vmesh.cell(i, std::size_t(j));
176 }
177 }
178 }
179
180 mesh.deduct_topology_from_top();
181
182 return std::make_pair(std::move(mesh), std::move(sdls));
183 }
184
185 template<typename DataType_>
186 std::pair<ConformalMesh<Shape::Hexahedron, 3, DataType_>, SubdivisionLevels>
187 MeshHexerSurfaceMesh::prepare_fbm_mesh(std::uint64_t levels)
188 {
189 const MeshHexer::BoundingBox bb = static_cast<MeshHexer::SurfaceMesh*>(_surface_mesh)->bounding_box();
190 return prepare_fbm_mesh<DataType_>(
191 DataType_(bb.min.x),
192 DataType_(bb.min.y),
193 DataType_(bb.min.z),
194 DataType_(bb.max.x),
195 DataType_(bb.max.y),
196 DataType_(bb.max.z),
197 levels);
198 }
199
200 void MeshHexerSurfaceMesh::write_to_file(const std::string& filename)
201 {
202 static_cast<MeshHexer::SurfaceMesh*>(_surface_mesh)->write_to_file(filename);
203 }
204
205 MeshHexerSurfaceMesh load_from_file(const String& filename, bool triangulate)
206 {
207 auto result = MeshHexer::load_from_file(filename, triangulate);
208
209 if(result.is_err())
210 {
211 std::cerr << result.err_ref() << "\n";
212 XABORTM("Reading MeshHexerSurfaceMesh failed!");
213 }
214
215 auto* mesh = new MeshHexer::SurfaceMesh();
216 *mesh = std::move(result).take_ok();
217
218 return MeshHexerSurfaceMesh(mesh);
219 }
220
221 template ConformalMesh<Shape::Hexahedron, 3, double>
222 MeshHexerSurfaceMesh::fbm_mesh(double, double, double, double, double, double, std::uint64_t);
223 template ConformalMesh<Shape::Hexahedron, 3, float>
224 MeshHexerSurfaceMesh::fbm_mesh(float, float, float, float, float, float, std::uint64_t);
225
226 template std::pair<ConformalMesh<Shape::Hexahedron, 3, double>, SubdivisionLevels>
227 MeshHexerSurfaceMesh::prepare_fbm_mesh(double, double, double, double, double, double, std::uint64_t);
228 template std::pair<ConformalMesh<Shape::Hexahedron, 3, float>, SubdivisionLevels>
229 MeshHexerSurfaceMesh::prepare_fbm_mesh(float, float, float, float, float, float, std::uint64_t);
230
231 template ConformalMesh<Shape::Hexahedron, 3, double> MeshHexerSurfaceMesh::fbm_mesh(std::uint64_t);
232 template ConformalMesh<Shape::Hexahedron, 3, float> MeshHexerSurfaceMesh::fbm_mesh(std::uint64_t);
233
234 template std::pair<ConformalMesh<Shape::Hexahedron, 3, double>, SubdivisionLevels>
236 template std::pair<ConformalMesh<Shape::Hexahedron, 3, float>, SubdivisionLevels>
238} // namespace FEAT::Geometry
239
240#endif
#define XABORTM(msg)
Abortion macro definition with custom message.
Definition: assertion.hpp:192
FEAT Kernel base header.
bool is_wound_consistently() const
Check if the winding order of the faces of the surface mesh is consistent.
bool is_outward_oriented() const
Check if the surface normals of all faces of the surface mesh point towards the unbounded side.
Gap min_gap()
Compute the smallest Gap of the surface mesh.
bool is_closed() const
Check if the surface mesh describes a closed surface.
ConformalMesh< Shape::Hexahedron, 3, DataType_ > fbm_mesh(DataType_ x_min, DataType_ y_min, DataType_ z_min, DataType_ x_max, DataType_ y_max, DataType_ z_max, std::uint64_t levels)
Create a non-fitted volume mesh for this surface mesh.
void write_to_file(const std::string &filename)
Write the surface mesh to disk.
std::pair< ConformalMesh< Shape::Hexahedron, 3, DataType_ >, SubdivisionLevels > prepare_fbm_mesh(DataType_ x_min, DataType_ y_min, DataType_ z_min, DataType_ x_max, DataType_ y_max, DataType_ z_max, std::uint64_t levels)
Create a non-fitted volume mesh for this surface mesh.
double minimal_aspect_ratio() const
Compute the smallest aspect ratio of any face of the surface mesh.
std::vector< Gap > gaps()
Compute Gap candidates of the surface mesh.
double maximal_aspect_ratio() const
Compute the largest aspect ratio of any face of the surface mesh.
Geometry namespace.
Intern::Layer Layer
Re-export of layer type.
MeshHexerSurfaceMesh load_from_file(const String &filename, bool triangulate=false)
Load a surface mesh from a file.
std::uint64_t Index
Index data type.