FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
mesh_extruder.hpp
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
6#pragma once
7
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>
16
17#include <sstream>
18#include <deque>
19
20namespace FEAT
21{
22 namespace Geometry
23 {
24 // Forward declarations of generic extruder class templates
25 // Note: The following templates are only implemented for
26 // SourceMesh_ = ConformalMesh<Hypercube<2>, 2, ...>
27
28 template<typename SourceMesh_>
30
31 template<typename SourceMesh_>
33
34 template<typename SourceMesh_>
36
37 template<typename SourceMesh_>
39
45 template<typename Coord_>
46 class MeshExtruder<ConformalMesh<Shape::Hypercube<2>, 2, Coord_>>
47 {
48 public:
49 typedef Coord_ CoordType;
50
53
56
59
62
65
66 typedef typename QuadMesh::IndexSetHolderType QuadTopology;
67 typedef typename HexaMesh::IndexSetHolderType HexaTopology;
68
71
72 typedef typename QuadPart::TargetSetHolderType QuadTrgSetHolder;
73 typedef typename HexaPart::TargetSetHolderType HexaTrgSetHolder;
74
77
78 protected:
80 std::deque<CoordType> _z_list;
84 const CoordType _z_min, _z_max;
86 String _zmin_part_name, _zmax_part_name;
88 CoordType _origin_x, _origin_y;
90 CoordType _angle_y, _angle_p, _angle_r;
92 CoordType _offset_x, _offset_y, _offset_z;
93
94 public:
109 explicit MeshExtruder(Index slices, CoordType z_min, CoordType z_max, String zmin_part_name, String zmax_part_name) :
110 _z_list(),
111 _slices(slices),
112 _z_min(z_min),
113 _z_max(z_max),
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))
124 {
125 XASSERT(slices > Index(0));
126 XASSERT(z_min < z_max);
127 for(Index i(0); i <= slices; ++i)
128 _z_list.push_back(z_min + (z_max-z_min)*CoordType(i)/CoordType(slices));
129 }
130
142 explicit MeshExtruder(const std::deque<CoordType>& z_list, String zmin_part_name, String zmax_part_name) :
143 _z_list(z_list),
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))
157 {
158 for(Index i(0); i < _slices; ++i)
159 {
160 XASSERTM(_z_list[i] < z_list[i+1], "z-coordinates not ascending");
161 }
162 }
163
170 void set_origin(CoordType x, CoordType y)
171 {
172 _origin_x = x;
173 _origin_y = y;
174 }
175
182 void set_angles(CoordType yaw, CoordType pitch, CoordType roll)
183 {
184 _angle_y = yaw;
185 _angle_p = pitch;
186 _angle_r = roll;
187 }
188
195 void set_offset(CoordType x, CoordType y, CoordType z)
196 {
197 _offset_x = x;
198 _offset_y = y;
199 _offset_z = z;
200 }
201
211 void extrude_num_entities(Index hexa_num_entities[], const Index quad_num_entities[]) const
212 {
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;
219 }
220
236 template<typename SubChart_>
237 bool try_extrude_chart(std::unique_ptr<HexaChart>& hexa_chart, const QuadChart& quad_chart) const
238 {
239 // try down-cast to sub-chart
240 const SubChart_* sub_chart = dynamic_cast<const SubChart_*>(&quad_chart);
241 if(sub_chart == nullptr)
242 return false;
243
244 // success; create the extruded hexa chart
245 std::unique_ptr<Atlas::Extrude<HexaMesh, SubChart_>> the_chart(
247 std::unique_ptr<SubChart_>(new SubChart_(*sub_chart))));
248
249 // set our transformation
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);
253
254 hexa_chart = std::move(the_chart);
255 return true;
256 }
257
270 std::unique_ptr<HexaChart> extrude_chart(const QuadChart& quad_chart) const
271 {
272 // The following ugly piece of code is a trial-&-error sequence using
273 // dynamic-cast to figure out the actual type of the 2D chart.
274 // That's not an elegant solution, but I don't have any other ideas...
275
276 std::unique_ptr<HexaChart> hexa_chart;
277
278 // Is it a Circle chart?
279 if(this->template try_extrude_chart<Atlas::Circle<QuadMesh>>(hexa_chart, quad_chart))
280 return hexa_chart;
281
282 // Is it a Bezier chart?
283 if(this->template try_extrude_chart<Atlas::Bezier<QuadMesh>>(hexa_chart, quad_chart))
284 return hexa_chart;
285
286 // If we come out here then we failed to extrude the 2D chart for some reason...
287 XABORTM("Could not extrude 2D chart to 3D");
288 }
289
302 void extrude_atlas(HexaAtlas& hexa_atlas, const QuadAtlas& quad_atlas) const
303 {
304 // get chart names
305 auto names = quad_atlas.get_chart_names();
306 for(auto& name : names)
307 {
308 // get input chart
309 const QuadChart* quad_chart = quad_atlas.find_mesh_chart(name);
310 XASSERT(quad_chart != nullptr);
311
312 // extrude chart
313 std::unique_ptr<HexaChart>hexa_chart = extrude_chart(*quad_chart);
314
315 // add to hexa atlas
316 hexa_atlas.add_mesh_chart(name, std::move(hexa_chart));
317 }
318 }
319
330 void extrude_vertex_set(HexaVertexSet& hexa_vtx, const QuadVertexSet& quad_vtx) const
331 {
332 // get number of source vertices
333 const Index quad_num_verts = quad_vtx.get_num_vertices();
334
335 // validate vertex count in hexa vertex set
336 XASSERT(hexa_vtx.get_num_vertices() == (quad_num_verts * (_slices+1)));
337
338 // compute rigid rotation matrix
340 rotation.set_rotation_3d(_angle_y, _angle_p, _angle_r);
342
343 // loop over all slices
344 for(Index j(0); j <= _slices; ++j)
345 {
346 // compute slice index offset
347 const Index vo = j * quad_num_verts;
348
349 // compute slice z-coord
350 //const CoordType z = _z_min + (CoordType(j) / CoordType(_slices))*(_z_max - _z_min);
351 const CoordType z = _z_list.at(j);
352
353 // loop over all vertices
354 for(Index i(0); i < quad_num_verts; ++i)
355 {
356 // apply our rigid transformation
357 tmp1[0] = quad_vtx[i][0] - _origin_x;
358 tmp1[1] = quad_vtx[i][1] - _origin_y;
359 tmp1[2] = z;
360 tmp2.set_mat_vec_mult(rotation, tmp1);
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;
364 }
365 }
366 }
367
377 void extrude_topology(HexaTopology& hexa_topo, const QuadTopology& quad_topo) const
378 {
379 // fetch index sets
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>();
385
386 const Index quad_num_entities[] =
387 {
388 quad_edge.get_index_bound(),
389 quad_edge.get_num_entities(),
390 quad_quad.get_num_entities()
391 };
392
393 // validate dimensions
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));
398
399 // loop over all slices (edges in x/y-direction)
400 for(Index j(0); j <= _slices; ++j)
401 {
402 // compute slice vertex index offset
403 const Index vo = j * quad_num_entities[0];
404
405 // compute slice edge index offset
406 const Index eo = j * quad_num_entities[1];
407
408 // loop over all edges
409 for(Index i(0); i < quad_num_entities[1]; ++i)
410 {
411 hexa_edge[eo+i][0] = vo + quad_edge[i][0];
412 hexa_edge[eo+i][1] = vo + quad_edge[i][1];
413 }
414 }
415
416 // loop over all slice intervals (edges in z-direction)
417 for(Index j(0); j < _slices; ++j)
418 {
419 // compute slice vertex index offset
420 const Index vo = j * quad_num_entities[0];
421
422 // compute slice edge index offset
423 const Index eo = j * quad_num_entities[0] + (_slices+1) * quad_num_entities[1];
424
425 // loop over all vertices
426 for(Index i(0); i < quad_num_entities[0]; ++i)
427 {
428 hexa_edge[eo+i][0] = vo + i;
429 hexa_edge[eo+i][1] = vo + i + quad_num_entities[0];
430 }
431 }
432
433 // loop over all slices (quads in x/y-direction)
434 for(Index j(0); j <= _slices; ++j)
435 {
436 // compute slice vertex index offset
437 const Index vo = j * quad_num_entities[0];
438
439 // compute slice quad index offset
440 const Index qo = j * quad_num_entities[2];
441
442 // loop over all quads
443 for(Index i(0); i < quad_num_entities[2]; ++i)
444 {
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];
449 }
450 }
451
452 // loop over all slice intervals (quads in z-direction)
453 for(Index j(0); j < _slices; ++j)
454 {
455 // compute slice vertex index offset
456 const Index vo = j * quad_num_entities[0];
457
458 // compute slice quad index offset
459 const Index qo = j * quad_num_entities[1] + (_slices+1) * quad_num_entities[2];
460
461 // loop over all edges
462 for(Index i(0); i < quad_num_entities[1]; ++i)
463 {
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];
468 }
469 }
470
471 // loop over all slices (quads in x/y-direction)
472 for(Index j(0); j < _slices; ++j)
473 {
474 // compute slice vertex index offset
475 const Index vo = j * quad_num_entities[0];
476
477 // compute slice quad index offset
478 const Index ho = j * quad_num_entities[2];
479
480 // loop over all quads
481 for(Index i(0); i < quad_num_entities[2]; ++i)
482 {
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];
491 }
492 }
493
494 // build redundant index sets
496 }
497
510 void extrude_mapping(HexaTrgSetHolder& hexa_mapp, const QuadTrgSetHolder& quad_mapp, const QuadMesh& quad_parent) const
511 {
512 // fetch target sets
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>();
520
521 const Index quad_num_entities[] =
522 {
523 quad_parent.get_num_entities(0),
524 quad_parent.get_num_entities(1),
525 quad_parent.get_num_entities(2)
526 };
527
528 const Index quad_part_num_entities[] =
529 {
530 qv.get_num_entities(),
531 qe.get_num_entities(),
532 qq.get_num_entities()
533 };
534
535 // compute vertices from vertices
536 for(Index j(0); j <= _slices; ++j)
537 {
538 const Index vom = j * quad_num_entities[0];
539 const Index vop = j * quad_part_num_entities[0];
540
541 for(Index i(0); i < quad_part_num_entities[0]; ++i)
542 hv[vop+i] = vom + qv[i];
543 }
544
545 // compute edges from edges
546 for(Index j(0); j <= _slices; ++j)
547 {
548 const Index eom = j * quad_num_entities[1];
549 const Index eop = j * quad_part_num_entities[1];
550
551 for(Index i(0); i < quad_part_num_entities[1]; ++i)
552 he[eop+i] = eom + qe[i];
553 }
554
555 // compute quads from quads
556 for(Index j(0); j <= _slices; ++j)
557 {
558 const Index qom = j * quad_num_entities[2];
559 const Index qop = j * quad_part_num_entities[2];
560
561 for(Index i(0); i < quad_part_num_entities[2]; ++i)
562 hq[qop+i] = qom + qq[i];
563 }
564
565 // compute edges from extruded vertices
566 for(Index j(0); j < _slices; ++j)
567 {
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];
570
571 for(Index i(0); i < quad_part_num_entities[0]; ++i)
572 he[eop+i] = eom + qv[i];
573 }
574
575 // compute quads from extruded edges
576 for(Index j(0); j < _slices; ++j)
577 {
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];
580
581 for(Index i(0); i < quad_part_num_entities[1]; ++i)
582 hq[qop+i] = qom + qe[i];
583 }
584
585 // compute hexas from extruded quads
586 for(Index j(0); j < _slices; ++j)
587 {
588 const Index hom = j * quad_num_entities[2];
589 const Index hop = j * quad_part_num_entities[2];
590
591 for(Index i(0); i < quad_part_num_entities[2]; ++i)
592 hh[hop+i] = hom + qq[i];
593 }
594 }
595
596 void extrude_slice_mapping(HexaTrgSetHolder& hexa_mapp, const QuadMesh& quad_parent, const Index slice) const
597 {
598 XASSERT(slice <= _slices);
599
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);
603
604 // compute offsets
605 const Index ov = slice * nv;
606 const Index oe = slice * ne;
607 const Index oq = slice * nq;
608
609 // fill vertex mapping
610 auto& hv = hexa_mapp.template get_target_set<0>();
611 for(Index i(0); i < nv; ++i)
612 hv[i] = ov + i;
613
614 // fill vertex mapping
615 auto& he = hexa_mapp.template get_target_set<1>();
616 for(Index i(0); i < ne; ++i)
617 he[i] = oe + i;
618
619 // fill vertex mapping
620 auto& hq = hexa_mapp.template get_target_set<2>();
621 for(Index i(0); i < nq; ++i)
622 hq[i] = oq + i;
623 }
624
634 void extrude_attribute(std::unique_ptr<HexaAttrib>& hexa_attrib, const QuadAttrib& quad_attrib) const
635 {
636 const Index quad_num_values = quad_attrib.get_num_values();
637 const int attrib_dim = quad_attrib.get_dimension();
638
639 // create attribute
640 XASSERT(hexa_attrib.get() == nullptr);
641 hexa_attrib.reset(new HexaAttrib(quad_num_values * (_slices+1), attrib_dim+1));
642
643 // loop over all slices
644 for(Index j(0); j <= _slices; ++j)
645 {
646 // compute slice index offset
647 const Index vo = j * quad_num_values;
648
649 // compute slice z-coord
650 //const CoordType z = _z_min + (CoordType(j) / CoordType(_slices))*(_z_max - _z_min);
651 const CoordType z = _z_list.at(j);
652
653 // loop over all vertices
654 for(Index i(0); i < quad_num_values; ++i)
655 {
656 for(int k(0); k < attrib_dim; ++k)
657 {
658 hexa_attrib->operator()(vo+i,k) = quad_attrib(i,k);
659 }
660 hexa_attrib->operator()(vo+i, attrib_dim) = z;
661 }
662 }
663 }
664
674 void extrude_partition(Partition& hexa_parti, const Partition& quad_parti) const
675 {
676 const Adjacency::Graph& quad_graph = quad_parti.get_patches();
677
678 const Index num_patches = quad_parti.get_num_patches();
679 const Index quad_num_elems = quad_parti.get_num_elements();
680
681 // allocate adjacency graph
682 Adjacency::Graph hexa_graph(quad_graph.get_num_nodes_domain(),
683 _slices * quad_graph.get_num_nodes_image(), _slices * quad_graph.get_num_indices());
684
685 // get arrays
686 const Index* q_ptr = quad_graph.get_domain_ptr();
687 const Index* q_idx = quad_graph.get_image_idx();
688 Index* h_ptr = hexa_graph.get_domain_ptr();
689 Index* h_idx = hexa_graph.get_image_idx();
690
691 // loop over all patches
692 h_ptr[0] = Index(0);
693 for(Index i(0); i < num_patches; ++i)
694 {
695 Index hp = h_ptr[i];
696 // loop over all elements in patch
697 for(Index j(q_ptr[i]); j < q_ptr[i+1]; ++j)
698 {
699 // add the element for each slice
700 for(Index k(0); k < _slices; ++k, ++hp)
701 h_idx[hp] = (k*quad_num_elems) + q_idx[j];
702 }
703 h_ptr[i+1] = hp;
704 }
705
706 // create the partition
707 hexa_parti = Partition(std::move(hexa_graph), quad_parti.get_name(),
708 quad_parti.get_priority(), quad_parti.get_level());
709 }
710
720 void extrude_partition_set(PartitionSet& hexa_part_set, const PartitionSet& quad_part_set) const
721 {
722 const auto& quad_parts = quad_part_set.get_partitions();
723 for(auto it = quad_parts.begin(); it != quad_parts.end(); ++it)
724 {
725 Partition hexa_parti;
726 extrude_partition(hexa_parti, *it);
727 hexa_part_set.add_partition(std::move(hexa_parti));
728 }
729 }
730
755 void extrude_root_node(HexaRootNode& hexa_root_node, const QuadRootNode& quad_root_node, const HexaAtlas* hexa_atlas) const
756 {
757 // get root mesh
758 const QuadMesh* quad_mesh = quad_root_node.get_mesh();
759 XASSERT(quad_mesh != nullptr);
760
761 // extrude root mesh
762 {
763 MeshExtruderFactory<QuadMesh> factory(*this, *quad_mesh);
764 hexa_root_node.set_mesh(factory.make_unique());
765 }
766
767 // extrude mesh parts
768 auto part_names = quad_root_node.get_mesh_part_names();
769 for(const auto& name : part_names)
770 {
771 // get the quad part
772 const QuadPart* quad_part = quad_root_node.find_mesh_part(name);
773
774 if(quad_part == nullptr)
775 continue;
776
777 // get the chart name
778 String chart_name = quad_root_node.find_mesh_part_chart_name(name);
779 const HexaChart* hexa_chart(nullptr);
780
781 // try to find the chart
782 if(!chart_name.empty() && (hexa_atlas != nullptr))
783 hexa_chart = hexa_atlas->find_mesh_chart(chart_name);
784
785 // create mesh part extruder factory
786 MeshPartExtruderFactory<QuadMesh> factory(*this, *quad_part, *quad_mesh);
787
788 // create hexa mesh part and insert into root node
789 hexa_root_node.add_mesh_part(name, factory.make_unique(), chart_name, hexa_chart);
790 }
791
792 // add zmin/zmax mesh-parts
793 if(!_zmin_part_name.empty())
794 {
795 MeshPartSliceExtruderFactory<QuadMesh> factory(*this, *quad_mesh, _zmin_part_name, Index(0));
796 hexa_root_node.add_mesh_part(_zmin_part_name, factory.make_unique());
797 }
798 if(!_zmax_part_name.empty())
799 {
800 MeshPartSliceExtruderFactory<QuadMesh> factory(*this, *quad_mesh, _zmax_part_name, _slices);
801 hexa_root_node.add_mesh_part(_zmax_part_name, factory.make_unique());
802 }
803 }
804 }; // class MeshExtruder<ConformalMesh<Hypercube<2>,...>>
805
814 template<typename Coord_>
815 class MeshExtruderFactory<ConformalMesh<Shape::Hypercube<2>, 2, Coord_>> :
816 public Factory<ConformalMesh<Shape::Hypercube<3>, 3, Coord_>>
817 {
818 public:
822
823 typedef typename HexaMesh::VertexSetType VertexSetType;
824 typedef typename HexaMesh::IndexSetHolderType IndexSetHolderType;
825
826 protected:
827 const MeshExtruderType& _mesh_extruder;
828 const QuadMesh& _quad_mesh;
829 Index _hexa_num_entities[4];
830
831 public:
841 explicit MeshExtruderFactory(const MeshExtruderType& mesh_extruder, const QuadMesh& quad_mesh) :
842 _mesh_extruder(mesh_extruder),
843 _quad_mesh(quad_mesh)
844 {
845 const Index quad_num_entities[3] =
846 {
847 _quad_mesh.get_num_entities(0),
848 _quad_mesh.get_num_entities(1),
849 _quad_mesh.get_num_entities(2)
850 };
851 _mesh_extruder.extrude_num_entities(_hexa_num_entities, quad_num_entities);
852 }
853
854 virtual Index get_num_entities(int dim) override
855 {
856 XASSERT(dim < 4);
857 return _hexa_num_entities[dim];
858 }
859
860 virtual void fill_vertex_set(VertexSetType& vertex_set) override
861 {
862 _mesh_extruder.extrude_vertex_set(vertex_set, _quad_mesh.get_vertex_set());
863 }
864
865 virtual void fill_index_sets(IndexSetHolderType& index_set_holder) override
866 {
867 _mesh_extruder.extrude_topology(index_set_holder, _quad_mesh.get_index_set_holder());
868 }
869 }; // class MeshExtruderFactory<ConformalMesh<Shape::Hypercube<2>,...>>
870
879 template<typename Coord_>
880 class MeshPartExtruderFactory<ConformalMesh<Shape::Hypercube<2>, 2, Coord_>> :
881 public Factory<MeshPart<ConformalMesh<Shape::Hypercube<3>, 3, Coord_>>>
882 {
883 public:
886
889
891
892 typedef typename HexaPart::IndexSetHolderType IndexSetHolderType;
893 typedef typename HexaPart::TargetSetHolderType TargetSetHolderType;
894 typedef typename HexaPart::AttributeSetContainer AttributeSetContainer;
896
897 protected:
898 const MeshExtruderType& _mesh_extruder;
899 const QuadPart& _quad_part;
900 const QuadMesh& _quad_parent;
901 Index _hexa_num_entities[4];
902
903 public:
916 explicit MeshPartExtruderFactory(const MeshExtruderType& mesh_extruder, const QuadPart& quad_part, const QuadMesh& quad_parent) :
917 _mesh_extruder(mesh_extruder),
918 _quad_part(quad_part),
919 _quad_parent(quad_parent)
920 {
921 const Index quad_num_entities[3] =
922 {
923 _quad_part.get_num_entities(0),
924 _quad_part.get_num_entities(1),
925 _quad_part.get_num_entities(2)
926 };
927 _mesh_extruder.extrude_num_entities(_hexa_num_entities, quad_num_entities);
928 }
929
930 virtual Index get_num_entities(int dim) override
931 {
932 XASSERT(dim < 4);
933 return _hexa_num_entities[dim];
934 }
935
936 virtual void fill_target_sets(TargetSetHolderType& target_set_holder) override
937 {
938 _mesh_extruder.extrude_mapping(target_set_holder, _quad_part.get_target_set_holder(), _quad_parent);
939 }
940
941 virtual void fill_index_sets(std::unique_ptr<IndexSetHolderType>& index_set_holder) override
942 {
943 if(_quad_part.has_topology())
944 {
945 index_set_holder.reset(new IndexSetHolderType(_hexa_num_entities));
946 _mesh_extruder.extrude_topology(*index_set_holder, *_quad_part.get_topology());
947 }
948 }
949
950 virtual void fill_attribute_sets(AttributeSetContainer& attribute_container) override
951 {
952 // extrude attributes
953 for(const auto& quad_attrib : _quad_part.get_mesh_attributes())
954 {
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)));
958 }
959 }
960 }; // class MeshPartExtruderFactory<ConformalMesh<Shape::Hypercube<2>,...>>
961
970 template<typename Coord_>
971 class MeshPartSliceExtruderFactory<ConformalMesh<Shape::Hypercube<2>, 2, Coord_>> :
972 public Factory<MeshPart<ConformalMesh<Shape::Hypercube<3>, 3, Coord_>>>
973 {
974 public:
977
980
982
983 typedef typename HexaPart::IndexSetHolderType IndexSetHolderType;
984 typedef typename HexaPart::TargetSetHolderType TargetSetHolderType;
985 typedef typename HexaPart::AttributeSetContainer AttributeSetContainer;
987
988 protected:
989 const MeshExtruderType& _mesh_extruder;
990 const QuadMesh& _quad_parent;
991 Index _slice;
992 String _name;
993
994 public:
995 explicit MeshPartSliceExtruderFactory(const MeshExtruderType& mesh_extruder, const QuadMesh& quad_parent, const String& name, const Index slice) :
996 _mesh_extruder(mesh_extruder),
997 _quad_parent(quad_parent),
998 _slice(slice),
999 _name(name)
1000 {
1001 }
1002
1003 virtual Index get_num_entities(int dim) override
1004 {
1005 XASSERT(dim < 4);
1006 return (dim < 3) ? _quad_parent.get_num_entities(dim) : Index(0);
1007 }
1008
1009 virtual void fill_target_sets(TargetSetHolderType& target_set_holder) override
1010 {
1011 _mesh_extruder.extrude_slice_mapping(target_set_holder, _quad_parent, _slice);
1012 }
1013
1014 virtual void fill_index_sets(std::unique_ptr<IndexSetHolderType>& index_set_holder) override
1015 {
1016 index_set_holder.reset();
1017 }
1018
1019 virtual void fill_attribute_sets(AttributeSetContainer& /*attribute_set_holder*/) override
1020 {
1021 }
1022 }; // class MeshPartSliceExtruderFactory<ConformalMesh<Shape::Hypercube<2>,...>>
1023 } // namespace Geometry
1024} // namespace FEAT
#define XABORTM(msg)
Abortion macro definition with custom message.
Definition: assertion.hpp:192
#define XASSERT(expr)
Assertion macro definition.
Definition: assertion.hpp:262
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Definition: assertion.hpp:263
Adjacency Graph implementation.
Definition: graph.hpp:34
Index * get_domain_ptr()
Returns the domain pointer array.
Definition: graph.hpp:359
Index * get_image_idx()
Returns the image node index array.
Definition: graph.hpp:374
Index get_num_indices() const
Returns the total number indices.
Definition: graph.hpp:390
Bezier chart class template.
Definition: bezier.hpp:45
Circle chart class template.
Definition: circle.hpp:52
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.
Conformal mesh class template.
Index get_num_entities(int dim) const
Returns the number of entities.
IndexSetHolder< ShapeType > IndexSetHolderType
index set holder type
VertexSetType & get_vertex_set()
Returns a reference to the vertex set of the mesh.
Mesh Factory class template.
Definition: factory.hpp:33
Mesh Atlas class template.
Definition: mesh_atlas.hpp:32
MeshChartType * find_mesh_chart(const String &name)
Searches for a mesh chart.
Definition: mesh_atlas.hpp:162
std::deque< String > get_chart_names() const
Returns the names of all charts of this atlas.
Definition: mesh_atlas.hpp:131
bool add_mesh_chart(const String &name, std::unique_ptr< MeshChartType > chart, bool replace=false)
Inserts a new chart into the map.
Definition: mesh_atlas.hpp:109
MeshExtruder(const std::deque< CoordType > &z_list, String zmin_part_name, String zmax_part_name)
Creates the mesh extruder object.
std::unique_ptr< HexaChart > extrude_chart(const QuadChart &quad_chart) const
Extrudes and returns a quadrilateral mesh chart.
void extrude_topology(HexaTopology &hexa_topo, const QuadTopology &quad_topo) const
Extrudes a quadrilateral topology (aka "index set holder").
void extrude_partition_set(PartitionSet &hexa_part_set, const PartitionSet &quad_part_set) const
Extrudes a quadrilateral mesh partition set.
String _zmin_part_name
mesh-part names for z-min/max boundary regions
void set_angles(CoordType yaw, CoordType pitch, CoordType roll)
Sets the transformation angles.
void set_origin(CoordType x, CoordType y)
Sets the transformation origin.
void extrude_attribute(std::unique_ptr< HexaAttrib > &hexa_attrib, const QuadAttrib &quad_attrib) const
Extrudes a quadrilateral mesh attribute.
void set_offset(CoordType x, CoordType y, CoordType z)
Sets the transformation offset.
void extrude_num_entities(Index hexa_num_entities[], const Index quad_num_entities[]) const
Computes the extruded entity counts.
void extrude_vertex_set(HexaVertexSet &hexa_vtx, const QuadVertexSet &quad_vtx) const
Extrudes a quadrilateral vertex set.
void extrude_atlas(HexaAtlas &hexa_atlas, const QuadAtlas &quad_atlas) const
Extrudes an quadrilateral mesh atlas.
MeshExtruder(Index slices, CoordType z_min, CoordType z_max, String zmin_part_name, String zmax_part_name)
Creates the mesh extruder object.
void extrude_root_node(HexaRootNode &hexa_root_node, const QuadRootNode &quad_root_node, const HexaAtlas *hexa_atlas) const
Extrudes a quadrilateral root mesh node.
void extrude_mapping(HexaTrgSetHolder &hexa_mapp, const QuadTrgSetHolder &quad_mapp, const QuadMesh &quad_parent) const
Extrudes a quadrilateral mapping (aka "target set holder")
bool try_extrude_chart(std::unique_ptr< HexaChart > &hexa_chart, const QuadChart &quad_chart) const
Tries to extrudes a quadrilateral mesh chart.
void extrude_partition(Partition &hexa_parti, const Partition &quad_parti) const
Extrudes a quadrilateral mesh partitioning.
MeshExtruderFactory(const MeshExtruderType &mesh_extruder, const QuadMesh &quad_mesh)
Constructor.
MeshPartType * find_mesh_part(const String &part_name)
Searches this container for a MeshPart.
Definition: mesh_node.hpp:398
String find_mesh_part_chart_name(const String &part_name) const
Searches for a chart name belonging to a MeshPart by name.
Definition: mesh_node.hpp:437
std::deque< String > get_mesh_part_names(bool no_internals=false) const
Returns the names of all mesh parts of this node.
Definition: mesh_node.hpp:251
MeshType * get_mesh()
Returns the mesh of this node.
Definition: mesh_node.hpp:225
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.
Definition: mesh_node.hpp:316
MeshPartExtruderFactory(const MeshExtruderType &mesh_extruder, const QuadPart &quad_part, const QuadMesh &quad_parent)
Constructor.
Class template for partial meshes.
Definition: mesh_part.hpp:90
const AttributeSetContainer & get_mesh_attributes() const
Returns a const reference to the mesh attributes container.
Definition: mesh_part.hpp:346
bool has_topology() const
Checks if this MeshPart has a mesh topology.
Definition: mesh_part.hpp:297
TargetSetHolder< ShapeType > TargetSetHolderType
Target set holder type.
Definition: mesh_part.hpp:101
IndexSetHolder< ShapeType > IndexSetHolderType
Index set holder type.
Definition: mesh_part.hpp:99
Index get_num_entities(int dim) const
Returns the number of entities.
Definition: mesh_part.hpp:311
std::map< String, std::unique_ptr< AttributeSetType > > AttributeSetContainer
submesh node bin container type
Definition: mesh_part.hpp:138
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.
Definition: mesh_node.hpp:748
String class implementation.
Definition: string.hpp:46
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.
FEAT namespace.
Definition: adjactor.hpp:12
std::uint64_t Index
Index data type.
Fixed-Sized Vertex Set class template.
Definition: vertex_set.hpp:37
Index get_num_vertices() const
Returns the number of vertices in the vertex set.
Definition: vertex_set.hpp:157