FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
tuple_matrix.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/lafem/tuple_vector.hpp>
9
10
11namespace FEAT
12{
13 namespace LAFEM
14 {
30 template<typename First_, typename... Rest_>
32 {
33 private:
34 template<typename,typename...>
35 friend class TupleMatrixRow;
36
37 typedef TupleMatrixRow<Rest_...> RestClass;
38
39 public:
41 static constexpr int num_blocks = TupleMatrixRow<Rest_...>::num_blocks + 1;
42
44 typedef typename First_::DataType DataType;
46 typedef typename First_::IndexType IndexType;
47
48 // ensure that all sub-matrix have the same data-type
49 static_assert(std::is_same<DataType, typename RestClass::DataType>::value,
50 "sub-matrices have different data-types");
51 static_assert(std::is_same<IndexType, typename RestClass::IndexType>::value,
52 "sub-matrices have different index-types");
53
55 template <typename DT2_ = DataType, typename IT2_ = IndexType>
57 typename First_::template ContainerType<DT2_, IT2_>,
58 typename Rest_::template ContainerType<DT2_, IT2_>...>;
59
61 template <typename DataType2_, typename IndexType2_>
63
65 typedef typename First_::VectorTypeL VectorTypeL;
67 typedef TupleVector<typename First_::VectorTypeR, typename Rest_::VectorTypeR...> VectorTypeR;
68
69 protected:
71 First_ _first;
74
77 {
78 return First_::name() + "," + RestClass::sub_name_list();
79 }
80
81 public:
84 {
85 }
86
88 explicit TupleMatrixRow(First_&& the_first, RestClass&& the_rest) :
89 _first(std::forward<First_>(the_first)),
90 _rest(std::forward<RestClass>(the_rest))
91 {
92 }
93
95 explicit TupleMatrixRow(First_&& the_first, Rest_&&... the_rest) :
96 _first(std::forward<First_>(the_first)),
97 _rest(std::forward<Rest_>(the_rest)...)
98 {
99 }
100
103 _first(std::forward<First_>(other._first)),
104 _rest(std::forward<RestClass>(other._rest))
105 {
106 }
107
110 {
111 if(this != &other)
112 {
113 _first = std::forward<First_>(other._first);
114 _rest = std::forward<RestClass>(other._rest);
115 }
116 return *this;
117 }
118
123
131 {
132 return TupleMatrixRow(_first.clone(mode), _rest.clone(mode));
133 }
134
141 void clone(const TupleMatrixRow& other, CloneMode clone_mode)
142 {
143 _first.clone(other._first, clone_mode);
144 _rest.clone(other._rest, clone_mode);
145 }
146
152 void clone(const TupleMatrixRow& other)
153 {
154 _first.clone(other._first);
155 _rest.clone(other._rest);
156 }
157
159 First_& first()
160 {
161 return _first;
162 }
163
164 const First_& first() const
165 {
166 return _first;
167 }
168
169 TupleMatrixRow<Rest_...>& rest()
170 {
171 return _rest;
172 }
173
174 const TupleMatrixRow<Rest_...>& rest() const
175 {
176 return _rest;
177 }
179
189 template<int i_>
190 typename TupleElement<i_, First_, Rest_...>::Type& at()
191 {
192 static_assert((0 <= i_) && (i_ < num_blocks), "invalid sub-matrix index");
194 }
195
197 template<int i_>
198 typename TupleElement<i_, First_, Rest_...>::Type const& at() const
199 {
200 static_assert((0 <= i_) && (i_ < num_blocks), "invalid sub-matrix index");
202 }
203
210 template <Perspective perspective_ = Perspective::native>
211 Index rows() const
212 {
213 const Index rows_f = _first.template rows<perspective_>();
214 const Index rows_r = _rest.template rows<perspective_>();
215 XASSERTM(rows_f == rows_r, "row count mismatch");
216 return rows_f;
217 }
218
225 template <Perspective perspective_ = Perspective::native>
227 {
228 return _first.template columns<perspective_>() + _rest.template columns<perspective_>();
229 }
230
237 template <Perspective perspective_ = Perspective::native>
239 {
240 return _first.template used_elements<perspective_>() + _rest.template used_elements<perspective_>();
241 }
242
248 std::size_t bytes() const
249 {
250 return _first.bytes() + _rest.bytes();
251 }
252
254 static String name()
255 {
256 return String("TupleMatrixRow<") + sub_name_list() + ">";
257 }
258
266 {
267 first().format(value);
268 rest().format(value);
269 }
270
278 void format(Random & rng, DataType min, DataType max)
279 {
280 first().format(rng, min, max);
281 rest().format(rng, min, max);
282 }
283
285 void clear()
286 {
287 first().clear();
288 rest().clear();
289 }
290
293 {
294 return first().create_vector_l();
295 }
296
299 {
300 return VectorTypeR(first().create_vector_r(), rest().create_vector_r());
301 }
302
303 void apply(VectorTypeL& r, const VectorTypeR& x) const
304 {
305 first().apply(r, x.first());
306 rest().apply(r, x.rest(), r, DataType(1));
307 }
308
309 void apply_transposed(VectorTypeR& r, const VectorTypeL& x) const
310 {
311 first().apply_transposed(r.first(), x);
312 rest().apply_transposed(r.rest(), x);
313 }
314
315 void apply(VectorTypeL& r, const VectorTypeR& x, const VectorTypeL& y, DataType alpha = DataType(1)) const
316 {
317 first().apply(r, x.first(), y, alpha);
318 rest().apply(r, x.rest(), r, alpha);
319 }
320
321 void apply_transposed(VectorTypeR& r, const VectorTypeL& x, const VectorTypeR& y, DataType alpha = DataType(1)) const
322 {
323 first().apply_transposed(r.first(), x, y.first(), alpha);
324 rest().apply_transposed(r.rest(), x, y.rest(), alpha);
325 }
326
327 Index get_length_of_line(const Index row) const
328 {
329 return first().get_length_of_line(row) + rest().get_length_of_line(row);
330 }
331
332 void set_line(const Index row, DataType * const pval_set, IndexType * const pcol_set, const Index col_start, const Index stride = 1) const
333 {
334 const Index first_length(first().get_length_of_line(row));
335
336 first().set_line(row, pval_set, pcol_set, col_start, stride);
337 rest().set_line(row, pval_set + stride * first_length, pcol_set + stride * first_length, col_start + first().template columns<Perspective::pod>(), stride);
338 }
339
340 void set_line_reverse(const Index row, DataType * const pval_set, const Index stride = 1)
341 {
342 const Index first_length(first().get_length_of_line(row));
343
344 first().set_line_reverse(row, pval_set, stride);
345 rest().set_line_reverse(row, pval_set + stride * first_length, stride);
346 }
347
349 std::uint64_t get_checkpoint_size(SerialConfig& config)
350 {
351 return sizeof(std::uint64_t) + _first.get_checkpoint_size(config) + _rest.get_checkpoint_size(config); //sizeof(std::uint64_t) bits needed to store lenght of checkpointed _first
352 }
353
355 void restore_from_checkpoint_data(std::vector<char> & data)
356 {
357 std::uint64_t isize = *(std::uint64_t*) data.data(); //get size of checkpointed _first
358 std::vector<char>::iterator start = std::begin(data) + sizeof(std::uint64_t);
359 std::vector<char>::iterator last_of_first = std::begin(data) + sizeof(std::uint64_t) + (int) isize;
360 std::vector<char> buffer_first(start, last_of_first);
361 _first.restore_from_checkpoint_data(buffer_first);
362
363 data.erase(std::begin(data), last_of_first);
365 }
366
368 std::uint64_t set_checkpoint_data(std::vector<char>& data, SerialConfig& config)
369 {
370 std::size_t old_size = data.size();
371 data.insert(std::end(data), sizeof(std::uint64_t), 0); //add placeholder
372 std::uint64_t ireal_size = _first.set_checkpoint_data(data, config); //add data of _first to the overall checkpoint and save its size
373 char* csize = reinterpret_cast<char*>(&ireal_size);
374 for(std::size_t i(0) ; i < sizeof(std::uint64_t) ; ++i) //overwrite the guessed datalength
375 {
376 data[old_size + i] = csize[i];
377 }
378
379 return sizeof(std::uint64_t) + ireal_size + _rest.set_checkpoint_data(data, config); //generate and add checkpoint data for the _rest
380 }
381
382 template<typename OtherFirst_, typename... OtherRest_>
383 void convert(const TupleMatrixRow<OtherFirst_, OtherRest_...>& other)
384 {
385 first().convert(other.first());
386 rest().convert(other.rest());
387 }
388
389 template<typename OtherFirst_, typename... OtherRest_>
390 void convert_reverse(TupleMatrixRow<OtherFirst_, OtherRest_...>& other) const
391 {
392 first().convert_reverse(other.first());
393 rest().convert_reverse(other.rest());
394 }
395 }; // template class TupleMatrixRow
396
398 // specialization for a single sub-matrix
399 template<typename First_>
400 class TupleMatrixRow<First_>
401 {
402 private:
403 template<typename,typename...>
404 friend class TupleMatrixRow;
405
406 public:
408 static constexpr int num_blocks = 1;
409
411 typedef typename First_::DataType DataType;
413 typedef typename First_::IndexType IndexType;
414
415 template <typename DT2_ = DataType, typename IT2_ = IndexType>
416 using ContainerType = TupleMatrixRow<typename First_::template ContainerType<DT2_, IT2_> >;
417
419 template <typename DataType2_, typename IndexType2_>
420 using ContainerTypeByDI = ContainerType<DataType2_, IndexType2_>;
421
423 typedef typename First_::VectorTypeL VectorTypeL;
425 typedef TupleVector<typename First_::VectorTypeR> VectorTypeR;
426
427 protected:
429 First_ _first;
430
432 static String sub_name_list()
433 {
434 return First_::name();
435 }
436
437 public:
439 TupleMatrixRow()
440 {
441 }
442
444 explicit TupleMatrixRow(First_&& the_first) :
445 _first(std::forward<First_>(the_first))
446 {
447 }
448
450 TupleMatrixRow(TupleMatrixRow&& other) :
451 _first(std::forward<First_>(other._first))
452 {
453 }
454
456 TupleMatrixRow& operator=(TupleMatrixRow&& other)
457 {
458 if(this != &other)
459 {
460 _first = std::forward<First_>(other._first);
461 }
462 return *this;
463 }
464
466 TupleMatrixRow(const TupleMatrixRow&) = delete;
468 TupleMatrixRow& operator=(const TupleMatrixRow&) = delete;
469
470 TupleMatrixRow clone(LAFEM::CloneMode mode = LAFEM::CloneMode::Weak) const
471 {
472 return TupleMatrixRow(_first.clone(mode));
473 }
474
475 void clone(const TupleMatrixRow& other, CloneMode clone_mode)
476 {
477 _first.clone(other._first, clone_mode);
478 }
479
480 void clone(const TupleMatrixRow& other)
481 {
482 _first.clone(other._first);
483 }
484
486 First_& first()
487 {
488 return _first;
489 }
490
491 const First_& first() const
492 {
493 return _first;
494 }
496
497 template<int i_>
498 First_& at()
499 {
500 static_assert(i_ == 0, "invalid sub-matrix index");
501 return first();
502 }
503
505 template<int i_>
506 const First_& at() const
507 {
508 static_assert(i_ == 0, "invalid sub-matrix index");
509 return first();
510 }
511
512 template <Perspective perspective_ = Perspective::native>
513 Index rows() const
514 {
515 return _first.template rows<perspective_>();
516 }
517
518 template <Perspective perspective_ = Perspective::native>
519 Index columns() const
520 {
521 return _first.template columns<perspective_>();
522 }
523
524 template <Perspective perspective_ = Perspective::native>
525 Index used_elements() const
526 {
527 return _first.template used_elements<perspective_>();
528 }
529
530 std::size_t bytes() const
531 {
532 return _first.bytes();
533 }
534
535 static String name()
536 {
537 return String("TupleMatrixRow<") + sub_name_list() + ">";
538 }
539
540 void format(DataType value = DataType(0))
541 {
542 first().format(value);
543 }
544
545 void format(Random & rng, DataType min, DataType max)
546 {
547 first().format(rng, min, max);
548 }
549
550 void clear()
551 {
552 first().clear();
553 }
554
556 {
557 return first().create_vector_l();
558 }
559
561 {
562 return VectorTypeR(first().create_vector_r());
563 }
564
565 void apply(VectorTypeL& r, const VectorTypeR& x) const
566 {
567 first().apply(r, x.first());
568 }
569
570 void apply(VectorTypeL& r, const VectorTypeR& x, const VectorTypeL& y, DataType alpha = DataType(1)) const
571 {
572 first().apply(r, x.first(), y, alpha);
573 }
574
575 void apply_transposed(VectorTypeR& r, const VectorTypeL& x) const
576 {
577 first().apply_transposed(r.first(), x);
578 }
579
580 void apply_transposed(VectorTypeR& r, const VectorTypeL& x, const VectorTypeR& y, DataType alpha = DataType(1)) const
581 {
582 first().apply_transposed(r.first(), x, y.first(), alpha);
583 }
584
585 Index get_length_of_line(const Index row) const
586 {
587 return first().get_length_of_line(row);
588 }
589
590 void set_line(const Index row, DataType * const pval_set, IndexType * const pcol_set, const Index col_start, const Index stride = 1) const
591 {
592 first().set_line(row, pval_set, pcol_set, col_start, stride);
593 }
594
595 void set_line_reverse(const Index row, DataType * const pval_set, const Index stride = 1)
596 {
597 first().set_line_reverse(row, pval_set, stride);
598 }
599
601 std::uint64_t get_checkpoint_size(SerialConfig& config)
602 {
603 return _first.get_checkpoint_size(config);
604 }
605
607 void restore_from_checkpoint_data(std::vector<char> & data)
608 {
609 _first.restore_from_checkpoint_data(data);
610 }
611
613 std::uint64_t set_checkpoint_data(std::vector<char>& data, SerialConfig& config)
614 {
615 return _first.set_checkpoint_data(data, config);
616 }
617
618 template<typename OtherFirst_>
619 void convert(const TupleMatrixRow<OtherFirst_>& other)
620 {
621 first().convert(other.first());
622 }
623
624 template<typename OtherFirst_>
625 void convert_reverse(TupleMatrixRow<OtherFirst_>& other) const
626 {
627 first().convert_reverse(other.first());
628 }
629 }; // template class TupleMatrixRow
631
633 namespace Intern
634 {
635 // helper class: checks whether 'T_' is an instance of 'TupleMatrixRow<...>'
636 template<typename T_>
637 struct IsTMR_
638 {
639 static constexpr bool value = false;
640 };
641
642 template<typename... T_>
643 struct IsTMR_<TupleMatrixRow<T_...>>
644 {
645 static constexpr bool value = true;
646 };
647 } // namespace Intern
649
658 template<int i_, int j_, typename FirstRow_, typename... RestRows_>
660 {
661 public:
662 static_assert(i_ > 0, "invalid row index"); // i_=0 is specialized below
663 static_assert(j_ >= 0, "invalid column index");
664
665 typedef typename TupleMatrixElement<i_-1, j_, RestRows_...>::Type Type;
666
667 template<typename Meta_>
668 static Type& get(Meta_& meta)
669 {
671 }
672
673 template<typename Meta_>
674 static const Type& get(const Meta_& meta)
675 {
677 }
678 };
679
681 // specialization for i_ = 0;
682 // Note: This specialization explicitly assumes that 'FirstRow_' is an instance of
683 // 'TupleMatrixRow', which is ensured by a static_assert in the TupleMatrix class.
684 template<int j_, typename First_, typename... Rest_, typename... RestRows_>
685 class TupleMatrixElement<0, j_, TupleMatrixRow<First_, Rest_...>, RestRows_... >
686 {
687 public:
688 static_assert(j_ >= 0, "invalid column index");
689
690 typedef typename TupleElement<j_, First_, Rest_...>::Type Type;
691
692 template<typename Meta_>
693 static Type& get(Meta_& meta)
694 {
695 return TupleElement<j_, First_, Rest_...>::get(meta.first());
696 }
697
698 template<typename Meta_>
699 static const Type& get(const Meta_& meta)
700 {
701 return TupleElement<j_, First_, Rest_...>::get(meta.first());
702 }
703 };
705
718 template<typename FirstRow_, typename... RestRows_>
720 {
721 private:
722 template<typename,typename...>
723 friend class TupleMatrix;
724
725 typedef TupleMatrix<RestRows_...> RestClass;
726
727 // sanity check: ensure that 'FirstRow_' is an instance of TupleMatrixRow
728 // note: this is essential for the implementation of TupleMatrixElement!
729 static_assert(Intern::IsTMR_<FirstRow_>::value,
730 "template parameter of TupleMatrix must be TupleMatrixRow<...>");
731
732 public:
734 static constexpr int num_row_blocks = TupleMatrix<RestRows_...>::num_row_blocks + 1;
736 static constexpr int num_col_blocks = FirstRow_::num_blocks;
737
738 // sanity check: number of column blocks must match for all rows
739 static_assert(num_col_blocks == RestClass::num_col_blocks, "column blocks mismatch");
740
742 typedef typename FirstRow_::DataType DataType;
744 typedef typename FirstRow_::IndexType IndexType;
745
746 // ensure that all sub-matrix have the same data-type
747 static_assert(std::is_same<DataType, typename RestClass::DataType>::value,
748 "sub-matrices have different data-types");
749 static_assert(std::is_same<IndexType, typename RestClass::IndexType>::value,
750 "sub-matrices have different index-types");
751
753 template <typename DT2_ = DataType, typename IT2_ = IndexType>
755 typename FirstRow_::template ContainerType<DT2_, IT2_>,
756 typename RestRows_::template ContainerType<DT2_, IT2_>...>;
757
759 template <typename DataType2_, typename IndexType2_>
761
763 typedef TupleVector<typename FirstRow_::VectorTypeL, typename RestRows_::VectorTypeL...> VectorTypeL;
765 typedef typename FirstRow_::VectorTypeR VectorTypeR;
766
768 static_assert(std::is_same<VectorTypeR, typename RestClass::VectorTypeR>::value, "vector type mismatch");
769
770 protected:
772 FirstRow_ _first;
775
778 {
779 return FirstRow_::name() + "," + RestClass::sub_name_list();
780 }
781
782 public:
785 {
786 }
787
789 explicit TupleMatrix(FirstRow_&& the_first, RestClass&& the_rest) :
790 _first(std::forward<FirstRow_>(the_first)),
791 _rest(std::forward<RestClass>(the_rest))
792 {
793 }
794
796 explicit TupleMatrix(FirstRow_&& the_first, RestRows_&&... the_rest) :
797 _first(std::forward<FirstRow_>(the_first)),
798 _rest(std::forward<RestRows_>(the_rest)...)
799 {
800 }
801
804 _first(std::forward<FirstRow_>(other._first)),
805 _rest(std::forward<RestClass>(other._rest))
806 {
807 }
808
811 {
812 if(this != &other)
813 {
814 _first = std::forward<FirstRow_>(other._first);
815 _rest = std::forward<RestClass>(other._rest);
816 }
817 return *this;
818 }
819
821 TupleMatrix(const TupleMatrix&) = delete;
824
832 {
833 return TupleMatrix(_first.clone(mode), _rest.clone(mode));
834 }
835
842 void clone(const TupleMatrix& other, CloneMode clone_mode)
843 {
844 _first.clone(other._first, clone_mode);
845 _rest.clone(other._rest, clone_mode);
846 }
847
853 void clone(const TupleMatrix& other)
854 {
855 _first.clone(other._first);
856 _rest.clone(other._rest);
857 }
858
860 FirstRow_& first()
861 {
862 return _first;
863 }
864
865 const FirstRow_& first() const
866 {
867 return _first;
868 }
869
870 TupleMatrix<RestRows_...>& rest()
871 {
872 return _rest;
873 }
874
875 const TupleMatrix<RestRows_...>& rest() const
876 {
877 return _rest;
878 }
880
890 template<int i_, int j_>
891 typename TupleMatrixElement<i_, j_, FirstRow_, RestRows_...>::Type& at()
892 {
893 static_assert((0 <= i_) && (i_ < num_row_blocks), "invalid sub-matrix row index");
894 static_assert((0 <= j_) && (j_ < num_col_blocks), "invalid sub-matrix column index");
896 }
897
899 template<int i_, int j_>
900 const typename TupleMatrixElement<i_, j_, FirstRow_, RestRows_...>::Type& at() const
901 {
902 static_assert((0 <= i_) && (i_ < num_row_blocks), "invalid sub-matrix row index");
903 static_assert((0 <= j_) && (j_ < num_col_blocks), "invalid sub-matrix column index");
905 }
906
913 template <Perspective perspective_ = Perspective::native>
914 Index rows() const
915 {
916 return _first.template rows<perspective_>() + _rest.template rows<perspective_>();
917 }
918
925 template <Perspective perspective_ = Perspective::native>
927 {
928 const Index cols_f = _first.template columns<perspective_>();
929 const Index cols_r = _rest.template columns<perspective_>();
930 XASSERTM(cols_f == cols_r, "column count mismatch");
931 return cols_f;
932 }
933
940 template <Perspective perspective_ = Perspective::native>
942 {
943 return _first.template used_elements<perspective_>() + _rest.template used_elements<perspective_>();
944 }
945
951 std::size_t bytes() const
952 {
953 return _first.bytes() + _rest.bytes();
954 }
955
957 static String name()
958 {
959 return String("TupleMatrix<") + sub_name_list() + ">";
960 }
961
969 {
970 first().format(value);
971 rest().format(value);
972 }
973
981 void format(Random & rng, DataType min, DataType max)
982 {
983 first().format(rng, min, max);
984 rest().format(rng, min, max);
985 }
986
988 void clear()
989 {
990 first().clear();
991 rest().clear();
992 }
993
996 {
997 return VectorTypeL(first().create_vector_l(), rest().create_vector_l());
998 }
999
1002 {
1003 return first().create_vector_r();
1004 }
1005
1012 void apply(VectorTypeL& r, const VectorTypeR& x) const
1013 {
1014 first().apply(r.first(), x);
1015 rest().apply(r.rest(), x);
1016 }
1017
1025 {
1026 first().apply_transposed(r, x.first());
1027 rest().apply_transposed(r, x.rest(), r, DataType(1));
1028 }
1029
1038 void apply(VectorTypeL& r, const VectorTypeR& x, const VectorTypeL& y, DataType alpha = DataType(1)) const
1039 {
1040 first().apply(r.first(), x, y.first(), alpha);
1041 rest().apply(r.rest(), x, y.rest(), alpha);
1042 }
1043
1052 void apply_transposed(VectorTypeR& r, const VectorTypeL& x, const VectorTypeR& y, DataType alpha = DataType(1)) const
1053 {
1054 first().apply_transposed(r, x.first(), y, alpha);
1055 rest().apply_transposed(r, x.rest(), r, alpha);
1056 }
1057
1058 Index get_length_of_line(const Index row) const
1059 {
1060 const Index first_rows = first().template rows<Perspective::pod>();
1061 if(row < first_rows)
1062 return first().get_length_of_line(row);
1063 else
1064 return rest().get_length_of_line(row - first_rows);
1065 }
1066
1067 void set_line(const Index row, DataType * const pval_set, IndexType * const pcol_set, const Index col_start, const Index stride = 1) const
1068 {
1069 const Index first_rows = first().template rows<Perspective::pod>();
1070 if(row < first_rows)
1071 first().set_line(row, pval_set, pcol_set, col_start, stride);
1072 else
1073 rest().set_line(row - first_rows, pval_set, pcol_set, col_start, stride);
1074 }
1075
1076 void set_line_reverse(const Index row, DataType * const pval_set, const Index stride = 1)
1077 {
1078 const Index first_rows = first().template rows<Perspective::pod>();
1079 if(row < first_rows)
1080 first().set_line_reverse(row, pval_set, stride);
1081 else
1082 rest().set_line_reverse(row - first_rows, pval_set, stride);
1083 }
1084
1086 std::uint64_t get_checkpoint_size(SerialConfig& config)
1087 {
1088 return sizeof(std::uint64_t) + _first.get_checkpoint_size(config) + _rest.get_checkpoint_size(config); //sizeof(std::uint64_t) bits needed to store lenght of checkpointed _first
1089 }
1090
1092 void restore_from_checkpoint_data(std::vector<char> & data)
1093 {
1094 std::uint64_t isize = *(std::uint64_t*) data.data(); //get size of checkpointed _first
1095 std::vector<char>::iterator start = std::begin(data) + sizeof(std::uint64_t);
1096 std::vector<char>::iterator last_of_first = std::begin(data) + sizeof(std::uint64_t) + (int) isize;
1097 std::vector<char> buffer_first(start, last_of_first);
1098 _first.restore_from_checkpoint_data(buffer_first);
1099
1100 data.erase(std::begin(data), last_of_first);
1102 }
1103
1105 std::uint64_t set_checkpoint_data(std::vector<char>& data, SerialConfig& config)
1106 {
1107 std::size_t old_size = data.size();
1108 data.insert(std::end(data), sizeof(std::uint64_t), 0); //add placeholder
1109 std::uint64_t ireal_size = _first.set_checkpoint_data(data, config); //add data of _first to the overall checkpoint and save its size
1110 char* csize = reinterpret_cast<char*>(&ireal_size);
1111 for(std::size_t i(0) ; i < sizeof(std::uint64_t) ; ++i) //overwrite the guessed datalength
1112 {
1113 data[old_size +i] = csize[i];
1114 }
1115 return sizeof(std::uint64_t) + ireal_size + _rest.set_checkpoint_data(data, config); //generate and add checkpoint data for the _rest
1116 }
1117
1118 template<typename OtherFirstRow_, typename... OtherRestRows_>
1119 void convert(const TupleMatrix<OtherFirstRow_, OtherRestRows_...>& other)
1120 {
1121 first().convert(other.first());
1122 rest().convert(other.rest());
1123 }
1124
1125 template<typename OtherFirstRow_, typename... OtherRestRows_>
1126 void convert_reverse(TupleMatrix<OtherFirstRow_, OtherRestRows_...>& other) const
1127 {
1128 first().convert_reverse(other.first());
1129 rest().convert_reverse(other.rest());
1130 }
1131 }; // template class TupleMatrix
1132
1134 // specialization for 1 row
1135 template<typename FirstRow_>
1136 class TupleMatrix<FirstRow_>
1137 {
1138 private:
1139 template<typename,typename...>
1140 friend class TupleMatrix;
1141
1142 // sanity check: ensure that 'FirstRow_' is an instance of TupleMatrixRow
1143 static_assert(Intern::IsTMR_<FirstRow_>::value,
1144 "template parameter of TupleMatrix must be TupleMatrixRow<...>");
1145
1146 public:
1148 static constexpr int num_blocks = 1;
1149
1151 static constexpr int num_row_blocks = num_blocks;
1153 static constexpr int num_col_blocks = FirstRow_::num_blocks;
1154
1155
1157 typedef typename FirstRow_::DataType DataType;
1159 typedef typename FirstRow_::IndexType IndexType;
1160
1161 template < typename DT2_ = DataType, typename IT2_ = IndexType>
1162 using ContainerType = TupleMatrix<typename FirstRow_::template ContainerType<DT2_, IT2_> >;
1163
1164 template <typename DataType2_, typename IndexType2_>
1165 using ContainerTypeByDI = ContainerType<DataType2_, IndexType2_>;
1166
1168 typedef TupleVector<typename FirstRow_::VectorTypeL> VectorTypeL;
1170 typedef typename FirstRow_::VectorTypeR VectorTypeR;
1171
1172 protected:
1174 FirstRow_ _first;
1175
1177 static String sub_name_list()
1178 {
1179 return FirstRow_::name();
1180 }
1181
1182 public:
1184 TupleMatrix()
1185 {
1186 }
1187
1189 explicit TupleMatrix(FirstRow_&& the_first) :
1190 _first(std::forward<FirstRow_>(the_first))
1191 {
1192 }
1193
1195 TupleMatrix(TupleMatrix&& other) :
1196 _first(std::forward<FirstRow_>(other._first))
1197 {
1198 }
1199
1201 TupleMatrix& operator=(TupleMatrix&& other)
1202 {
1203 if(this != &other)
1204 {
1205 _first = std::forward<FirstRow_>(other._first);
1206 }
1207 return *this;
1208 }
1209
1211 TupleMatrix(const TupleMatrix&) = delete;
1213 TupleMatrix& operator=(const TupleMatrix&) = delete;
1214
1215 TupleMatrix clone(LAFEM::CloneMode mode = LAFEM::CloneMode::Weak) const
1216 {
1217 return TupleMatrix(_first.clone(mode));
1218 }
1219
1220 void clone(const TupleMatrix& other, CloneMode clone_mode)
1221 {
1222 _first.clone(other._first, clone_mode);
1223 }
1224
1225 void clone(const TupleMatrix& other)
1226 {
1227 _first.clone(other._first);
1228 }
1229
1230 FirstRow_& first()
1231 {
1232 return _first;
1233 }
1234
1235 const FirstRow_& first() const
1236 {
1237 return _first;
1238 }
1239
1240 template<int i_, int j_>
1241 typename TupleMatrixElement<i_, j_, FirstRow_>::Type& at()
1242 {
1243 static_assert(0 == i_, "invalid sub-matrix row index");
1244 static_assert((0 <= j_) && (j_ < num_col_blocks), "invalid sub-matrix column index");
1245 return TupleMatrixElement<i_, j_, FirstRow_>::get(*this);
1246 }
1247
1248 template<int i_, int j_>
1249 const typename TupleMatrixElement<i_, j_, FirstRow_>::Type& at() const
1250 {
1251 static_assert(0 == i_, "invalid sub-matrix row index");
1252 static_assert((0 <= j_) && (j_ < num_col_blocks), "invalid sub-matrix column index");
1253 return TupleMatrixElement<i_, j_, FirstRow_>::get(*this);
1254 }
1255
1256 template <Perspective perspective_ = Perspective::native>
1257 Index rows() const
1258 {
1259 return _first.template rows<perspective_>();
1260 }
1261
1262 template <Perspective perspective_ = Perspective::native>
1263 Index columns() const
1264 {
1265 return _first.template columns<perspective_>();
1266 }
1267
1268 template <Perspective perspective_ = Perspective::native>
1269 Index used_elements() const
1270 {
1271 return _first.template used_elements<perspective_>();
1272 }
1273
1274 std::size_t bytes() const
1275 {
1276 return _first.bytes();
1277 }
1278
1279 static String name()
1280 {
1281 return String("TupleMatrix<") + sub_name_list() + ">";
1282 }
1283
1284 void format(DataType value = DataType(0))
1285 {
1286 first().format(value);
1287 }
1288
1289 void format(Random & rng, DataType min, DataType max)
1290 {
1291 first().format(rng, min, max);
1292 }
1293
1294 void clear()
1295 {
1296 first().clear();
1297 }
1298
1301 {
1302 return VectorTypeL(first().create_vector_l());
1303 }
1304
1307 {
1308 return first().create_vector_r();
1309 }
1310
1311 void apply(VectorTypeL& r, const VectorTypeR& x) const
1312 {
1313 first().apply(r.first(), x);
1314 }
1315
1316 void apply(VectorTypeL& r, const VectorTypeR& x, const VectorTypeL& y, DataType alpha = DataType(1)) const
1317 {
1318 first().apply(r.first(), x, y.first(), alpha);
1319 }
1320
1321 void apply_transposed(VectorTypeR& r, const VectorTypeL& x) const
1322 {
1323 first().apply_transposed(r, x.first());
1324 }
1325
1326 void apply_transposed(VectorTypeR& r, const VectorTypeL& x, const VectorTypeR& y, DataType alpha = DataType(1)) const
1327 {
1328 first().apply(r, x.first(), y, alpha);
1329 }
1330
1331 Index get_length_of_line(const Index row) const
1332 {
1333 return first().get_length_of_line(row);
1334 }
1335
1336 void set_line(const Index row, DataType * const pval_set, IndexType * const pcol_set, const Index col_start, const Index stride = 1) const
1337 {
1338 first().set_line(row, pval_set, pcol_set, col_start, stride);
1339 }
1340
1341 void set_line_reverse(const Index row, DataType * const pval_set, const Index stride = 1)
1342 {
1343 first().set_line_reverse(row, pval_set, stride);
1344 }
1345
1347 std::uint64_t get_checkpoint_size(SerialConfig& config)
1348 {
1349 return _first.get_checkpoint_size(config);
1350 }
1351
1353 void restore_from_checkpoint_data(std::vector<char> & data)
1354 {
1355 _first.restore_from_checkpoint_data(data);
1356 }
1357
1359 std::uint64_t set_checkpoint_data(std::vector<char>& data, SerialConfig& config)
1360 {
1361 return _first.set_checkpoint_data(data, config);
1362 }
1363
1364 template<typename OtherFirstRow_>
1365 void convert(const TupleMatrix<OtherFirstRow_>& other)
1366 {
1367 first().convert(other.first());
1368 }
1369
1370 template<typename OtherFirstRow_>
1371 void convert_reverse(TupleMatrix<OtherFirstRow_>& other) const
1372 {
1373 first().convert_reverse(other.first());
1374 }
1375 }; // template class TupleMatrix
1377 } // namespace LAFEM
1378} // namespace FEAT
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Definition: assertion.hpp:263
Config class for serialize parameter.
Definition: container.hpp:47
TupleMatrix element helper class template.
Variadic TupleMatrix class template.
TupleMatrix & operator=(TupleMatrix &&other)
move-assign operator
static constexpr int num_col_blocks
number of column blocks (horizontal size)
FirstRow_::IndexType IndexType
sub-matrix index-type
TupleMatrixElement< i_, j_, FirstRow_, RestRows_... >::Type & at()
Returns a sub-matrix block.
void format(Random &rng, DataType min, DataType max)
Reset all elements of the container to random values.
VectorTypeL create_vector_l() const
Returns a new compatible L-Vector.
VectorTypeR create_vector_r() const
Returns a new compatible R-Vector.
TupleMatrix clone(LAFEM::CloneMode mode=LAFEM::CloneMode::Weak) const
Creates and returns a copy of this matrix.
void clone(const TupleMatrix &other)
Turns this matrix into a clone of other.
static constexpr int num_row_blocks
number of row blocks (vertical size)
std::size_t bytes() const
Returns the total amount of bytes allocated.
void clear()
Free all allocated arrays.
std::uint64_t get_checkpoint_size(SerialConfig &config)
Calculate size.
FirstRow_ _first
sanity check: vector types must match for all rows
TupleMatrix(FirstRow_ &&the_first, RestRows_ &&... the_rest)
Sub-Matrix emplacement constructor.
void format(DataType value=DataType(0))
Reset all elements of the container to a given value or zero if missing.
Index columns() const
Returns the total number of columns in this matrix.
void apply(VectorTypeL &r, const VectorTypeR &x) const
Calculate .
ContainerType< DataType2_, IndexType2_ > ContainerTypeByDI
this typedef lets you create a vector container with new Datatype and Index types
Index rows() const
Returns the total number of rows in this matrix.
void restore_from_checkpoint_data(std::vector< char > &data)
Extract object from checkpoint.
FirstRow_::DataType DataType
sub-matrix data-type
RestClass _rest
all remaining sub-matrix rows
TupleMatrix & operator=(const TupleMatrix &)=delete
deleted copy-assign operator
Index used_elements() const
Returns the total number of non-zeros in this matrix.
void apply_transposed(VectorTypeR &r, const VectorTypeL &x) const
Calculate .
static String sub_name_list()
Returns a list of all sub-matrix type names.
TupleMatrix< typename FirstRow_::template ContainerType< DT2_, IT2_ >, typename RestRows_::template ContainerType< DT2_, IT2_ >... > ContainerType
Our 'base' class type.
void apply_transposed(VectorTypeR &r, const VectorTypeL &x, const VectorTypeR &y, DataType alpha=DataType(1)) const
Calculate .
TupleMatrix(FirstRow_ &&the_first, RestClass &&the_rest)
rest-class emplacement ctor; for internal use only
TupleVector< typename FirstRow_::VectorTypeL, typename RestRows_::VectorTypeL... > VectorTypeL
Compatible L-vector type.
TupleMatrix(const TupleMatrix &)=delete
deleted copy-ctor
const TupleMatrixElement< i_, j_, FirstRow_, RestRows_... >::Type & at() const
Returns a sub-matrix block.
void clone(const TupleMatrix &other, CloneMode clone_mode)
Turns this matrix into a clone of other.
std::uint64_t set_checkpoint_data(std::vector< char > &data, SerialConfig &config)
TupleMatrix(TupleMatrix &&other)
move ctor
static String name()
Returns a descriptive string for this container.
void apply(VectorTypeL &r, const VectorTypeR &x, const VectorTypeL &y, DataType alpha=DataType(1)) const
Calculate .
FirstRow_::VectorTypeR VectorTypeR
Compatible R-vector type.
TupleMatrix row helper class template.
void restore_from_checkpoint_data(std::vector< char > &data)
Extract object from checkpoint.
static String name()
Returns a descriptive string for this container.
VectorTypeL create_vector_l() const
Returns a new compatible L-Vector.
void clone(const TupleMatrixRow &other, CloneMode clone_mode)
Turns this matrix into a clone of other.
Index columns() const
Returns the total number of columns in this matrix.
static constexpr int num_blocks
number of matrix columns
static String sub_name_list()
Returns a list of all sub-matrix type names.
TupleVector< typename First_::VectorTypeR, typename Rest_::VectorTypeR... > VectorTypeR
Compatible R-vector type.
TupleElement< i_, First_, Rest_... >::Type const & at() const
Returns a sub-matrix block.
TupleMatrixRow< typename First_::template ContainerType< DT2_, IT2_ >, typename Rest_::template ContainerType< DT2_, IT2_ >... > ContainerType
Our 'base' class type.
std::uint64_t get_checkpoint_size(SerialConfig &config)
Calculate size.
VectorTypeR create_vector_r() const
Returns a new compatible R-Vector.
TupleMatrixRow & operator=(TupleMatrixRow &&other)
move-assign operator
RestClass _rest
all remaining sub-matrices
TupleMatrixRow(TupleMatrixRow &&other)
move ctor
Index used_elements() const
Returns the total number of non-zeros in this matrix.
TupleMatrixRow(First_ &&the_first, RestClass &&the_rest)
rest-class emplacement ctor; for internal use only
ContainerType< DataType2_, IndexType2_ > ContainerTypeByDI
this typedef lets you create a vector container with new Datatype and Index types
void format(Random &rng, DataType min, DataType max)
Reset all elements of the container to random values.
TupleMatrixRow(First_ &&the_first, Rest_ &&... the_rest)
Sub-Matrix emplacement constructor.
void format(DataType value=DataType(0))
Reset all elements of the container to a given value or zero if missing.
First_::IndexType IndexType
sub-matrix index-type
std::size_t bytes() const
Returns the total amount of bytes allocated.
First_::DataType DataType
sub-matrix data-type
TupleMatrixRow clone(LAFEM::CloneMode mode=LAFEM::CloneMode::Weak) const
Creates and returns a copy of this matrix.
void clone(const TupleMatrixRow &other)
Turns this matrix into a clone of other.
TupleMatrixRow(const TupleMatrixRow &)=delete
deleted copy-ctor
TupleElement< i_, First_, Rest_... >::Type & at()
Returns a sub-matrix block.
First_::VectorTypeL VectorTypeL
Compatible L-vector type.
Index rows() const
Returns the total number of rows in this matrix.
First_ _first
the first sub-matrix
TupleMatrixRow & operator=(const TupleMatrixRow &)=delete
deleted copy-assign operator
void clear()
Free all allocated arrays.
std::uint64_t set_checkpoint_data(std::vector< char > &data, SerialConfig &config)
Variadic TupleVector class template.
Pseudo-Random Number Generator.
Definition: random.hpp:54
String class implementation.
Definition: string.hpp:46
@ other
generic/other permutation strategy
@ rest
restriction (multigrid)
FEAT namespace.
Definition: adjactor.hpp:12
@ value
specifies whether the space should supply basis function values
std::uint64_t Index
Index data type.
Tuple container element helper class template.