8#include <kernel/geometry/atlas/extrude.hpp>
9#include <kernel/geometry/conformal_mesh.hpp>
10#include <kernel/geometry/mesh_atlas.hpp>
11#include <kernel/geometry/mesh_node.hpp>
12#include <kernel/geometry/mesh_part.hpp>
13#include <kernel/geometry/index_calculator.hpp>
14#include <kernel/geometry/partition_set.hpp>
15#include <kernel/util/xml_scanner.hpp>
28 template<
typename SourceMesh_>
31 template<
typename SourceMesh_>
34 template<
typename SourceMesh_>
37 template<
typename SourceMesh_>
45 template<
typename Coord_>
49 typedef Coord_ CoordType;
114 _zmin_part_name(zmin_part_name),
115 _zmax_part_name(zmax_part_name),
116 _origin_x(CoordType(0)),
117 _origin_y(CoordType(0)),
118 _angle_y(CoordType(0)),
119 _angle_p(CoordType(0)),
120 _angle_r(CoordType(0)),
121 _offset_x(CoordType(0)),
122 _offset_y(CoordType(0)),
123 _offset_z(CoordType(0))
127 for(
Index i(0); i <= slices; ++i)
128 _z_list.push_back(z_min + (z_max-z_min)*CoordType(i)/CoordType(slices));
144 _slices(
Index(z_list.size())-1u),
145 _z_min(z_list.front()),
146 _z_max(z_list.back()),
147 _zmin_part_name(zmin_part_name),
148 _zmax_part_name(zmax_part_name),
149 _origin_x(CoordType(0)),
150 _origin_y(CoordType(0)),
151 _angle_y(CoordType(0)),
152 _angle_p(CoordType(0)),
153 _angle_r(CoordType(0)),
154 _offset_x(CoordType(0)),
155 _offset_y(CoordType(0)),
156 _offset_z(CoordType(0))
158 for(
Index i(0); i < _slices; ++i)
160 XASSERTM(_z_list[i] < z_list[i+1],
"z-coordinates not ascending");
182 void set_angles(CoordType yaw, CoordType pitch, CoordType roll)
213 XASSERT(hexa_num_entities !=
nullptr);
214 XASSERT(quad_num_entities !=
nullptr);
215 hexa_num_entities[0] = quad_num_entities[0] * (_slices + 1);
216 hexa_num_entities[1] = quad_num_entities[0] * _slices + quad_num_entities[1] * (_slices + 1);
217 hexa_num_entities[2] = quad_num_entities[1] * _slices + quad_num_entities[2] * (_slices + 1);
218 hexa_num_entities[3] = quad_num_entities[2] * _slices;
236 template<
typename SubChart_>
240 const SubChart_* sub_chart =
dynamic_cast<const SubChart_*
>(&quad_chart);
241 if(sub_chart ==
nullptr)
245 std::unique_ptr<Atlas::Extrude<HexaMesh, SubChart_>> the_chart(
247 std::unique_ptr<SubChart_>(
new SubChart_(*sub_chart))));
250 the_chart->set_origin(_origin_x, _origin_y);
251 the_chart->set_offset(_offset_x, _offset_y, _offset_z);
252 the_chart->set_angles(_angle_y, _angle_p, _angle_r);
254 hexa_chart = std::move(the_chart);
276 std::unique_ptr<HexaChart> hexa_chart;
287 XABORTM(
"Could not extrude 2D chart to 3D");
306 for(
auto& name : names)
310 XASSERT(quad_chart !=
nullptr);
313 std::unique_ptr<HexaChart>hexa_chart = extrude_chart(*quad_chart);
344 for(
Index j(0); j <= _slices; ++j)
347 const Index vo = j * quad_num_verts;
351 const CoordType z = _z_list.at(j);
354 for(
Index i(0); i < quad_num_verts; ++i)
357 tmp1[0] = quad_vtx[i][0] - _origin_x;
358 tmp1[1] = quad_vtx[i][1] - _origin_y;
361 hexa_vtx[vo+i][0] = tmp2[0] + _offset_x;
362 hexa_vtx[vo+i][1] = tmp2[1] + _offset_y;
363 hexa_vtx[vo+i][2] = tmp2[2] + _offset_z;
380 const auto& quad_edge = quad_topo.template get_index_set<1,0>();
381 const auto& quad_quad = quad_topo.template get_index_set<2,0>();
382 auto& hexa_edge = hexa_topo.template get_index_set<1,0>();
383 auto& hexa_quad = hexa_topo.template get_index_set<2,0>();
384 auto& hexa_hexa = hexa_topo.template get_index_set<3,0>();
386 const Index quad_num_entities[] =
388 quad_edge.get_index_bound(),
389 quad_edge.get_num_entities(),
390 quad_quad.get_num_entities()
394 XASSERT(hexa_edge.get_index_bound() == (quad_num_entities[0] * (_slices+1)));
395 XASSERT(hexa_edge.get_num_entities() == (quad_num_entities[0] * _slices + quad_num_entities[1] * (_slices+1)));
396 XASSERT(hexa_quad.get_num_entities() == (quad_num_entities[1] * _slices + quad_num_entities[2] * (_slices+1)));
397 XASSERT(hexa_hexa.get_num_entities() == (quad_num_entities[2] * _slices));
400 for(
Index j(0); j <= _slices; ++j)
403 const Index vo = j * quad_num_entities[0];
406 const Index eo = j * quad_num_entities[1];
409 for(
Index i(0); i < quad_num_entities[1]; ++i)
411 hexa_edge[eo+i][0] = vo + quad_edge[i][0];
412 hexa_edge[eo+i][1] = vo + quad_edge[i][1];
417 for(
Index j(0); j < _slices; ++j)
420 const Index vo = j * quad_num_entities[0];
423 const Index eo = j * quad_num_entities[0] + (_slices+1) * quad_num_entities[1];
426 for(
Index i(0); i < quad_num_entities[0]; ++i)
428 hexa_edge[eo+i][0] = vo + i;
429 hexa_edge[eo+i][1] = vo + i + quad_num_entities[0];
434 for(
Index j(0); j <= _slices; ++j)
437 const Index vo = j * quad_num_entities[0];
440 const Index qo = j * quad_num_entities[2];
443 for(
Index i(0); i < quad_num_entities[2]; ++i)
445 hexa_quad[qo+i][0] = vo + quad_quad[i][0];
446 hexa_quad[qo+i][1] = vo + quad_quad[i][1];
447 hexa_quad[qo+i][2] = vo + quad_quad[i][2];
448 hexa_quad[qo+i][3] = vo + quad_quad[i][3];
453 for(
Index j(0); j < _slices; ++j)
456 const Index vo = j * quad_num_entities[0];
459 const Index qo = j * quad_num_entities[1] + (_slices+1) * quad_num_entities[2];
462 for(
Index i(0); i < quad_num_entities[1]; ++i)
464 hexa_quad[qo+i][0] = vo + quad_edge[i][0];
465 hexa_quad[qo+i][1] = vo + quad_edge[i][1];
466 hexa_quad[qo+i][2] = vo + quad_edge[i][0] + quad_num_entities[0];
467 hexa_quad[qo+i][3] = vo + quad_edge[i][1] + quad_num_entities[0];
472 for(
Index j(0); j < _slices; ++j)
475 const Index vo = j * quad_num_entities[0];
478 const Index ho = j * quad_num_entities[2];
481 for(
Index i(0); i < quad_num_entities[2]; ++i)
483 hexa_hexa[ho+i][0] = vo + quad_quad[i][0];
484 hexa_hexa[ho+i][1] = vo + quad_quad[i][1];
485 hexa_hexa[ho+i][2] = vo + quad_quad[i][2];
486 hexa_hexa[ho+i][3] = vo + quad_quad[i][3];
487 hexa_hexa[ho+i][4] = vo + quad_quad[i][0] + quad_num_entities[0];
488 hexa_hexa[ho+i][5] = vo + quad_quad[i][1] + quad_num_entities[0];
489 hexa_hexa[ho+i][6] = vo + quad_quad[i][2] + quad_num_entities[0];
490 hexa_hexa[ho+i][7] = vo + quad_quad[i][3] + quad_num_entities[0];
513 const auto& qv = quad_mapp.template get_target_set<0>();
514 const auto& qe = quad_mapp.template get_target_set<1>();
515 const auto& qq = quad_mapp.template get_target_set<2>();
516 auto& hv = hexa_mapp.template get_target_set<0>();
517 auto& he = hexa_mapp.template get_target_set<1>();
518 auto& hq = hexa_mapp.template get_target_set<2>();
519 auto& hh = hexa_mapp.template get_target_set<3>();
521 const Index quad_num_entities[] =
528 const Index quad_part_num_entities[] =
530 qv.get_num_entities(),
531 qe.get_num_entities(),
532 qq.get_num_entities()
536 for(
Index j(0); j <= _slices; ++j)
538 const Index vom = j * quad_num_entities[0];
539 const Index vop = j * quad_part_num_entities[0];
541 for(
Index i(0); i < quad_part_num_entities[0]; ++i)
542 hv[vop+i] = vom + qv[i];
546 for(
Index j(0); j <= _slices; ++j)
548 const Index eom = j * quad_num_entities[1];
549 const Index eop = j * quad_part_num_entities[1];
551 for(
Index i(0); i < quad_part_num_entities[1]; ++i)
552 he[eop+i] = eom + qe[i];
556 for(
Index j(0); j <= _slices; ++j)
558 const Index qom = j * quad_num_entities[2];
559 const Index qop = j * quad_part_num_entities[2];
561 for(
Index i(0); i < quad_part_num_entities[2]; ++i)
562 hq[qop+i] = qom + qq[i];
566 for(
Index j(0); j < _slices; ++j)
568 const Index eom = j * quad_num_entities[0] + (_slices+1)*quad_num_entities[1];
569 const Index eop = j * quad_part_num_entities[0] + (_slices+1)*quad_part_num_entities[1];
571 for(
Index i(0); i < quad_part_num_entities[0]; ++i)
572 he[eop+i] = eom + qv[i];
576 for(
Index j(0); j < _slices; ++j)
578 const Index qom = j * quad_num_entities[1] + (_slices+1)*quad_num_entities[2];
579 const Index qop = j * quad_part_num_entities[1] + (_slices+1)*quad_part_num_entities[2];
581 for(
Index i(0); i < quad_part_num_entities[1]; ++i)
582 hq[qop+i] = qom + qe[i];
586 for(
Index j(0); j < _slices; ++j)
588 const Index hom = j * quad_num_entities[2];
589 const Index hop = j * quad_part_num_entities[2];
591 for(
Index i(0); i < quad_part_num_entities[2]; ++i)
592 hh[hop+i] = hom + qq[i];
596 void extrude_slice_mapping(HexaTrgSetHolder& hexa_mapp,
const QuadMesh& quad_parent,
const Index slice)
const
600 const Index nv = quad_parent.get_num_entities(0);
601 const Index ne = quad_parent.get_num_entities(1);
602 const Index nq = quad_parent.get_num_entities(2);
605 const Index ov = slice * nv;
606 const Index oe = slice * ne;
607 const Index oq = slice * nq;
610 auto& hv = hexa_mapp.template get_target_set<0>();
611 for(
Index i(0); i < nv; ++i)
615 auto& he = hexa_mapp.template get_target_set<1>();
616 for(
Index i(0); i < ne; ++i)
620 auto& hq = hexa_mapp.template get_target_set<2>();
621 for(
Index i(0); i < nq; ++i)
640 XASSERT(hexa_attrib.get() ==
nullptr);
641 hexa_attrib.reset(
new HexaAttrib(quad_num_values * (_slices+1), attrib_dim+1));
644 for(
Index j(0); j <= _slices; ++j)
647 const Index vo = j * quad_num_values;
651 const CoordType z = _z_list.at(j);
654 for(
Index i(0); i < quad_num_values; ++i)
656 for(
int k(0); k < attrib_dim; ++k)
658 hexa_attrib->operator()(vo+i,k) = quad_attrib(i,k);
660 hexa_attrib->operator()(vo+i, attrib_dim) = z;
683 _slices * quad_graph.get_num_nodes_image(), _slices * quad_graph.
get_num_indices());
693 for(
Index i(0); i < num_patches; ++i)
697 for(
Index j(q_ptr[i]); j < q_ptr[i+1]; ++j)
700 for(
Index k(0); k < _slices; ++k, ++hp)
701 h_idx[hp] = (k*quad_num_elems) + q_idx[j];
722 const auto& quad_parts = quad_part_set.get_partitions();
723 for(
auto it = quad_parts.begin(); it != quad_parts.end(); ++it)
726 extrude_partition(hexa_parti, *it);
727 hexa_part_set.add_partition(std::move(hexa_parti));
764 hexa_root_node.set_mesh(factory.make_unique());
769 for(
const auto& name : part_names)
774 if(quad_part ==
nullptr)
782 if(!chart_name.empty() && (hexa_atlas !=
nullptr))
789 hexa_root_node.
add_mesh_part(name, factory.make_unique(), chart_name, hexa_chart);
793 if(!_zmin_part_name.empty())
796 hexa_root_node.
add_mesh_part(_zmin_part_name, factory.make_unique());
798 if(!_zmax_part_name.empty())
801 hexa_root_node.
add_mesh_part(_zmax_part_name, factory.make_unique());
814 template<
typename Coord_>
816 public Factory<ConformalMesh<Shape::Hypercube<3>, 3, Coord_>>
829 Index _hexa_num_entities[4];
842 _mesh_extruder(mesh_extruder),
843 _quad_mesh(quad_mesh)
845 const Index quad_num_entities[3] =
851 _mesh_extruder.extrude_num_entities(_hexa_num_entities, quad_num_entities);
854 virtual Index get_num_entities(
int dim)
override
857 return _hexa_num_entities[dim];
860 virtual void fill_vertex_set(VertexSetType& vertex_set)
override
862 _mesh_extruder.extrude_vertex_set(vertex_set, _quad_mesh.
get_vertex_set());
865 virtual void fill_index_sets(IndexSetHolderType& index_set_holder)
override
867 _mesh_extruder.extrude_topology(index_set_holder, _quad_mesh.get_index_set_holder());
879 template<
typename Coord_>
881 public Factory<MeshPart<ConformalMesh<Shape::Hypercube<3>, 3, Coord_>>>
901 Index _hexa_num_entities[4];
917 _mesh_extruder(mesh_extruder),
918 _quad_part(quad_part),
919 _quad_parent(quad_parent)
921 const Index quad_num_entities[3] =
927 _mesh_extruder.extrude_num_entities(_hexa_num_entities, quad_num_entities);
930 virtual Index get_num_entities(
int dim)
override
933 return _hexa_num_entities[dim];
936 virtual void fill_target_sets(TargetSetHolderType& target_set_holder)
override
938 _mesh_extruder.extrude_mapping(target_set_holder, _quad_part.get_target_set_holder(), _quad_parent);
941 virtual void fill_index_sets(std::unique_ptr<IndexSetHolderType>& index_set_holder)
override
945 index_set_holder.reset(
new IndexSetHolderType(_hexa_num_entities));
946 _mesh_extruder.extrude_topology(*index_set_holder, *_quad_part.get_topology());
950 virtual void fill_attribute_sets(AttributeSetContainer& attribute_container)
override
955 std::unique_ptr<HexaAttribute> hexa_attrib;
956 _mesh_extruder.extrude_attribute(hexa_attrib, *(quad_attrib.second));
957 attribute_container.insert(std::make_pair(quad_attrib.first, std::move(hexa_attrib)));
970 template<
typename Coord_>
972 public Factory<MeshPart<ConformalMesh<Shape::Hypercube<3>, 3, Coord_>>>
996 _mesh_extruder(mesh_extruder),
997 _quad_parent(quad_parent),
1003 virtual Index get_num_entities(
int dim)
override
1009 virtual void fill_target_sets(TargetSetHolderType& target_set_holder)
override
1011 _mesh_extruder.extrude_slice_mapping(target_set_holder, _quad_parent, _slice);
1014 virtual void fill_index_sets(std::unique_ptr<IndexSetHolderType>& index_set_holder)
override
1016 index_set_holder.reset();
1019 virtual void fill_attribute_sets(AttributeSetContainer& )
override
#define XABORTM(msg)
Abortion macro definition with custom message.
#define XASSERT(expr)
Assertion macro definition.
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Adjacency Graph implementation.
Index * get_domain_ptr()
Returns the domain pointer array.
Index * get_image_idx()
Returns the image node index array.
Index get_num_indices() const
Returns the total number indices.
Bezier chart class template.
Circle chart class template.
Container for saving data related to mesh entities.
Index get_num_values() const
Returns the number of attribute values.
int get_dimension() const
Returns the number attribute dimension.
Mesh Factory class template.
Mesh Atlas class template.
MeshChartType * find_mesh_chart(const String &name)
Searches for a mesh chart.
std::deque< String > get_chart_names() const
Returns the names of all charts of this atlas.
bool add_mesh_chart(const String &name, std::unique_ptr< MeshChartType > chart, bool replace=false)
Inserts a new chart into the map.
MeshPartType * find_mesh_part(const String &part_name)
Searches this container for a MeshPart.
String find_mesh_part_chart_name(const String &part_name) const
Searches for a chart name belonging to a MeshPart by name.
std::deque< String > get_mesh_part_names(bool no_internals=false) const
Returns the names of all mesh parts of this node.
MeshType * get_mesh()
Returns the mesh of this node.
MeshPartNodeType * add_mesh_part(const String &part_name, std::unique_ptr< MeshPartType > mesh_part, const String &chart_name="", const MeshChartType *chart=nullptr)
Adds a new mesh-part child node.
Class template for partial meshes.
const AttributeSetContainer & get_mesh_attributes() const
Returns a const reference to the mesh attributes container.
bool has_topology() const
Checks if this MeshPart has a mesh topology.
TargetSetHolder< ShapeType > TargetSetHolderType
Target set holder type.
IndexSetHolder< ShapeType > IndexSetHolderType
Index set holder type.
Index get_num_entities(int dim) const
Returns the number of entities.
std::map< String, std::unique_ptr< AttributeSetType > > AttributeSetContainer
submesh node bin container type
Index get_num_patches() const
Index get_num_elements() const
const Adjacency::Graph & get_patches() const
static void compute(IndexSetHolder< Shape_ > &index_set_holder)
Routine that does the actual work.
Root mesh node class template.
String class implementation.
Tiny Matrix class template.
CUDA_HOST_DEVICE Matrix & set_rotation_3d(T_ yaw, T_ pitch, T_ roll)
Sets this matrix to a 3D yaw-pitch-roll rotation matrix.
Tiny Vector class template.
CUDA_HOST_DEVICE Vector & set_mat_vec_mult(const Matrix< T_, n_, m_, sma_, sna_ > &a, const Vector< T_, m_, sx_ > &x)
Sets this vector to the result of a matrix-vector product.
std::uint64_t Index
Index data type.
Fixed-Sized Vertex Set class template.
Index get_num_vertices() const
Returns the number of vertices in the vertex set.