FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
index_set.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/shape.hpp>
10#include <kernel/adjacency/permutation.hpp>
11
12// includes, system
13#include <array>
14#include <vector>
15
16namespace FEAT
17{
21 namespace Geometry
22 {
33 template<int num_indices_>
35 {
36 static_assert(num_indices_ > 0, "invalid number of indices");
37
39 static constexpr int num_indices = num_indices_;
40
43
46 {
47 ASSERT(i >= 0);
49 return indices[i];
50 }
51
53 const Index& operator[](int i) const
54 {
55 ASSERT(i >= 0);
57 return indices[i];
58 }
59
60 void permute_map(const Adjacency::Permutation& inv_perm)
61 {
62 for(int i(0); i < num_indices; ++i)
63 indices[i] = inv_perm.map(indices[i]);
64 }
65 }; // struct IndexTuple
66
80 template<int num_indices_>
82 {
83 static_assert(num_indices_ > 0, "invalid index count");
84
85 public:
87 static constexpr int num_indices = num_indices_;
88
91
93 typedef const Index* ImageIterator;
94
95 protected:
99
101 std::vector<IndexTupleType> _indices;
102
104 explicit IndexSet(Index idx_bnd, const std::vector<IndexTupleType>& idx) :
105 _index_bound(idx_bnd), _indices(idx)
106 {
107 }
108
109 public:
119 explicit IndexSet(
120 Index num_entities = 0,
121 Index index_bound = 0)
122 :
123 _index_bound(index_bound),
124 _indices(std::size_t(num_entities))
125 {
126 }
127
131 _indices(std::forward<std::vector<IndexTupleType>>(other._indices))
132 {
133 }
134
137 {
138 // avoid self-move
139 if(this == &other)
140 return *this;
141
142 _index_bound = other._index_bound;
143 _indices = std::forward<std::vector<IndexTupleType>>(other._indices);
144
145 return *this;
146 }
147
149 virtual ~IndexSet()
150 {
151 }
152
155 {
156 return IndexSet(this->_index_bound, this->_indices);
157 }
158
159 void set_indices(std::vector<IndexTupleType>&& vec)
160 {
161 this->_indices = std::move(vec);
162 }
163
165 std::size_t bytes() const
166 {
167 return _indices.size() * sizeof(IndexTupleType);
168 }
169
175 int get_num_indices() const
176 {
177 return num_indices_;
178 }
179
186 {
187 return Index(_indices.size());
188 }
189
196 {
197 return _index_bound;
198 }
199
206 {
207 return _indices.data();
208 }
209
212 {
213 return _indices.data();
214 }
215
226 {
228 return _indices[i];
229 }
230
233 {
235 return _indices[i];
236 }
237
251 {
253 ASSERT(j < num_indices);
254 return _indices[i][j];
255 }
256
257 // copy-paste documentation because \copydoc does not work with operators
270 const Index& operator()(Index i, int j) const
271 {
273 ASSERT(j < num_indices);
274 return _indices[i][j];
275 }
276
284 {
285 _index_bound = bound;
286 }
287
297 void permute(const Adjacency::Permutation& perm, const Adjacency::Permutation& inv_perm_face)
298 {
299 if(_indices.empty())
300 return;
301
302 // first, permute the actual index tuples by the forward permutation
303 if(!perm.empty())
304 {
305 XASSERT(perm.size() == get_num_entities());
306 perm.apply(_indices.data());
307 }
308
309 // now, permute all indices by the inverse face permutation
310 if(!inv_perm_face.empty())
311 {
312 XASSERT(inv_perm_face.size() == get_index_bound());
313 const Index n = Index(_indices.size());
314 for(Index i(0); i < n; ++i)
315 _indices.at(i).permute_map(inv_perm_face);
316 }
317 }
318
324 static String name()
325 {
326 return "IndexSet<" + stringify(num_indices_) + ">";
327 }
328
329 /* *************************************************************************************** */
330 /* A D J A C T O R I N T E R F A C E I M P L E M E N T A T I O N */
331 /* *************************************************************************************** */
334 {
335 return get_num_entities();
336 }
337
340 {
341 return _index_bound;
342 }
343
345 ImageIterator image_begin(Index domain_node) const
346 {
347 ASSERT(domain_node < get_num_entities());
348 return reinterpret_cast<const Index*>(&_indices.data()[domain_node]);
349 }
350
352 ImageIterator image_end(Index domain_node) const
353 {
354 ASSERT(domain_node < get_num_entities());
355 return reinterpret_cast<const Index*>(&_indices.data()[domain_node+1]);
356 }
357 }; // class IndexSet<...>
358
359 /* ***************************************************************************************** */
360 /* ***************************************************************************************** */
361 /* ***************************************************************************************** */
362
364 template<
365 typename Shape_,
366 int face_dim_ = Shape_::dimension - 1>
367 class IndexSetWrapper :
368 public IndexSetWrapper<Shape_, face_dim_ - 1>
369 {
370 static_assert(face_dim_ < Shape_::dimension, "invalid face dimension");
371 static_assert(face_dim_ > 0, "invalid face dimension");
372
373 public:
374 typedef IndexSetWrapper<Shape_, face_dim_ - 1> BaseClass;
375 typedef IndexSet<Shape::FaceTraits<Shape_, face_dim_>::count> IndexSetType;
376
377 protected:
378 IndexSetType _index_set;
379
380 public:
381 IndexSetWrapper() :
382 BaseClass(),
383 _index_set()
384 {
385 }
386
387 explicit IndexSetWrapper(const Index num_entities[]) :
388 BaseClass(num_entities),
389 _index_set(
390 num_entities[Shape_::dimension],
391 num_entities[face_dim_])
392 {
393 }
394
395 template<std::size_t m_>
396 explicit IndexSetWrapper(const std::array<Index, m_>& num_entities) :
397 BaseClass(num_entities),
398 _index_set(
399 num_entities[Shape_::dimension],
400 num_entities[face_dim_])
401 {
402 static_assert(int(m_) > Shape_::dimension, "invalid array size");
403 }
404
405 IndexSetWrapper(IndexSetWrapper&& other) :
406 BaseClass(std::forward<BaseClass>(other)),
407 _index_set(std::forward<IndexSetType>(other._index_set))
408 {
409 }
410
411 IndexSetWrapper& operator=(IndexSetWrapper&& other)
412 {
413 if(this == &other)
414 return *this;
415
416 BaseClass::operator=(std::forward<BaseClass>(other));
417 _index_set = std::forward<IndexSetType>(other._index_set);
418
419 return *this;
420 }
421
422 virtual ~IndexSetWrapper()
423 {
424 }
425
426 void clone(const IndexSetWrapper& other)
427 {
428 BaseClass::clone(other);
429 this->_index_set = other._index_set.clone();
430 }
431
432 IndexSetWrapper clone() const
433 {
434 IndexSetWrapper isw;
435 isw.clone(*this);
436 return isw;
437 }
438
439 template<int face_dim__>
440 IndexSet<Shape::FaceTraits<Shape_, face_dim__>::count>& get_index_set()
441 {
442 static_assert(face_dim__ >= 0, "invalid face dimension");
443 static_assert(face_dim__ < Shape_::dimension, "invalid face dimension");
444 return IndexSetWrapper<Shape_, face_dim__>::_index_set;
445 }
446
447 template<int face_dim__>
448 const IndexSet<Shape::FaceTraits<Shape_, face_dim__>::count>& get_index_set() const
449 {
450 static_assert(face_dim__ >= 0, "invalid face dimension");
451 static_assert(face_dim__ < Shape_::dimension, "invalid face dimension");
452 return IndexSetWrapper<Shape_, face_dim__>::_index_set;
453 }
454
455 template<std::size_t np_>
456 void permute(const Adjacency::Permutation& shape_perm,
457 const std::array<Adjacency::Permutation, np_>& inv_perm)
458 {
459 BaseClass::permute(shape_perm, inv_perm);
460 _index_set.permute(shape_perm, inv_perm.at(face_dim_));
461 }
462
463 static String name()
464 {
465 return "IndexSetWrapper<" + Shape_::name() + "," + stringify(face_dim_) + ">";
466 }
467
468 std::size_t bytes() const
469 {
470 return BaseClass::bytes() + _index_set.bytes();
471 }
472 };
473
474 template<typename Shape_>
475 class IndexSetWrapper<Shape_, 0>
476 {
477 static_assert(Shape_::dimension > 0, "invalid shape dimension");
478
479 public:
480 typedef IndexSet<Shape::FaceTraits<Shape_, 0>::count> IndexSetType;
481
482 protected:
483 IndexSetType _index_set;
484
485 public:
486 IndexSetWrapper() :
487 _index_set()
488 {
489 }
490
491 explicit IndexSetWrapper(const Index num_entities[]) :
492 _index_set(
493 num_entities[Shape_::dimension],
494 num_entities[0])
495 {
496 }
497
498 template<std::size_t m_>
499 explicit IndexSetWrapper(const std::array<Index, m_>& num_entities) :
500 _index_set(
501 num_entities[Shape_::dimension],
502 num_entities[0])
503 {
504 static_assert(int(m_) > Shape_::dimension, "invalid array size");
505 }
506
507 IndexSetWrapper(IndexSetWrapper&& other) :
508 _index_set(std::forward<IndexSetType>(other._index_set))
509 {
510 }
511
512 IndexSetWrapper& operator=(IndexSetWrapper&& other)
513 {
514 if(this == &other)
515 return *this;
516
517 _index_set = std::forward<IndexSetType>(other._index_set);
518
519 return *this;
520 }
521
522 virtual ~IndexSetWrapper()
523 {
524 }
525
526 void clone(const IndexSetWrapper& other)
527 {
528 this->_index_set = other._index_set.clone();
529 }
530
531 IndexSetWrapper clone() const
532 {
533 IndexSetWrapper isw;
534 isw.clone(*this);
535 return isw;
536 }
537
538 template<int face_dim__>
539 IndexSet<Shape::FaceTraits<Shape_, face_dim__>::count>& get_index_set()
540 {
541 static_assert(face_dim__ == 0, "invalid face dimension");
542 return IndexSetWrapper<Shape_, face_dim__>::_index_set;
543 }
544
545 template<int face_dim__>
546 const IndexSet<Shape::FaceTraits<Shape_, face_dim__>::count>& get_index_set() const
547 {
548 static_assert(face_dim__ == 0, "invalid face dimension");
549 return IndexSetWrapper<Shape_, face_dim__>::_index_set;
550 }
551
552 template<std::size_t np_>
553 void permute(const Adjacency::Permutation& shape_perm,
554 const std::array<Adjacency::Permutation, np_>& inv_perm)
555 {
556 _index_set.permute(shape_perm, inv_perm.at(0));
557 }
558
559 static String name()
560 {
561 return "IndexSetWrapper<" + Shape_::name() + ",0>";
562 }
563
564 std::size_t bytes() const
565 {
566 return _index_set.bytes();
567 }
568 };
569
570 /* ***************************************************************************************** */
571 /* ***************************************************************************************** */
572 /* ***************************************************************************************** */
573
603 template<typename Shape_>
604 class IndexSetHolder :
605 public IndexSetHolder<typename Shape::FaceTraits<Shape_, Shape_::dimension - 1>::ShapeType>
606 {
607 public:
608 typedef IndexSetHolder<typename Shape::FaceTraits<Shape_, Shape_::dimension - 1>::ShapeType> BaseClass;
609 typedef IndexSetWrapper<Shape_> IndexSetWrapperType;
610
611 template<
612 int cell_dim_,
613 int face_dim_>
614 struct IndexSet
615 {
617 typedef Geometry::IndexSet
618 <
619 Shape::FaceTraits
620 <
621 typename Shape::FaceTraits<Shape_, cell_dim_> ::ShapeType,
622 face_dim_
623 >
624 ::count
625 > Type;
626 }; // struct IndexSet<...>
627
628 protected:
629 IndexSetWrapperType _index_set_wrapper;
630
631 public:
632 IndexSetHolder() :
633 BaseClass(),
634 _index_set_wrapper()
635 {
636 }
637
638 explicit IndexSetHolder(const Index num_entities[]) :
639 BaseClass(num_entities),
640 _index_set_wrapper(num_entities)
641 {
642 }
643
644 template<std::size_t m_>
645 explicit IndexSetHolder(const std::array<Index, m_>& num_entities) :
646 BaseClass(num_entities),
647 _index_set_wrapper(num_entities)
648 {
649 static_assert(int(m_) > Shape_::dimension, "invalid array size");
650 }
651
652 IndexSetHolder(IndexSetHolder&& other) :
653 BaseClass(std::forward<BaseClass>(other)),
654 _index_set_wrapper(std::forward<IndexSetWrapperType>(other._index_set_wrapper))
655 {
656 }
657
658 IndexSetHolder& operator=(IndexSetHolder&& other)
659 {
660 if(this == &other)
661 return *this;
662
663 BaseClass::operator=(std::forward<BaseClass>(other));
664 _index_set_wrapper = std::forward<IndexSetWrapperType>(other._index_set_wrapper);
665
666 return *this;
667 }
668
669 virtual ~IndexSetHolder()
670 {
671 }
672
673 void clone(const IndexSetHolder& other)
674 {
675 BaseClass::clone(other);
676 this->_index_set_wrapper.clone(other._index_set_wrapper);
677 }
678
679 IndexSetHolder clone() const
680 {
681 IndexSetHolder ish;
682 ish.clone(*this);
683 return ish;
684 }
685
686 template<int shape_dim_>
687 IndexSetWrapper<typename Shape::FaceTraits<Shape_, shape_dim_>::ShapeType>& get_index_set_wrapper()
688 {
689 static_assert(shape_dim_ > 0, "invalid shape dimension");
690 static_assert(shape_dim_ <= Shape_::dimension, "invalid shape dimension");
691 typedef typename Shape::FaceTraits<Shape_, shape_dim_>::ShapeType ShapeType;
692 return IndexSetHolder<ShapeType>::_index_set_wrapper;
693 }
694
695 template<int shape_dim_>
696 const IndexSetWrapper<typename Shape::FaceTraits<Shape_, shape_dim_>::ShapeType>& get_index_set_wrapper() const
697 {
698 static_assert(shape_dim_ > 0, "invalid shape dimension");
699 static_assert(shape_dim_ <= Shape_::dimension, "invalid shape dimension");
700 typedef typename Shape::FaceTraits<Shape_, shape_dim_>::ShapeType ShapeType;
701 return IndexSetHolder<ShapeType>::_index_set_wrapper;
702 }
703
704 template<
705 int cell_dim_,
706 int face_dim_>
707 Geometry::IndexSet<
708 Shape::FaceTraits<
709 typename Shape::FaceTraits<
710 Shape_,
711 cell_dim_>
712 ::ShapeType,
713 face_dim_>
714 ::count>&
715 get_index_set()
716 {
717 static_assert(cell_dim_ <= Shape_::dimension, "invalid cell dimension");
718 static_assert(face_dim_ < cell_dim_, "invalid face/cell dimension");
719 static_assert(face_dim_ >= 0, "invalid face dimension");
720 return get_index_set_wrapper<cell_dim_>().template get_index_set<face_dim_>();
721 }
722
723 template<
724 int cell_dim_,
725 int face_dim_>
726 const Geometry::IndexSet<
727 Shape::FaceTraits<
728 typename Shape::FaceTraits<
729 Shape_,
730 cell_dim_>
731 ::ShapeType,
732 face_dim_>
733 ::count>&
734 get_index_set() const
735 {
736 static_assert(cell_dim_ <= Shape_::dimension, "invalid cell dimension");
737 static_assert(face_dim_ < cell_dim_, "invalid face/cell dimension");
738 static_assert(face_dim_ >= 0, "invalid face dimension");
739 return get_index_set_wrapper<cell_dim_>().template get_index_set<face_dim_>();
740 }
741
742 template<std::size_t np_>
743 void permute(const std::array<Adjacency::Permutation, np_>& perms,
744 const std::array<Adjacency::Permutation, np_>& inv_perms)
745 {
746 BaseClass::permute(perms, inv_perms);
747 _index_set_wrapper.permute(perms.at(Shape_::dimension), inv_perms);
748 }
749
750 static String name()
751 {
752 return "IndexSetHolder<" + Shape_::name() + ">";
753 }
754
755 std::size_t bytes() const
756 {
757 return BaseClass::bytes() + _index_set_wrapper.bytes();
758 }
759 };
760
761 template<>
762 class IndexSetHolder<Shape::Vertex>
763 {
764 public:
765 IndexSetHolder()
766 {
767 }
768
769 explicit IndexSetHolder(const Index* /*num_entities*/)
770 {
771 }
772
773 template<std::size_t m_>
774 explicit IndexSetHolder(const std::array<Index, m_>&)
775 {
776 }
777
778 IndexSetHolder(IndexSetHolder&&)
779 {
780 }
781
782 IndexSetHolder& operator=(IndexSetHolder&&)
783 {
784 return *this;
785 }
786
787 virtual ~IndexSetHolder()
788 {
789 }
790
791 void clone(const IndexSetHolder&)
792 {
793 }
794
795 IndexSetHolder clone() const
796 {
797 return IndexSetHolder();
798 }
799
800 template<std::size_t np_>
801 void permute(const std::array<Adjacency::Permutation, np_>&,
802 const std::array<Adjacency::Permutation, np_>&)
803 {
804 }
805
806 static String name()
807 {
808 return "IndexSetHolder<Vertex>";
809 }
810
811 std::size_t bytes() const
812 {
813 return std::size_t(0);
814 }
815 };
816
843 template<int shape_dim_, int co_dim_>
844 struct IndexSetHolderDimensionUpdater
845 {
855 template<typename IndexSetHolderType_>
856 static void update(IndexSetHolderType_& DOXY(ish))
857 {
858 //dummy
859 }
860 };
861
866 template<int shape_dim_>
867 struct IndexSetHolderDimensionUpdater<shape_dim_,1>
868 {
869 template<typename IndexSetHolderType_>
870 static void update(IndexSetHolderType_& ish)
871 {
872 auto& vert_at_subshape_index_set(ish.template get_index_set<shape_dim_-1,0>());
873
874 Index num_shapes(ish.template get_index_set<shape_dim_,0>().get_num_entities());
875 // Get the type of the IndexSet to dimensions <Shape_::dimension, face_dim_>
876 typename std::remove_reference<decltype( (ish.template get_index_set<shape_dim_, shape_dim_-1>()) )>::type
877 // The output IndexSet has num_shapes entities and the maximum index is the number of subshapes
878 subshape_at_shape_index_set(num_shapes, vert_at_subshape_index_set.get_num_entities());
879
880 // Replace the corresponding IndexSet in the IndexSetHolder by the just generated IndexSet of the right
881 // size
882 ish.template get_index_set<shape_dim_, shape_dim_-1>() = std::move(subshape_at_shape_index_set);
883 }
884 };
885
890 template<int shape_dim_>
891 struct IndexSetHolderDimensionUpdater<shape_dim_,2>
892 {
893 template<typename IndexSetHolderType_>
894 static void update(IndexSetHolderType_& ish)
895 {
896 // Update edge\@cell IndexSet dimensions
897 // vert\@edge IndexSet
898 auto& vert_at_subshape_index_set(ish.template get_index_set<shape_dim_-2,0>());
899 // Number of cells
900 Index num_shapes(ish.template get_index_set<shape_dim_,0>().get_num_entities());
901 // Get the type of the IndexSet to dimensions <Shape_::dimension, Shape::dimension-2>
902 typename std::remove_reference<decltype( (ish.template get_index_set<shape_dim_, shape_dim_-2>()) )>::type
903 // The output IndexSet has num_shapes entities and the maximum index is the number of subshapes (=edges)
904 subshape_at_shape_index_set(num_shapes, vert_at_subshape_index_set.get_num_entities());
905 // Replace the corresponding IndexSet in the IndexSetHolder by the just generated IndexSet of the right
906 // size
907 ish.template get_index_set<shape_dim_, shape_dim_-2>() = std::move(subshape_at_shape_index_set);
908
909 // Now do it again for the edge\@face IndexSet
910 // Number of faces
911 Index num_intermediate_shapes(ish.template get_index_set<shape_dim_-1,0>().get_num_entities());
912 // Get the type of the IndexSet to dimensions <Shape_::dimension-1, Shape::dimension-2>
913 typename std::remove_reference<decltype( (ish.template get_index_set<shape_dim_-1, shape_dim_-2>()) )>::type
914 // The output IndexSet has num_intermediate_shapes entities and the maximum index is the number of subshapes
915 subshape_at_intermediate_index_set(
916 num_intermediate_shapes, vert_at_subshape_index_set.get_num_entities());
917 // Replace the corresponding IndexSet in the IndexSetHolder by the just generated IndexSet of the right
918 // size
919 ish.template get_index_set<shape_dim_-1, shape_dim_-2>() = std::move(subshape_at_intermediate_index_set);
920 }
921 };
922
939 template<int dim_>
940 struct NumEntitiesExtractor
941 {
955 template<typename IndexSetHolderType_>
956 static void set_num_entities(const IndexSetHolderType_& ish, Index* num_entities)
957 {
958 // The number of entities of dimension dim_ is the length of the vertex\@shape[dim_] IndexSet
959 num_entities[dim_] = ish.template get_index_set<dim_,0>().get_num_entities();
960 // Recurse down
961 NumEntitiesExtractor<dim_-1>::set_num_entities(ish, num_entities);
962 }
963
964 template<typename IndexSetHolderType_>
965 static void set_num_entities_with_numverts(const IndexSetHolderType_& ish, Index* num_entities)
966 {
967 // The number of entities of dimension dim_ is the length of the vertex\@shape[dim_] IndexSet
968 num_entities[dim_] = ish.template get_index_set<dim_,0>().get_num_entities();
969 // Recurse down
970 NumEntitiesExtractor<dim_-1>::set_num_entities_with_numverts(ish, num_entities);
971 }
972 };
973
980 template<>
981 struct NumEntitiesExtractor<1>
982 {
983 template<typename IndexSetHolderType_>
984 static void set_num_entities(const IndexSetHolderType_& ish, Index* num_entities)
985 {
986 num_entities[1] = ish.template get_index_set<1,0>().get_num_entities();
987 }
988
989 template<typename IndexSetHolderType_>
990 static void set_num_entities_with_numverts(const IndexSetHolderType_& ish, Index* num_entities)
991 {
992 num_entities[0] = ish.template get_index_set<1,0>().get_index_bound();
993 num_entities[1] = ish.template get_index_set<1,0>().get_num_entities();
994 }
995 };
997 } // namespace Geometry
998} // namespace FEAT
#define ASSERT(expr)
Debug-Assertion macro definition.
Definition: assertion.hpp:229
#define XASSERT(expr)
Assertion macro definition.
Definition: assertion.hpp:262
Index size() const
returns the size of the permutation
bool empty() const
Checks whether the permutation is empty.
void apply(Tx_ *x, bool invert=false) const
Applies In-Situ permutation.
Conformal Index-Set class template.
Definition: index_set.hpp:82
Index get_num_nodes_domain() const
Returns the number of domain nodes.
Definition: index_set.hpp:333
Index & operator()(Index i, int j)
Maps a face index.
Definition: index_set.hpp:250
IndexSet(IndexSet &&other)
move constructor
Definition: index_set.hpp:129
static constexpr int num_indices
number of indices per entry
Definition: index_set.hpp:87
IndexSet(Index num_entities=0, Index index_bound=0)
Constructor.
Definition: index_set.hpp:119
IndexSet(Index idx_bnd, const std::vector< IndexTupleType > &idx)
internal clone constructor
Definition: index_set.hpp:104
std::size_t bytes() const
Definition: index_set.hpp:165
const Index * ImageIterator
ImageIterator type for Adjactor interface implementation.
Definition: index_set.hpp:93
virtual ~IndexSet()
virtual destructor
Definition: index_set.hpp:149
void set_index_bound(Index bound)
Sets the index bound.
Definition: index_set.hpp:283
IndexTupleType * get_indices()
Returns the index vector array.
Definition: index_set.hpp:205
Index get_index_bound() const
Returns the index bound.
Definition: index_set.hpp:195
std::vector< IndexTupleType > _indices
index vector array
Definition: index_set.hpp:101
const Index & operator()(Index i, int j) const
Maps a face index.
Definition: index_set.hpp:270
const IndexTupleType & operator[](Index i) const
Returns a reference to an index tuple.
Definition: index_set.hpp:232
ImageIterator image_begin(Index domain_node) const
Returns an iterator for the first adjacent image node.
Definition: index_set.hpp:345
void permute(const Adjacency::Permutation &perm, const Adjacency::Permutation &inv_perm_face)
Permutes this index set in-situ.
Definition: index_set.hpp:297
const IndexTupleType * get_indices() const
Returns the index vector array.
Definition: index_set.hpp:211
IndexTupleType & operator[](Index i)
Returns a reference to an index tuple.
Definition: index_set.hpp:225
IndexTuple< num_indices > IndexTupleType
index tuple type
Definition: index_set.hpp:90
Index get_num_entities() const
Returns the number of entities.
Definition: index_set.hpp:185
Index get_num_nodes_image() const
Returns the number of image nodes.
Definition: index_set.hpp:339
static String name()
Returns the name of the class.
Definition: index_set.hpp:324
IndexSet & operator=(IndexSet &&other)
move-assignment operator
Definition: index_set.hpp:136
ImageIterator image_end(Index domain_node) const
Returns an iterator for the first position past the last adjacent image node.
Definition: index_set.hpp:352
int get_num_indices() const
Returns the number of indices per entity.
Definition: index_set.hpp:175
IndexSet clone() const
Definition: index_set.hpp:154
String class implementation.
Definition: string.hpp:47
@ other
generic/other permutation strategy
Type
Type enumeration.
Definition: pack.hpp:70
FEAT namespace.
Definition: adjactor.hpp:12
String stringify(const T_ &item)
Converts an item into a String.
Definition: string.hpp:993
std::uint64_t Index
Index data type.
Index Tuple class template.
Definition: index_set.hpp:35
const Index & operator[](int i) const
access operator
Definition: index_set.hpp:53
Index & operator[](int i)
access operator
Definition: index_set.hpp:45
static constexpr int num_indices
number of indices per tuple
Definition: index_set.hpp:39
Index indices[num_indices]
indices array
Definition: index_set.hpp:42