FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
common_factories.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// includes, FEAT
9#include <kernel/geometry/mesh_part.hpp>
10#include <kernel/geometry/conformal_mesh.hpp>
11#include <kernel/geometry/structured_mesh.hpp>
12#include <kernel/geometry/shape_convert_factory.hpp>
13
14#include <deque>
15namespace FEAT
16{
17 namespace Geometry
18 {
27 template<typename Mesh_>
28 class UnitCubeFactory DOXY({});
29
31 template<typename Coord_>
32 class UnitCubeFactory< ConformalMesh<Shape::Hypercube<1>, 1, Coord_> > :
33 public Factory< ConformalMesh<Shape::Hypercube<1>, 1, Coord_> >
34 {
35 public:
37 typedef ConformalMesh<Shape::Hypercube<1>, 1, Coord_> MeshType;
39 typedef typename MeshType::VertexSetType VertexSetType;
41 typedef typename MeshType::IndexSetHolderType IndexSetHolderType;
42
43 public:
45 {
46 }
47
48 virtual Index get_num_entities(int dim) override
49 {
50 return Index(2 - dim);
51 }
52
53 virtual void fill_vertex_set(VertexSetType& vertex_set) override
54 {
55 vertex_set[0][0] = Coord_(0);
56 vertex_set[1][0] = Coord_(1);
57 }
58
59 virtual void fill_index_sets(IndexSetHolderType& index_set_holder) override
60 {
61 IndexSet<2>& v_e(index_set_holder.template get_index_set<1,0>());
62 v_e[0][0] = 0;
63 v_e[0][1] = 1;
64 }
65 }; // class UnitCubeFactory<ConformalMesh<Hypercube<1>,...>>
66
67 template<typename Coord_>
68 class UnitCubeFactory< ConformalMesh<Shape::Hypercube<2>, 2, Coord_> > :
69 public Factory< ConformalMesh<Shape::Hypercube<2>, 2, Coord_> >
70 {
71 public:
73 typedef Shape::Hypercube<2> ShapeType;
75 typedef ConformalMesh<Shape::Hypercube<2>, 2, Coord_> MeshType;
77 typedef typename MeshType::VertexSetType VertexSetType;
79 typedef typename MeshType::IndexSetHolderType IndexSetHolderType;
80
81 public:
82 UnitCubeFactory()
83 {
84 }
85
86 virtual Index get_num_entities(int dim) override
87 {
88 switch(dim)
89 {
90 case 0:
91 return 4u;
92 case 1:
93 return 4u;
94 case 2:
95 return 1u;
96 default:
97 return 0u;
98 }
99 }
100
101 virtual void fill_vertex_set(VertexSetType& vertex_set) override
102 {
103 for(Index i(0); i < 4u; ++i)
104 {
105 for(int j(0); j < 2; ++j)
106 {
107 vertex_set[i][j] = Coord_((i >> j) & 0x1);
108 }
109 }
110 }
111
112 virtual void fill_index_sets(IndexSetHolderType& index_set_holder) override
113 {
114 _fill_sub_index_set<1,0>(index_set_holder);
115 _fill_cell_index_set<0>(index_set_holder);
116 _fill_cell_index_set<1>(index_set_holder);
117 }
118
119 private:
120 template<int cell_dim_, int face_dim_>
121 static void _fill_sub_index_set(IndexSetHolderType& index_set_holder)
122 {
123 typedef typename Intern::FaceIndexMapping<ShapeType, cell_dim_, face_dim_> FimType;
124 typename IndexSetHolderType::template IndexSet<cell_dim_, face_dim_>::Type&
125 idx(index_set_holder.template get_index_set<cell_dim_, face_dim_>());
126
127 for(int i(0); i < Shape::FaceTraits<ShapeType, cell_dim_>::count; ++i)
128 {
129 for(int j(0); j < idx.num_indices; ++j)
130 {
131 idx[Index(i)][j] = Index(FimType::map(i, j));
132 }
133 }
134 }
135
136 template<int face_dim_>
137 static void _fill_cell_index_set(IndexSetHolderType& index_set_holder)
138 {
139 typename IndexSetHolderType::template IndexSet<2, face_dim_>::Type&
140 idx(index_set_holder.template get_index_set<2, face_dim_>());
141 for(int j(0); j < idx.num_indices; ++j)
142 {
143 idx[0][j] = Index(j);
144 }
145 }
146 }; // class UnitCubeFactory<ConformalMesh<Hypercube<2>,...>>
147
148 template<typename Coord_>
149 class UnitCubeFactory< ConformalMesh<Shape::Hypercube<3>, 3, Coord_> > :
150 public Factory< ConformalMesh<Shape::Hypercube<3>, 3, Coord_> >
151 {
152 public:
154 typedef Shape::Hypercube<3> ShapeType;
156 typedef ConformalMesh<Shape::Hypercube<3>, 3, Coord_> MeshType;
158 typedef typename MeshType::VertexSetType VertexSetType;
160 typedef typename MeshType::IndexSetHolderType IndexSetHolderType;
161
162 public:
163 UnitCubeFactory()
164 {
165 }
166
167 virtual Index get_num_entities(int dim) override
168 {
169 switch(dim)
170 {
171 case 0:
172 return 8u;
173 case 1:
174 return 12u;
175 case 2:
176 return 6u;
177 case 3:
178 return 1u;
179 default:
180 return 0u;
181 }
182 }
183
184 virtual void fill_vertex_set(VertexSetType& vertex_set) override
185 {
186 for(Index i(0); i < 8u; ++i)
187 {
188 for(int j(0); j < 3; ++j)
189 {
190 vertex_set[i][j] = Coord_((i >> j) & 0x1);
191 }
192 }
193 }
194
195 virtual void fill_index_sets(IndexSetHolderType& index_set_holder) override
196 {
197 _fill_sub_index_set<1,0>(index_set_holder);
198 _fill_sub_index_set<2,0>(index_set_holder);
199 _fill_sub_index_set<2,1>(index_set_holder);
200 _fill_cell_index_set<0>(index_set_holder);
201 _fill_cell_index_set<1>(index_set_holder);
202 _fill_cell_index_set<2>(index_set_holder);
203 }
204
205 private:
206 template<int cell_dim_, int face_dim_>
207 static void _fill_sub_index_set(IndexSetHolderType& index_set_holder)
208 {
209 typedef typename Intern::FaceIndexMapping<ShapeType, cell_dim_, face_dim_> FimType;
210 typename IndexSetHolderType::template IndexSet<cell_dim_, face_dim_>::Type&
211 idx(index_set_holder.template get_index_set<cell_dim_, face_dim_>());
212
213 for(int i(0); i < Shape::FaceTraits<ShapeType, cell_dim_>::count; ++i)
214 {
215 for(int j(0); j < idx.num_indices; ++j)
216 {
217 idx[Index(i)][j] = Index(FimType::map(i, j));
218 }
219 }
220 }
221
222 template<int face_dim_>
223 static void _fill_cell_index_set(IndexSetHolderType& index_set_holder)
224 {
225 typename IndexSetHolderType::template IndexSet<3, face_dim_>::Type&
226 idx(index_set_holder.template get_index_set<3, face_dim_>());
227 for(int j(0); j < idx.num_indices; ++j)
228 {
229 idx[Index(0)][j] = Index(j);
230 }
231 }
232 }; // class UnitCubeFactory<ConformalMesh<Hypercube<3>,...>>
233
234 template<>
235 class UnitCubeFactory< MeshPart<ConformalMesh<Shape::Hypercube<2> > > >:
236 public Factory< MeshPart<ConformalMesh<Shape::Hypercube<2> > > >
237 {
238 public:
239 typedef Shape::Hypercube<2> ShapeType;
241 typedef MeshPart<ConformalMesh<ShapeType>> MeshType;
243 typedef MeshType::TargetSetHolderType TargetSetHolderType;
244
245 public:
246 virtual Index get_num_entities(int dim) override
247 {
248 switch(dim)
249 {
250 case 0:
251 return 4;
252 case 1:
253 return 4;
254 default:
255 return 0;
256 }
257 }
258
259 virtual void fill_target_sets(TargetSetHolderType& target_set_holder) override
260 {
261 // set vertex indices
262 TargetSet& vi(target_set_holder.get_target_set<0>());
263 vi[0] = 0;
264 vi[1] = 1;
265 vi[2] = 2;
266 vi[3] = 3;
267
268 // set edge indices
269 TargetSet& ei(target_set_holder.get_target_set<1>());
270 ei[0] = 0;
271 ei[1] = 1;
272 ei[2] = 2;
273 ei[3] = 3;
274 }
275 }; //UnitCubeFactory< MeshPart<ConformalMesh<Shape::Hypercube<2> > > >
276
286 template<typename Coord_, int dim_>
287 class UnitCubeFactory< ConformalMesh<Shape::Simplex<dim_>, dim_, Coord_> > :
288 public Factory< ConformalMesh<Shape::Simplex<dim_>, dim_, Coord_> >
289 {
290 public:
292 typedef ConformalMesh<Shape::Simplex<dim_>, dim_, Coord_> MeshType;
294 typedef typename MeshType::VertexSetType VertexSetType;
296 typedef typename MeshType::IndexSetHolderType IndexSetHolderType;
297
298 private:
300 typedef ShapeConvertFactory<MeshType> FactoryType;
302 typedef ConformalMesh<Shape::Hypercube<dim_>, dim_, Coord_> GeneratorMeshType;
303
304 GeneratorMeshType* _generator_mesh;
305 FactoryType* _factory;
306
307 public:
308 UnitCubeFactory() :
309 _generator_mesh(nullptr),
310 _factory(nullptr)
311 {
312 UnitCubeFactory<GeneratorMeshType> cube_factory;
313 _generator_mesh = new GeneratorMeshType(cube_factory);
314 _factory = new FactoryType(*_generator_mesh);
315 }
316
317 virtual ~UnitCubeFactory()
318 {
319 delete _generator_mesh;
320 delete _factory;
321 }
322
323 virtual Index get_num_entities(int dim) override
324 {
325 return _factory->get_num_entities(dim);
326 }
327
328 virtual void fill_vertex_set(VertexSetType& vertex_set) override
329 {
330 _factory->fill_vertex_set(vertex_set);
331 }
332
333 virtual void fill_index_sets(IndexSetHolderType& index_set_holder) override
334 {
335 _factory->fill_index_sets(index_set_holder);
336 }
337 }; // class UnitCubeFactory<ConformalMesh<Simplex<dim_>,...>>
338
339 template<int dim_, typename Coord_>
340 class UnitCubeFactory< StructuredMesh<dim_, dim_, Coord_> > :
341 public Factory< StructuredMesh<dim_, dim_, Coord_> >
342 {
343 public:
345 typedef Shape::Hypercube<dim_> ShapeType;
347 typedef StructuredMesh<dim_, dim_, Coord_> MeshType;
349 typedef typename MeshType::VertexSetType VertexSetType;
350
351 protected:
352 const Index _level;
353
354 public:
355 explicit UnitCubeFactory(Index level = Index(0)) :
356 _level(level)
357 {
358 }
359
360 virtual Index get_num_slices(int DOXY(dir)) override
361 {
362 return (Index(1) << _level); // = 2^level in each direction
363 }
364
365 virtual void fill_vertex_set(VertexSetType& vertex_set) override
366 {
367 // coordinate scaling factor
368 const Coord_ sc = Coord_(1) / Coord_(Index(1) << _level); // = 2^{-level}
369
370 // number of vertices in each direction
371 const Index nx = (Index(1) << _level) + Index(1); // = 2^level + 1
372
373 // total number of vertices = nx ^ dim
374 const Index nv = vertex_set.get_num_vertices();
375
376 for(Index i(0); i < nv; ++i)
377 {
378 Index k = i;
379 auto& v = vertex_set[i];
380 for(int j(0); j < dim_; ++j, k /= nx)
381 {
382 v[j] = Coord_(k % nx) * sc;
383 }
384 }
385 }
386 };
388
402 template<typename Mesh_, template<typename> class Factory_>
403 class RefineFactory DOXY({});
404
406 template<typename Shape_, int num_coords_, typename Coord_, template<typename> class Factory_>
407 class RefineFactory< ConformalMesh<Shape_, num_coords_, Coord_>, Factory_ > :
408 public Factory< ConformalMesh<Shape_, num_coords_, Coord_> >
409 {
410 public:
412 typedef typename MeshType::VertexSetType VertexSetType;
413 typedef typename MeshType::IndexSetHolderType IndexSetHolderType;
414
415 private:
416 typedef Factory<MeshType> MeshFactory;
417 typedef Factory_<MeshType> MyFactoryType;
418 typedef StandardRefinery<MeshType> Refinery;
419
420 MeshType* _coarse_mesh;
421 MeshFactory* _factory;
422
423 public:
424 template<typename... Arguments>
425 explicit RefineFactory(Index num_refines, Arguments&&... args) :
426 _coarse_mesh(nullptr),
427 _factory(nullptr)
428 {
429 if(num_refines <= 0)
430 {
431 _factory = new MyFactoryType(std::forward<Arguments>(args)...);
432 return;
433 }
434
435 // create coarse mesh
436 MyFactoryType my_factory(std::forward<Arguments>(args)...);
437 _coarse_mesh = new MeshType(my_factory);
438
439 // create refinery
440 _factory = new Refinery(*_coarse_mesh);
441
442 // refine n-1 times;
443 for(Index i(1); i < num_refines; ++i)
444 {
445 // backup old mesh
446 MeshType* mesh_old = _coarse_mesh;
447 // refine mesh
448 _coarse_mesh = new MeshType(*_factory);
449 // delete old factory
450 delete _factory;
451 // delete old coarse mesh
452 delete mesh_old;
453 // create new factory
454 _factory = new Refinery(*_coarse_mesh);
455 }
456 }
457
458 virtual ~RefineFactory()
459 {
460 if(_factory != nullptr)
461 {
462 delete _factory;
463 }
464 if(_coarse_mesh != nullptr)
465 {
466 delete _coarse_mesh;
467 }
468 }
469
470 virtual Index get_num_entities(int dim) override
471 {
472 return _factory->get_num_entities(dim);
473 }
474
475 virtual void fill_vertex_set(VertexSetType& vertex_set) override
476 {
477 _factory->fill_vertex_set(vertex_set);
478 }
479
480 virtual void fill_index_sets(IndexSetHolderType& index_set_holder) override
481 {
482 _factory->fill_index_sets(index_set_holder);
483 }
484 }; // class RefineFactory<ConformalMesh<...>, ...>
485
486 template<int shape_dim_, int num_coords_, typename Coord_, template<typename> class Factory_>
487 class RefineFactory< StructuredMesh<shape_dim_, num_coords_, Coord_>, Factory_ > :
488 public Factory< StructuredMesh<shape_dim_, num_coords_, Coord_> >
489 {
490 public:
491 typedef StructuredMesh<shape_dim_, num_coords_, Coord_> MeshType;
492 typedef typename MeshType::VertexSetType VertexSetType;
493
494 private:
495 typedef Factory<MeshType> MeshFactory;
496 typedef Factory_<MeshType> MyFactoryType;
497 typedef StandardRefinery<MeshType> Refinery;
498
499 MeshType* _coarse_mesh;
500 MeshFactory* _factory;
501
502 public:
503 template<typename... Arguments>
504 explicit RefineFactory(Index num_refines, Arguments&&... args) :
505 _coarse_mesh(nullptr),
506 _factory(nullptr)
507 {
508 if(num_refines <= 0)
509 {
510 _factory = new MyFactoryType(std::forward<Arguments>(args)...);
511 return;
512 }
513
514 // create coarse mesh
515 MyFactoryType my_factory(std::forward<Arguments>(args)...);
516 _coarse_mesh = new MeshType(my_factory);
517
518 // create refinery
519 _factory = new Refinery(*_coarse_mesh);
520
521 // refine n-1 times;
522 for(Index i(1); i < num_refines; ++i)
523 {
524 // backup old mesh
525 MeshType* mesh_old = _coarse_mesh;
526 // refine mesh
527 _coarse_mesh = new MeshType(*_factory);
528 // delete old factory
529 delete _factory;
530 // delete old coarse mesh
531 delete mesh_old;
532 // create new factory
533 _factory = new Refinery(*_coarse_mesh);
534 }
535 }
536
537 virtual ~RefineFactory()
538 {
539 if(_factory != nullptr)
540 {
541 delete _factory;
542 }
543 if(_coarse_mesh != nullptr)
544 {
545 delete _coarse_mesh;
546 }
547 }
548
549 virtual void fill_vertex_set(VertexSetType& vertex_set) override
550 {
551 _factory->fill_vertex_set(vertex_set);
552 }
553
554 virtual Index get_num_slices(int dir) override
555 {
556 return _factory->get_num_slices(dir);
557 }
558 }; // class RefineFactory<StructuredMesh<...>, ...>
560
561 template<typename MeshType_>
562 using RefinedUnitCubeFactory = RefineFactory<MeshType_, Geometry::UnitCubeFactory >;
563
574 template<typename Mesh_>
576
579 template<int shape_dim_, typename Coord_>
580 class StructUnitCubeFactory<ConformalMesh<Shape::Hypercube<shape_dim_>, shape_dim_, Coord_>> :
581 public Factory<ConformalMesh<Shape::Hypercube<shape_dim_>, shape_dim_, Coord_>>
582 {
583 public:
584 typedef ConformalMesh<Shape::Hypercube<shape_dim_>, shape_dim_, Coord_> MeshType;
585 typedef Factory<MeshType> BaseClass;
586
587 typedef typename BaseClass::VertexSetType VertexSetType;
588 typedef typename BaseClass::IndexSetHolderType IndexSetHolderType;
589
590 static_assert(shape_dim_ <= 3, "this class can only be used for dimension <= 3");
591
592 private:
593 Index _num_slices[3];
594 Index _num_entities[4];
595 std::unique_ptr<StructIndexSetHolder<shape_dim_>> _sish;
596
597 public:
598 explicit StructUnitCubeFactory(Index nx = 1u, Index ny = 1u, Index nz = 1u) :
599 _sish()
600 {
601 _num_slices[0] = nx;
602 _num_slices[1] = (shape_dim_ >= 2 ? ny : Index(0));
603 _num_slices[2] = (shape_dim_ >= 3 ? nz : Index(0));
604
605 // create structured index set
606 _sish.reset(new StructIndexSetHolder<shape_dim_>(_num_slices));
607
608 // get entity counts
609 _num_entities[0] = _sish-> template get_index_set<shape_dim_, 0>().get_index_bound();
610 if constexpr (shape_dim_ >= 2)
611 _num_entities[1] = _sish-> template get_index_set<shape_dim_, 1>().get_index_bound();
612 if constexpr (shape_dim_ >= 3)
613 _num_entities[2] = _sish-> template get_index_set<shape_dim_, 2>().get_index_bound();
614 _num_entities[shape_dim_] = _sish-> template get_index_set<shape_dim_, 0>().get_num_entities();
615 }
616
617 virtual Index get_num_entities(int dim) override
618 {
619 return _num_entities[dim];
620 }
621
622 virtual void fill_vertex_set(VertexSetType& vertex_set) override
623 {
624 const Coord_ fx = (_num_slices[0] > 0u ? Coord_(1) / Coord_(_num_slices[0]) : Coord_(0));
625 const Coord_ fy = (_num_slices[1] > 0u ? Coord_(1) / Coord_(_num_slices[1]) : Coord_(0));
626 const Coord_ fz = (_num_slices[2] > 0u ? Coord_(1) / Coord_(_num_slices[2]) : Coord_(0));
627 for(Index i(0u); i <= _num_slices[2]; ++i)
628 {
629 for(Index j(0u); j <= _num_slices[1]; ++j)
630 {
631 for(Index k(0u); k <= _num_slices[0]; ++k)
632 {
633 auto& v =vertex_set[k + (_num_slices[0]+1u) * (j + (_num_slices[1]+1u)*i)];
634 v[0] = Coord_(k) * fx;
635 if constexpr(shape_dim_ >= 2) v[1] = Coord_(j) * fy;
636 if constexpr(shape_dim_ >= 3) v[2] = Coord_(i) * fz;
637 }
638 }
639 }
640 // silence unused variable warnings in 1D and 2D
641 (void)fy;
642 (void)fz;
643 }
644
645 virtual void fill_index_sets(IndexSetHolderType& index_set_holder) override
646 {
647 // copy structured index sets
648 _sish->copy_to(index_set_holder);
649 }
650
651 static MeshType make_from(Index nx = 1u, Index ny = 1u, Index nz = 1u)
652 {
653 StructUnitCubeFactory factory(nx, ny, nz);
654 return MeshType(factory);
655 }
656
657 static std::unique_ptr<MeshType> make_unique_from(Index nx = 1u, Index ny = 1u, Index nz = 1u)
658 {
659 StructUnitCubeFactory factory(nx, ny, nz);
660 return std::unique_ptr<MeshType>(new MeshType(factory));
661 }
662 }; // StructUnitCubeFactory<ConformalMesh<Hypercube>>
663
665 template<int shape_dim_, typename Coord_>
666 class StructUnitCubeFactory<ConformalMesh<Shape::Simplex<shape_dim_>, shape_dim_, Coord_>> :
667 public Factory<ConformalMesh<Shape::Simplex<shape_dim_>, shape_dim_, Coord_>>
668 {
669 public:
670 typedef ConformalMesh<Shape::Simplex<shape_dim_>, shape_dim_, Coord_> MeshType;
671 typedef ConformalMesh<Shape::Hypercube<shape_dim_>, shape_dim_, Coord_> QuadMeshType;
672 typedef Factory<MeshType> BaseClass;
673
674 typedef typename BaseClass::VertexSetType VertexSetType;
675 typedef typename BaseClass::IndexSetHolderType IndexSetHolderType;
676
677 static_assert(shape_dim_ <= 3, "this class can only be used for dimension <= 3");
678
679 private:
680 std::unique_ptr<QuadMeshType> _quad_mesh;
681 std::unique_ptr<ShapeConvertFactory<MeshType>> _shape_convert_factory;
682
683 public:
684 explicit StructUnitCubeFactory(Index nx = 1u, Index ny = 1u, Index nz = 1u)
685 {
686 // create a structured quad mesh
687 StructUnitCubeFactory<QuadMeshType> quad_factory(nx, ny, nz);
688 this->_quad_mesh.reset(new QuadMeshType(quad_factory));
689
690 // create shape convert factory
691 this->_shape_convert_factory.reset(new ShapeConvertFactory<MeshType>(*this->_quad_mesh));
692 }
693
694 virtual Index get_num_entities(int dim) override
695 {
696 return this->_shape_convert_factory->get_num_entities(dim);
697 }
698
699 virtual void fill_vertex_set(VertexSetType& vertex_set) override
700 {
701 this->_shape_convert_factory->fill_vertex_set(vertex_set);
702 }
703
704 virtual void fill_index_sets(IndexSetHolderType& index_set_holder) override
705 {
706 this->_shape_convert_factory->fill_index_sets(index_set_holder);
707 }
708
709 static MeshType make_from(Index nx = 1u, Index ny = 1u, Index nz = 1u)
710 {
711 StructUnitCubeFactory factory(nx, ny, nz);
712 return MeshType(factory);
713 }
714
715 static std::unique_ptr<MeshType> make_unique_from(Index nx = 1u, Index ny = 1u, Index nz = 1u)
716 {
717 StructUnitCubeFactory factory(nx, ny, nz);
718 return std::unique_ptr<MeshType>(new MeshType(factory));
719 }
720 }; // StructUnitCubeFactory<ConformalMesh<Simplex>>
721
723 template<int shape_dim_, typename Coord_>
724 class StructUnitCubeFactory<StructuredMesh<shape_dim_, shape_dim_, Coord_>> :
725 public Factory<StructuredMesh<shape_dim_, shape_dim_, Coord_>>
726 {
727 public:
728 typedef StructuredMesh<shape_dim_, shape_dim_, Coord_> MeshType;
729 typedef Factory<MeshType> BaseClass;
730
731 typedef typename BaseClass::VertexSetType VertexSetType;
732
733 static_assert(shape_dim_ <= 3, "this class can only be used for dimension <= 3");
734
735 private:
736 Index _num_slices[3];
737
738 public:
739 explicit StructUnitCubeFactory(Index nx = 1u, Index ny = 1u, Index nz = 1u)
740 {
741 _num_slices[0] = nx;
742 _num_slices[1] = (shape_dim_ >= 2 ? ny : Index(0));
743 _num_slices[2] = (shape_dim_ >= 3 ? nz : Index(0));
744 }
745
746 virtual Index get_num_slices(int dir) override
747 {
748 XASSERT((dir >= 0) && (dir <= shape_dim_));
749 return _num_slices[dir];
750 }
751
752 virtual void fill_vertex_set(VertexSetType& vertex_set) override
753 {
754 const Coord_ fx = (_num_slices[0] > 0u ? Coord_(1) / Coord_(_num_slices[0]) : Coord_(0));
755 const Coord_ fy = (_num_slices[1] > 0u ? Coord_(1) / Coord_(_num_slices[1]) : Coord_(0));
756 const Coord_ fz = (_num_slices[2] > 0u ? Coord_(1) / Coord_(_num_slices[2]) : Coord_(0));
757 for(Index i(0u); i <= _num_slices[2]; ++i)
758 {
759 for(Index j(0u); j <= _num_slices[1]; ++j)
760 {
761 for(Index k(0u); k <= _num_slices[0]; ++k)
762 {
763 auto& v =vertex_set[k + (_num_slices[0]+1u) * (j + (_num_slices[1]+1u)*i)];
764 v[0] = Coord_(k) * fx;
765 if constexpr(shape_dim_ >= 2) v[1] = Coord_(j) * fy;
766 if constexpr(shape_dim_ >= 3) v[2] = Coord_(i) * fz;
767 }
768 }
769 }
770 // silence unused variable warnings in 1D and 2D
771 (void)fy;
772 (void)fz;
773 }
774
775 static MeshType make_from(Index nx = 1u, Index ny = 1u, Index nz = 1u)
776 {
777 StructUnitCubeFactory factory(nx, ny, nz);
778 return MeshType(factory);
779 }
780
781 static std::unique_ptr<MeshType> make_unique_from(Index nx = 1u, Index ny = 1u, Index nz = 1u)
782 {
783 StructUnitCubeFactory factory(nx, ny, nz);
784 return std::unique_ptr<MeshType>(new MeshType(factory));
785 }
786 }; // StructUnitCubeFactory<StructuredMesh>
788
828 template<typename Mesh_>
829 class UnitStarCubeFactory DOXY({});
830
832 /*
833 * \brief Specialization for Hypercube<2> meshes
834 */
835 template<typename Coord_>
836 class UnitStarCubeFactory< ConformalMesh<Shape::Hypercube<2>, 2, Coord_> > :
837 public Factory< ConformalMesh<Shape::Hypercube<2>, 2, Coord_> >
838 {
839 public:
841 typedef Shape::Hypercube<2> ShapeType;
843 typedef ConformalMesh<Shape::Hypercube<2>, 2, Coord_> MeshType;
845 typedef typename MeshType::VertexSetType VertexSetType;
847 typedef typename MeshType::IndexSetHolderType IndexSetHolderType;
848
849 public:
851 {
852 }
853
854 virtual Index get_num_entities(int dim) override
855 {
856 switch(dim)
857 {
858 case 0:
859 return 8u;
860 case 1:
861 return 12u;
862 case 2:
863 return 5u;
864 default:
865 return 0u;
866 }
867 }
868
869 virtual void fill_vertex_set(VertexSetType& vertex_set) override
870 {
871 vertex_set[0][0] = Coord_(0);
872 vertex_set[0][1] = Coord_(0);
873
874 vertex_set[1][0] = Coord_(1);
875 vertex_set[1][1] = Coord_(0);
876
877 vertex_set[2][0] = Coord_(0);
878 vertex_set[2][1] = Coord_(1);
879
880 vertex_set[3][0] = Coord_(1);
881 vertex_set[3][1] = Coord_(1);
882
883 vertex_set[4][0] = Coord_(0.25);
884 vertex_set[4][1] = Coord_(0.25);
885
886 vertex_set[5][0] = Coord_(0.75);
887 vertex_set[5][1] = Coord_(0.25);
888
889 vertex_set[6][0] = Coord_(0.25);
890 vertex_set[6][1] = Coord_(0.75);
891
892 vertex_set[7][0] = Coord_(0.75);
893 vertex_set[7][1] = Coord_(0.75);
894
895 }
896
897 virtual void fill_index_sets(IndexSetHolderType& index_set_holder) override
898 {
899 IndexSet<4>& v_q = index_set_holder.template get_index_set<2,0>();
900
901 v_q(0,0) = Index(0);
902 v_q(0,1) = Index(1);
903 v_q(0,2) = Index(4);
904 v_q(0,3) = Index(5);
905
906 v_q(1,0) = Index(5);
907 v_q(1,1) = Index(1);
908 v_q(1,2) = Index(7);
909 v_q(1,3) = Index(3);
910
911 v_q(2,0) = Index(6);
912 v_q(2,1) = Index(7);
913 v_q(2,2) = Index(2);
914 v_q(2,3) = Index(3);
915
916 v_q(3,0) = Index(0);
917 v_q(3,1) = Index(4);
918 v_q(3,2) = Index(2);
919 v_q(3,3) = Index(6);
920
921 v_q(4,0) = Index(4);
922 v_q(4,1) = Index(5);
923 v_q(4,2) = Index(6);
924 v_q(4,3) = Index(7);
925
926 IndexSet<4>& e_q = index_set_holder.template get_index_set<2,1>();
927
928 e_q(0,0) = Index(0);
929 e_q(0,1) = Index(4);
930 e_q(0,2) = Index(8);
931 e_q(0,3) = Index(9);
932
933 e_q(1,0) = Index(9);
934 e_q(1,1) = Index(10);
935 e_q(1,2) = Index(7);
936 e_q(1,3) = Index(3);
937
938 e_q(2,0) = Index(5);
939 e_q(2,1) = Index(1);
940 e_q(2,2) = Index(11);
941 e_q(2,3) = Index(10);
942
943 e_q(3,0) = Index(8);
944 e_q(3,1) = Index(11);
945 e_q(3,2) = Index(2);
946 e_q(3,3) = Index(6);
947
948 e_q(4,0) = Index(4);
949 e_q(4,1) = Index(5);
950 e_q(4,2) = Index(6);
951 e_q(4,3) = Index(7);
952
953 IndexSet<2>& v_e = index_set_holder.template get_index_set<1,0>();
954
955 v_e(0,0) = Index(0);
956 v_e(0,1) = Index(1);
957
958 v_e(1,0) = Index(2);
959 v_e(1,1) = Index(3);
960
961 v_e(2,0) = Index(0);
962 v_e(2,1) = Index(2);
963
964 v_e(3,0) = Index(1);
965 v_e(3,1) = Index(3);
966
967 v_e(4,0) = Index(4);
968 v_e(4,1) = Index(5);
969
970 v_e(5,0) = Index(6);
971 v_e(5,1) = Index(7);
972
973 v_e(6,0) = Index(4);
974 v_e(6,1) = Index(6);
975
976 v_e(7,0) = Index(5);
977 v_e(7,1) = Index(7);
978
979 v_e(8,0) = Index(0);
980 v_e(8,1) = Index(4);
981
982 v_e(9,0) = Index(1);
983 v_e(9,1) = Index(5);
984
985 v_e(10,0) = Index(7);
986 v_e(10,1) = Index(3);
987
988 v_e(11,0) = Index(6);
989 v_e(11,1) = Index(2);
990 }
991 }; // class UnitStarCubeFactory<ConformalMesh<...>>
993
995 /*
996 * \brief Specialization for simplical meshes
997 *
998 * This uses the UnitStarCubeFactory for Hypercubes and then the ShapeConvertFactory.
999 *
1000 */
1001 template<typename Coord_, int dim_>
1002 class UnitStarCubeFactory< ConformalMesh<Shape::Simplex<dim_>, dim_, Coord_> > :
1003 public Factory< ConformalMesh<Shape::Simplex<dim_>, dim_, Coord_> >
1004 {
1005 public:
1007 typedef Shape::Simplex<dim_> ShapeType;
1009 typedef ConformalMesh<Shape::Simplex<dim_>, dim_, Coord_> MeshType;
1011 typedef typename MeshType::VertexSetType VertexSetType;
1013 typedef typename MeshType::IndexSetHolderType IndexSetHolderType;
1015 typedef ShapeConvertFactory<MeshType> FactoryType;
1017 typedef ConformalMesh<Shape::Hypercube<dim_>, dim_, Coord_> GeneratorMeshType;
1018
1019 private:
1020 GeneratorMeshType* _generator_mesh;
1021 FactoryType* _factory;
1022
1023 public:
1024 UnitStarCubeFactory() :
1025 _generator_mesh(nullptr),
1026 _factory(nullptr)
1027 {
1028 UnitStarCubeFactory<GeneratorMeshType> cube_factory;
1029 _generator_mesh = new GeneratorMeshType(cube_factory);
1030 _factory = new FactoryType(*_generator_mesh);
1031 }
1032
1033 virtual ~UnitStarCubeFactory()
1034 {
1035 delete _generator_mesh;
1036 delete _factory;
1037 }
1038
1039 virtual Index get_num_entities(int dim) override
1040 {
1041 return _factory->get_num_entities(dim);
1042 }
1043
1044 virtual void fill_vertex_set(VertexSetType& vertex_set) override
1045 {
1046 _factory->fill_vertex_set(vertex_set);
1047 }
1048
1049 virtual void fill_index_sets(IndexSetHolderType& index_set_holder) override
1050 {
1051 _factory->fill_index_sets(index_set_holder);
1052 }
1053 }; // class UnitStarCubeFactory<ConformalMesh<Simplex<dim_>, ...>>
1055
1069 template<int dim_, typename Coord_>
1071 public Factory< ConformalMesh<Shape::Hypercube<1>, dim_, Coord_> >
1072 {
1073 public:
1080
1081 private:
1083 std::deque<Tiny::Vector<Coord_, dim_>>& _points;
1084
1085 public:
1086
1090 explicit PolylineFactory(std::deque<typename VertexSetType::VertexType>& points_) :
1091 _points(points_)
1092 {
1093 XASSERTM(!points_.empty(), "PolylineFactory constructor called on empty point set!");
1094
1095 }
1096
1100 virtual Index get_num_entities(int dimension) override
1101 {
1102 switch(dimension)
1103 {
1104 case 0:
1105 return Index(_points.size());
1106 case 1:
1107 return Index(_points.size())-Index(1);
1108 default:
1109 return 0;
1110 }
1111 }
1112
1116 virtual void fill_vertex_set(VertexSetType& vertex_set) override
1117 {
1118 Index i(0);
1119 const auto& jt(_points.end());
1120 for(auto it(_points.begin()); it != jt; ++i)
1121 {
1122 vertex_set[i] = *it;
1123 it++;
1124 }
1125 }
1126
1130 virtual void fill_index_sets(IndexSetHolderType& index_set_holder) override
1131 {
1132 IndexSet<2>& v_e(index_set_holder.template get_index_set<1,0>());
1133 for(Index i(0); i < get_num_entities(1); ++i)
1134 {
1135 v_e[i][0] = i;
1136 v_e[i][1] = i + Index(1);
1137 }
1138 }
1139 };
1140
1141 template<typename Mesh_>
1142 class UnitSphereFactory DOXY({});
1143
1145
1146 template<typename Coord_>
1147 class UnitSphereFactory< ConformalMesh<Shape::Simplex<2>, 3, Coord_> > :
1148 public Factory< ConformalMesh<Shape::Simplex<2>, 3, Coord_> >
1149 {
1150 public:
1152 typedef Shape::Simplex<2> ShapeType;
1154 typedef ConformalMesh<Shape::Simplex<2>, 3, Coord_> MeshType;
1156 typedef typename MeshType::VertexSetType VertexSetType;
1158 typedef typename MeshType::IndexSetHolderType IndexSetHolderType;
1159
1160 public:
1162 {
1163 }
1164
1165 virtual Index get_num_entities(int dim) override
1166 {
1167 switch(dim)
1168 {
1169 case 0:
1170 return 12u;
1171 case 1:
1172 return 30u;
1173 case 2:
1174 return 20u;
1175 default:
1176 return 0u;
1177 }
1178 }
1179
1180 virtual void fill_vertex_set(VertexSetType& vertex_set) override
1181 {
1182 const Coord_ s5 = Math::sqrt(Coord_(5));
1183 const Coord_ va = Coord_(0);
1184 const Coord_ vb = Math::sqrt(Coord_(2) / (Coord_(5) + s5));
1185 const Coord_ vc = (s5 + Coord_(1)) / Math::sqrt(Coord_(10) + Coord_(2)*s5);
1186 vertex_set[ 0][0] = va;
1187 vertex_set[ 0][1] = -vb;
1188 vertex_set[ 0][2] = vc;
1189 vertex_set[ 1][0] = vc;
1190 vertex_set[ 1][1] = va;
1191 vertex_set[ 1][2] = vb;
1192 vertex_set[ 2][0] = vc;
1193 vertex_set[ 2][1] = va;
1194 vertex_set[ 2][2] = -vb;
1195 vertex_set[ 3][0] = -vc;
1196 vertex_set[ 3][1] = va;
1197 vertex_set[ 3][2] = -vb;
1198 vertex_set[ 4][0] = -vc;
1199 vertex_set[ 4][1] = va;
1200 vertex_set[ 4][2] = vb;
1201 vertex_set[ 5][0] = -vb;
1202 vertex_set[ 5][1] = vc;
1203 vertex_set[ 5][2] = va;
1204 vertex_set[ 6][0] = vb;
1205 vertex_set[ 6][1] = vc;
1206 vertex_set[ 6][2] = va;
1207 vertex_set[ 7][0] = vb;
1208 vertex_set[ 7][1] = -vc;
1209 vertex_set[ 7][2] = va;
1210 vertex_set[ 8][0] = -vb;
1211 vertex_set[ 8][1] = -vc;
1212 vertex_set[ 8][2] = va;
1213 vertex_set[ 9][0] = va;
1214 vertex_set[ 9][1] = -vb;
1215 vertex_set[ 9][2] = -vc;
1216 vertex_set[10][0] = va;
1217 vertex_set[10][1] = vb;
1218 vertex_set[10][2] = -vc;
1219 vertex_set[11][0] = va;
1220 vertex_set[11][1] = vb;
1221 vertex_set[11][2] = vc;
1222 }
1223
1224 virtual void fill_index_sets(IndexSetHolderType& index_set_holder) override
1225 {
1226 // vertices-at-edge
1227 auto& ve = index_set_holder.template get_index_set<1,0>();
1228 ve[ 0][0] = 1;
1229 ve[ 0][1] = 2;
1230 ve[ 1][0] = 2;
1231 ve[ 1][1] = 6;
1232 ve[ 2][0] = 1;
1233 ve[ 2][1] = 6;
1234 ve[ 3][0] = 1;
1235 ve[ 3][1] = 7;
1236 ve[ 4][0] = 2;
1237 ve[ 4][1] = 7;
1238 ve[ 5][0] = 3;
1239 ve[ 5][1] = 4;
1240 ve[ 6][0] = 4;
1241 ve[ 6][1] = 5;
1242 ve[ 7][0] = 3;
1243 ve[ 7][1] = 5;
1244 ve[ 8][0] = 3;
1245 ve[ 8][1] = 8;
1246 ve[ 9][0] = 4;
1247 ve[ 9][1] = 8;
1248 ve[10][0] = 5;
1249 ve[10][1] = 6;
1250 ve[11][0] = 5;
1251 ve[11][1] = 11;
1252 ve[12][0] = 6;
1253 ve[12][1] = 11;
1254 ve[13][0] = 6;
1255 ve[13][1] = 10;
1256 ve[14][0] = 5;
1257 ve[14][1] = 10;
1258 ve[15][0] = 9;
1259 ve[15][1] = 10;
1260 ve[16][0] = 2;
1261 ve[16][1] = 10;
1262 ve[17][0] = 2;
1263 ve[17][1] = 9;
1264 ve[18][0] = 3;
1265 ve[18][1] = 9;
1266 ve[19][0] = 3;
1267 ve[19][1] = 10;
1268 ve[20][0] = 7;
1269 ve[20][1] = 8;
1270 ve[21][0] = 8;
1271 ve[21][1] = 9;
1272 ve[22][0] = 7;
1273 ve[22][1] = 9;
1274 ve[23][0] = 0;
1275 ve[23][1] = 7;
1276 ve[24][0] = 0;
1277 ve[24][1] = 8;
1278 ve[25][0] = 0;
1279 ve[25][1] = 11;
1280 ve[26][0] = 0;
1281 ve[26][1] = 1;
1282 ve[27][0] = 1;
1283 ve[27][1] = 11;
1284 ve[28][0] = 4;
1285 ve[28][1] = 11;
1286 ve[29][0] = 0;
1287 ve[29][1] = 4;
1288
1289 // vertices-at-face
1290 auto& vf = index_set_holder.template get_index_set<2,0>();
1291 vf[ 0][0] = 1;
1292 vf[ 0][1] = 2;
1293 vf[ 0][2] = 6;
1294 vf[ 1][0] = 1;
1295 vf[ 1][1] = 7;
1296 vf[ 1][2] = 2;
1297 vf[ 2][0] = 3;
1298 vf[ 2][1] = 4;
1299 vf[ 2][2] = 5;
1300 vf[ 3][0] = 4;
1301 vf[ 3][1] = 3;
1302 vf[ 3][2] = 8;
1303 vf[ 4][0] = 6;
1304 vf[ 4][1] = 5;
1305 vf[ 4][2] = 11;
1306 vf[ 5][0] = 5;
1307 vf[ 5][1] = 6;
1308 vf[ 5][2] = 10;
1309 vf[ 6][0] = 9;
1310 vf[ 6][1] = 10;
1311 vf[ 6][2] = 2;
1312 vf[ 7][0] = 10;
1313 vf[ 7][1] = 9;
1314 vf[ 7][2] = 3;
1315 vf[ 8][0] = 7;
1316 vf[ 8][1] = 8;
1317 vf[ 8][2] = 9;
1318 vf[ 9][0] = 8;
1319 vf[ 9][1] = 7;
1320 vf[ 9][2] = 0;
1321 vf[10][0] = 11;
1322 vf[10][1] = 0;
1323 vf[10][2] = 1;
1324 vf[11][0] = 0;
1325 vf[11][1] = 11;
1326 vf[11][2] = 4;
1327 vf[12][0] = 6;
1328 vf[12][1] = 2;
1329 vf[12][2] = 10;
1330 vf[13][0] = 1;
1331 vf[13][1] = 6;
1332 vf[13][2] = 11;
1333 vf[14][0] = 3;
1334 vf[14][1] = 5;
1335 vf[14][2] = 10;
1336 vf[15][0] = 5;
1337 vf[15][1] = 4;
1338 vf[15][2] = 11;
1339 vf[16][0] = 2;
1340 vf[16][1] = 7;
1341 vf[16][2] = 9;
1342 vf[17][0] = 7;
1343 vf[17][1] = 1;
1344 vf[17][2] = 0;
1345 vf[18][0] = 3;
1346 vf[18][1] = 9;
1347 vf[18][2] = 8;
1348 vf[19][0] = 4;
1349 vf[19][1] = 8;
1350 vf[19][2] = 0;
1351
1353 }
1354 }; // class UnitSphereFactory<ConformalMesh<Shape::Simplex<2>, ...>>
1355
1356 template<typename Coord_>
1357 class UnitSphereFactory< ConformalMesh<Shape::Hypercube<2>, 3, Coord_> > :
1358 public Factory< ConformalMesh<Shape::Hypercube<2>, 3, Coord_> >
1359 {
1360 public:
1362 typedef Shape::Hypercube<2> ShapeType;
1364 typedef ConformalMesh<Shape::Hypercube<2>, 3, Coord_> MeshType;
1366 typedef typename MeshType::VertexSetType VertexSetType;
1368 typedef typename MeshType::IndexSetHolderType IndexSetHolderType;
1369
1370 public:
1371 UnitSphereFactory()
1372 {
1373 }
1374
1375 virtual Index get_num_entities(int dim) override
1376 {
1377 switch(dim)
1378 {
1379 case 0:
1380 return 8u;
1381 case 1:
1382 return 12u;
1383 case 2:
1384 return 6u;
1385 default:
1386 return 0u;
1387 }
1388 }
1389
1390 virtual void fill_vertex_set(VertexSetType& vertex_set) override
1391 {
1392 const Coord_ scale = Coord_(2) / Math::sqrt(Coord_(3));
1393 for(Index i(0); i < 8u; ++i)
1394 {
1395 for(int j(0); j < 3; ++j)
1396 {
1397 vertex_set[i][j] = scale * (Coord_((i >> j) & 0x1) - Coord_(0.5));
1398 }
1399 }
1400 }
1401
1402 virtual void fill_index_sets(IndexSetHolderType& index_set_holder) override
1403 {
1404 _fill_index_set<1,0>(index_set_holder);
1405 _fill_index_set<2,0>(index_set_holder);
1406 _fill_index_set<2,1>(index_set_holder);
1407 }
1408
1409 private:
1410 template<int cell_dim_, int face_dim_>
1411 static void _fill_index_set(IndexSetHolderType& index_set_holder)
1412 {
1413 typedef typename Intern::FaceIndexMapping<Shape::Hypercube<3>, cell_dim_, face_dim_> FimType;
1414 auto& idx = index_set_holder.template get_index_set<cell_dim_, face_dim_>();
1415
1416 for(int i(0); i < Shape::FaceTraits<Shape::Hypercube<3>, cell_dim_>::count; ++i)
1417 {
1418 for(int j(0); j < idx.num_indices; ++j)
1419 {
1420 idx[Index(i)][j] = Index(FimType::map(i, j));
1421 }
1422 }
1423 }
1424 }; // class UnitSphereFactory<ConformalMesh<Shape::Hypercube<2>, ...>>
1426
1427 template<typename MeshType_>
1428 using RefinedUnitSphereFactory = RefineFactory<MeshType_, Geometry::UnitSphereFactory>;
1429 } // namespace Geometry
1430} // namespace FEAT
#define XASSERT(expr)
Assertion macro definition.
Definition: assertion.hpp:262
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Definition: assertion.hpp:263
Conformal mesh class template.
IndexSetHolder< ShapeType > IndexSetHolderType
index set holder type
Mesh Factory class template.
Definition: factory.hpp:33
Conformal Index-Set class template.
Definition: index_set.hpp:82
Constructs a polyline mesh.
MeshType::VertexSetType VertexSetType
vertex set type
virtual void fill_vertex_set(VertexSetType &vertex_set) override
std::deque< Tiny::Vector< Coord_, dim_ > > & _points
Reference to the set of points in the polyline.
MeshType::IndexSetHolderType IndexSetHolderType
index holder type
virtual Index get_num_entities(int dimension) override
virtual void fill_index_sets(IndexSetHolderType &index_set_holder) override
PolylineFactory(std::deque< typename VertexSetType::VertexType > &points_)
From deque of Tiny::Vectors constructor.
ConformalMesh< Shape::Hypercube< 1 >, dim_, Coord_ > MeshType
mesh type
static void compute(IndexSetHolder< Shape_ > &index_set_holder)
Routine that does the actual work.
Standard Refinery class template.
Definition: factory.hpp:58
Structured unit-cube mesh factory.
Unit cube factory with star shaped mesh topology.
T_ sqrt(T_ x)
Returns the square-root of a value.
Definition: math.hpp:300
FEAT namespace.
Definition: adjactor.hpp:12
std::uint64_t Index
Index data type.
Fixed-Sized Vertex Set class template.
Definition: vertex_set.hpp:37
Hypercube shape tag struct template.
Definition: shape.hpp:64
Simplex shape tag struct template.
Definition: shape.hpp:44