FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
tuple_vector.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/lafem/meta_element.hpp>
10
11
12// includes, system
13#include <iostream>
14#include <type_traits>
15
16namespace FEAT
17{
18 namespace LAFEM
19 {
30 template<
31 typename First_,
32 typename... Rest_>
34 {
35 private:
36 template<typename,typename...>
37 friend class TupleVector;
38
39 typedef TupleVector<Rest_...> RestClass;
40
42 void _read_from_binary(std::istream& file)
43 {
44 //process first
45 _first.read_from(FileMode::fm_binary, file);
46
47 // append rest
49 }
50
52 void _write_out_binary(std::ostream& file) const
53 {
54 //process first
55 _first.write_out(FileMode::fm_binary, file);
56
57 // append rest
59 }
60
61 public:
63 static constexpr int num_blocks = TupleVector<Rest_...>::num_blocks + 1;
64
66 typedef typename First_::DataType DataType;
68 typedef typename First_::IndexType IndexType;
69
71 template <typename DT2_ = DataType, typename IT2_ = IndexType>
73 typename First_::template ContainerType<DT2_, IT2_>,
74 typename Rest_::template ContainerType<DT2_, IT2_>...>;
75
77 template <typename DataType2_, typename IndexType2_>
79
80 // ensure that all sub-vector have the same data-type
81 static_assert(std::is_same<DataType, typename RestClass::DataType>::value,
82 "sub-vectors have different data-types");
83 static_assert(std::is_same<IndexType, typename RestClass::IndexType>::value,
84 "sub-vectors have different index-types");
85
86 protected:
88 First_ _first;
91
94 {
95 return First_::name() + "," + RestClass::sub_name_list();
96 }
97
98 public:
101 {
102 }
103
105 explicit TupleVector(First_&& the_first, RestClass&& the_rest) :
106 _first(std::forward<First_>(the_first)),
107 _rest(std::forward<RestClass>(the_rest))
108 {
109 }
110
112 explicit TupleVector(First_&& the_first, Rest_&&... the_rest) :
113 _first(std::forward<First_>(the_first)),
114 _rest(std::forward<Rest_>(the_rest)...)
115 {
116 }
117
120 _first(std::forward<First_>(other._first)),
121 _rest(std::forward<RestClass>(other._rest))
122 {
123 }
124
127 {
128 if(this != &other)
129 {
130 _first = std::forward<First_>(other._first);
131 _rest = std::forward<RestClass>(other._rest);
132 }
133 return *this;
134 }
135
137 TupleVector(const TupleVector&) = delete;
140
149 {
150 return TupleVector(_first.clone(mode), _rest.clone(mode));
151 }
152
160 void clone(const TupleVector& other, CloneMode clone_mode)
161 {
162 _first.clone(other._first, clone_mode);
163 _rest.clone(other._rest, clone_mode);
164 }
165
172 void clone(const TupleVector& other)
173 {
174 _first.clone(other._first);
175 _rest.clone(other._rest);
176 }
177
179 std::uint64_t get_checkpoint_size(SerialConfig& config)
180 {
181 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
182 }
183
185 void restore_from_checkpoint_data(std::vector<char> & data)
186 {
187 std::uint64_t isize = *(std::uint64_t*) data.data(); //get size of checkpointed _first
188 std::vector<char>::iterator start = std::begin(data) + sizeof(std::uint64_t);
189 std::vector<char>::iterator last_of_first = std::begin(data) + sizeof(std::uint64_t) + (int) isize;
190 std::vector<char> buffer_first(start, last_of_first);
191 _first.restore_from_checkpoint_data(buffer_first);
192
193 data.erase(std::begin(data), last_of_first);
195 }
196
198 std::uint64_t set_checkpoint_data(std::vector<char>& data, SerialConfig& config)
199 {
200 std::size_t old_size = data.size();
201 data.insert(std::end(data), sizeof(std::uint64_t), 0); //add placeholder
202 std::uint64_t ireal_size = _first.set_checkpoint_data(data, config); //add data of _first to the overall checkpoint and save its size
203 char* csize = reinterpret_cast<char*>(&ireal_size);
204 for(std::size_t i(0) ; i < sizeof(std::uint64_t) ; ++i) //overwrite the guessed datalength
205 {
206 data[old_size +i] = csize[i];
207 }
208
209 return sizeof(std::uint64_t) + ireal_size + _rest.set_checkpoint_data(data, config); //generate and add checkpoint data for the _rest
210 }
211
213 First_& first()
214 {
215 return _first;
216 }
217
218 const First_& first() const
219 {
220 return _first;
221 }
222
223 TupleVector<Rest_...>& rest()
224 {
225 return _rest;
226 }
227
228 const TupleVector<Rest_...>& rest() const
229 {
230 return _rest;
231 }
233
243 template<int i_>
244 typename TupleElement<i_, First_, Rest_...>::Type& at()
245 {
246 static_assert((0 <= i_) && (i_ < num_blocks), "invalid sub-vector index");
248 }
249
251 template<int i_>
252 typename TupleElement<i_, First_, Rest_...>::Type const& at() const
253 {
254 static_assert((0 <= i_) && (i_ < num_blocks), "invalid sub-vector index");
256 }
257
259 template <Perspective perspective_ = Perspective::native>
260 Index size() const
261 {
262 return _first.template size<perspective_>() + _rest.template size<perspective_>();
263 }
264
266 int blocks() const
267 {
268 return num_blocks;
269 }
270
272 static String name()
273 {
274 return String("TupleVector<") + sub_name_list() + ">";
275 }
276
284 {
285 first().format(value);
286 rest().format(value);
287 }
288
296 void format(Random & rng, DataType min, DataType max)
297 {
298 first().format(rng, min, max);
299 rest().format(rng, min, max);
300 }
301
303 void clear()
304 {
305 first().clear();
306 rest().clear();
307 }
308
315 //template<typename First2_, typename... Rest2_>
316 void copy(const TupleVector/*<First2_, Rest2_...>*/& x, bool full = false)
317 {
318 first().copy(x.first(), full);
319 rest().copy(x.rest(), full);
320 }
321
322 void axpy(const TupleVector& x, DataType alpha = DataType(1))
323 {
324 first().axpy(x.first(), alpha);
325 rest().axpy(x.rest(), alpha);
326 }
327
328 void component_product(const TupleVector & x, const TupleVector & y)
329 {
330 first().component_product(x.first(), y.first());
331 rest().component_product(x.rest(), y.rest());
332 }
333
334 void component_invert(const TupleVector& x, DataType alpha = DataType(1))
335 {
336 first().component_invert(x.first(), alpha);
337 rest().component_invert(x.rest(), alpha);
338 }
339
340 void scale(const TupleVector& x, DataType alpha)
341 {
342 first().scale(x.first(), alpha);
343 rest().scale(x.rest(), alpha);
344 }
345
346 DataType dot(const TupleVector& x) const
347 {
348 return first().dot(x.first()) + rest().dot(x.rest());
349 }
350
354 DataType triple_dot(const TupleVector& x, const TupleVector& y) const
355 {
356 return first().triple_dot(x.first(), y.first())
357 + rest().triple_dot(x.rest(), y.rest());
358 }
359
360 DataType norm2sqr() const
361 {
362 return first().norm2sqr() + rest().norm2sqr();
363 }
364
365 DataType norm2() const
366 {
367 return Math::sqrt(norm2sqr());
368 }
369
376 {
377 return Math::max(first().max_abs_element(), rest().max_abs_element());
378 }
379
386 {
387 return Math::min(first().min_abs_element(), rest().min_abs_element());
388 }
389
396 {
397 return Math::max(first().max_element(), rest().max_element());
398 }
399
406 {
407 return Math::min(first().min_element(), rest().min_element());
408 }
409
416 template <typename First2_, typename... Rest2_>
418 {
419 return Math::max(first().max_rel_diff(x.first()), rest().max_rel_diff(x.rest()));
420 }
421
424 void set_vec(DataType * const pval_set) const
425 {
426 this->first().set_vec(pval_set);
427 this->rest().set_vec(pval_set + this->first().template size<Perspective::pod>());
428 }
429
431 void set_vec_inv(const DataType * const pval_set)
432 {
433 this->first().set_vec_inv(pval_set);
434 this->rest().set_vec_inv(pval_set + this->first().template size<Perspective::pod>());
435 }
437
445 template <typename First2_, typename... Rest2_>
447 {
448 this->first().convert(other.first());
449 this->rest().convert(other.rest());
450 }
451
453 std::size_t bytes() const
454 {
455 return _first.bytes() + _rest.bytes();
456 }
457
464 void read_from(FileMode mode, const String& filename)
465 {
466 std::ifstream file(filename.c_str(), std::ifstream::in | std::ifstream::binary);
467 if (! file.is_open())
468 XABORTM("Unable to open Vector file " + filename);
469 read_from(mode, file);
470 file.close();
471 }
472
479 void read_from(FileMode mode, std::istream& file)
480 {
481 switch(mode)
482 {
484 {
485 std::uint64_t magic; // magic_number
486 file.read((char *)&magic, (long)(sizeof(std::uint64_t)));
487 if (magic != 101)
488 XABORTM("Given file or file component is no TupleVector!");
489 std::uint64_t count; // subvector count
490 file.read((char *)&count, (long)(sizeof(std::uint64_t)));
491 //if (count != num_blocks)
492 // XABORTM("TupleVector file read in component count mismatch: class has " + stringify(num_blocks) + "- " + stringify(count) + " read in!");
493
494 _read_from_binary(file);
495 break;
496 }
497 default:
498 XABORTM("Filemode not supported!");
499 }
500 }
501
508 void write_out(FileMode mode, const String& filename) const
509 {
510 std::ofstream file(filename.c_str(), std::ofstream::out | std::ofstream::binary);
511 if (! file.is_open())
512 XABORTM("Unable to open Vector file " + filename);
513 write_out(mode, file);
514 file.close();
515 }
516
523 void write_out(FileMode mode, std::ostream& file) const
524 {
525 switch(mode)
526 {
528 {
529 size_t gsize(2 * sizeof(std::uint64_t)); // magic_number and subvector count
530 std::vector<char> result(gsize);
531 char * array(result.data());
532 std::uint64_t * uiarray(reinterpret_cast<std::uint64_t *>(array));
533 uiarray[0] = 101;
534 uiarray[1] = num_blocks;
535
536 file.write(result.data(), long(result.size()));
537
538 _write_out_binary(file);
539 break;
540 }
541 default:
542 XABORTM("Filemode not supported!");
543 }
544 }
545 }; // class TupleVector<...>
546
548 template<typename First_>
549 class TupleVector<First_>
550 {
551 private:
552 template<typename,typename...>
553 friend class TupleVector;
554
556 void _read_from_binary(std::istream& file)
557 {
558 //process first
559 _first.read_from(FileMode::fm_binary, file);
560 }
561
563 void _write_out_binary(std::ostream& file) const
564 {
565 //process first
566 _first.write_out(FileMode::fm_binary, file);
567 }
568
569 public:
570 static constexpr int num_blocks = 1;
571
572 typedef typename First_::DataType DataType;
573 typedef typename First_::IndexType IndexType;
574
575 template <typename DT2_ = DataType, typename IT2_ = IndexType>
576 using ContainerType = TupleVector<typename First_::template ContainerType<DT2_, IT2_> >;
577
579 template <typename DataType2_, typename IndexType2_>
580 using ContainerTypeByDI = ContainerType<DataType2_, IndexType2_>;
581
582 protected:
583 First_ _first;
584
585 static String sub_name_list()
586 {
587 return First_::name();
588 }
589
590 public:
591 TupleVector()
592 {
593 }
594
595 explicit TupleVector(First_&& the_first) :
596 _first(std::forward<First_>(the_first))
597 {
598 }
599
601 TupleVector(TupleVector&& other) :
602 _first(std::forward<First_>(other._first))
603 {
604 }
605
607 TupleVector& operator=(TupleVector&& other)
608 {
609 if(this != &other)
610 {
611 _first = std::forward<First_>(other._first);
612 }
613 return *this;
614 }
615
617 TupleVector(const TupleVector&) = delete;
619 TupleVector& operator=(const TupleVector&) = delete;
620
628 TupleVector clone(LAFEM::CloneMode mode = LAFEM::CloneMode::Weak) const
629 {
630 return TupleVector(_first.clone(mode));
631 }
632
640 void clone(const TupleVector& other, CloneMode clone_mode)
641 {
642 _first.clone(other._first, clone_mode);
643 }
644
651 void clone(const TupleVector& other)
652 {
653 _first.clone(other._first);
654 }
655
656 First_& first()
657 {
658 return _first;
659 }
660
661 const First_& first() const
662 {
663 return _first;
664 }
665
667 std::uint64_t get_checkpoint_size(SerialConfig& config)
668 {
669 return _first.get_checkpoint_size(config);
670 }
671
673 void restore_from_checkpoint_data(std::vector<char> & data)
674 {
675 _first.restore_from_checkpoint_data(data);
676 }
677
679 std::uint64_t set_checkpoint_data(std::vector<char>& data, SerialConfig& config)
680 {
681 return _first.set_checkpoint_data(data, config);
682 }
683
684 template <Perspective perspective_ = Perspective::native>
685 Index size() const
686 {
687 return _first.template size<perspective_>();
688 }
689
691 int blocks() const
692 {
693 return num_blocks;
694 }
695
697 static String name()
698 {
699 return String("TupleVector<") + sub_name_list() + ">";
700 }
701
702 template<int i_>
703 typename TupleElement<i_, First_>::Type& at()
704 {
705 static_assert(i_ == 0, "invalid sub-vector index");
706 return first();
707 }
708
709 template<int i_>
710 typename TupleElement<i_, First_>::Type const& at() const
711 {
712 static_assert(i_ == 0, "invalid sub-vector index");
713 return first();
714 }
715
716 void format(DataType value = DataType(0))
717 {
718 _first.format(value);
719 }
720
721 void format(Random & rng, DataType min, DataType max)
722 {
723 first().format(rng, min, max);
724 }
725
726 void clear()
727 {
728 _first.clear();
729 }
730
731 //template<typename First2_>
732 void copy(const TupleVector/*<First2_>*/& x, bool full = false)
733 {
734 first().copy(x.first(), full);
735 }
736
737 void axpy(const TupleVector& x, DataType alpha = DataType(1))
738 {
739 first().axpy(x.first(), alpha);
740 }
741
742 void component_product(const TupleVector & x, const TupleVector & y)
743 {
744 first().component_product(x.first(), y.first());
745 }
746
747 void component_invert(const TupleVector& x, DataType alpha = DataType(1))
748 {
749 first().component_invert(x.first(), alpha);
750 }
751
752 void scale(const TupleVector& x, DataType alpha)
753 {
754 first().scale(x.first(), alpha);
755 }
756
757 DataType dot(const TupleVector& x) const
758 {
759 return first().dot(x.first());
760 }
761
762 DataType triple_dot(const TupleVector& x, const TupleVector& y) const
763 {
764 return first().triple_dot(x.first(), y.first());
765 }
766
767 DataType triple_dot_i(const TupleVector& x, const TupleVector& y) const
768 {
769 return first().triple_dot_i(x.first(), y.first());
770 }
771
772 DataType norm2sqr() const
773 {
774 return first().norm2sqr();
775 }
776
777 DataType norm2() const
778 {
779 return first().norm2();
780 }
781
783 {
784 return first().max_abs_element();
785 }
786
788 {
789 return first().min_abs_element();
790 }
791
792 DataType max_element() const
793 {
794 return first().max_element();
795 }
796
797 DataType min_element() const
798 {
799 return first().min_element();
800 }
801
802 const typename First_::DataType operator()(Index index) const
803 {
804 ASSERT(index < size());
805 return first()(index);
806 }
807
808 void operator()(Index index, typename First_::DataType value)
809 {
810 ASSERT(index < size());
811 first()(index, value);
812 }
813
814 void set_vec(DataType * const pval_set) const
815 {
816 this->first().set_vec(pval_set);
817 }
818
819 void set_vec_inv(const DataType * const pval_set)
820 {
821 this->first().set_vec_inv(pval_set);
822 }
823
831 template <typename First2_>
832 void convert(const TupleVector<First2_>& other)
833 {
834 this->first().convert(other.first());
835 }
836
838 std::size_t bytes() const
839 {
840 return _first.bytes();
841 }
842
849 void read_from(FileMode mode, const String& filename)
850 {
851 switch(mode)
852 {
854 read_from_binary(filename);
855 break;
856 default:
857 XABORTM("Filemode not supported!");
858 }
859 }
860
867 void read_from(FileMode mode, std::istream& file)
868 {
869 switch(mode)
870 {
872 read_from_binary(file);
873 break;
874 default:
875 XABORTM("Filemode not supported!");
876 }
877 }
878
884 void read_from_binary(const String& filename)
885 {
886 std::ifstream file(filename.c_str(), std::ifstream::in | std::ifstream::binary);
887 if (! file.is_open())
888 XABORTM("Unable to open Vector file " + filename);
889 read_from_binary(file);
890 file.close();
891 }
892
898 void read_from_binary(std::istream& file)
899 {
900 std::uint64_t magic; // magic_number
901 file.read((char *)&magic, (long)(sizeof(std::uint64_t)));
902 if (magic != 101)
903 XABORTM("Given file or file component is no TupleVector!");
904 std::uint64_t count; // subvector count
905 file.read((char *)&count, (long)(sizeof(std::uint64_t)));
906 if (count != 1)
907 XABORTM("PowerVector file read in component count mismatch: class has 1 - " + stringify(count) + " read in!");
908
909 _read_from_binary(file);
910 }
911
918 void write_out(FileMode mode, const String& filename) const
919 {
920 switch(mode)
921 {
923 write_out_binary(filename);
924 break;
925 default:
926 XABORTM("Filemode not supported!");
927 }
928 }
929
936 void write_out(FileMode mode, std::ostream& file) const
937 {
938 switch(mode)
939 {
941 write_out_binary(file);
942 break;
943 default:
944 XABORTM("Filemode not supported!");
945 }
946 }
947
953 void write_out_binary(const String& filename) const
954 {
955 std::ofstream file(filename.c_str(), std::ofstream::out | std::ofstream::binary);
956 if (! file.is_open())
957 XABORTM("Unable to open Vector file " + filename);
958 write_out_binary(file);
959 file.close();
960 }
961
969 void write_out_binary(std::ostream& file) const
970 {
971 size_t gsize(2 * sizeof(std::uint64_t)); // magic_number and subvector count
972 std::vector<char> result(gsize);
973 char * array(result.data());
974 std::uint64_t * uiarray(reinterpret_cast<std::uint64_t *>(array));
975 uiarray[0] = 101;
976 uiarray[1] = 1; //fixed num_blocks for tuple vector specialization
977
978 file.write(result.data(), long(result.size()));
979
980 _write_out_binary(file);
981 }
982 };
984
986 template <typename First_>
987 inline void dump_tuple_vector(std::ostream & os, const TupleVector<First_>& x)
988 {
989 os << x.first();
990 }
991
992 template <typename First_, typename... Rest_>
993 inline void dump_tuple_vector(std::ostream & os, const TupleVector<First_, Rest_...>& x)
994 {
995 os << x.first() << ",";
996 dump_tuple_vector<Rest_...>(os, x.rest());
997 }
998
999 template <typename First_, typename... Rest_>
1000 inline std::ostream& operator<< (std::ostream & os, const TupleVector<First_, Rest_...>& x)
1001 {
1002 os << "[";
1003 dump_tuple_vector(os, x);
1004 os << "]";
1005 return os;
1006 }
1008 } // namespace LAFEM
1009} // namespace FEAT
#define ASSERT(expr)
Debug-Assertion macro definition.
Definition: assertion.hpp:229
#define XABORTM(msg)
Abortion macro definition with custom message.
Definition: assertion.hpp:192
Config class for serialize parameter.
Definition: container.hpp:47
Variadic TupleVector class template.
void clone(const TupleVector &other)
Turns this vector into a clone of other.
TupleElement< i_, First_, Rest_... >::Type & at()
Returns a sub-vector block.
std::size_t bytes() const
Returns the total amount of bytes allocated.
DataType min_abs_element() const
Retrieve the absolute minimum value of this vector.
TupleElement< i_, First_, Rest_... >::Type const & at() const
Returns a sub-vector block.
DataType max_rel_diff(const TupleVector< First2_, Rest2_... > &x) const
Retrieve the maximum relative difference of this vector and another one y.max_rel_diff(x) returns .
int blocks() const
Returns the number of blocks in this tuple-vector.
void read_from(FileMode mode, const String &filename)
Read in vector from file.
void clone(const TupleVector &other, CloneMode clone_mode)
Turns this vector into a clone of other.
void write_out(FileMode mode, const String &filename) const
Write out vector to file.
std::uint64_t set_checkpoint_data(std::vector< char > &data, SerialConfig &config)
First_ _first
the first sub-vector
TupleVector(TupleVector &&other)
move ctor
void restore_from_checkpoint_data(std::vector< char > &data)
Extract object from checkpoint.
void copy(const TupleVector &x, bool full=false)
Performs .
void format(DataType value=DataType(0))
Reset all elements of the container to a given value or zero if missing.
void write_out(FileMode mode, std::ostream &file) const
Write out vector to file.
First_::DataType DataType
sub-vector data-type
RestClass _rest
all remaining sub-vectors
void convert(const TupleVector< First2_, Rest2_... > &other)
Conversion method.
TupleVector(const TupleVector &)=delete
deleted copy-ctor
TupleVector< typename First_::template ContainerType< DT2_, IT2_ >, typename Rest_::template ContainerType< DT2_, IT2_ >... > ContainerType
Our 'base' class type.
DataType max_element() const
Retrieve the maximum value of this vector.
TupleVector(First_ &&the_first, Rest_ &&... the_rest)
Sub-Vector emplacement constructor.
void _write_out_binary(std::ostream &file) const
write binary data of _first and _rest to file.
void _read_from_binary(std::istream &file)
read binary data of _first and _rest to file.
DataType min_element() const
Retrieve the minimum value of this vector.
DataType triple_dot(const TupleVector &x, const TupleVector &y) const
Calculate .
TupleVector(First_ &&the_first, RestClass &&the_rest)
rest-class emplacement ctor; for internal use only
void clear()
Free all allocated arrays.
TupleVector clone(LAFEM::CloneMode mode=LAFEM::CloneMode::Weak) const
Creates and returns a copy of this vector.
std::uint64_t get_checkpoint_size(SerialConfig &config)
Calculate size.
void format(Random &rng, DataType min, DataType max)
Reset all elements of the container to random values.
First_::IndexType IndexType
sub-vector index-type
TupleVector & operator=(const TupleVector &)=delete
deleted copy-assign operator
static String sub_name_list()
Returns a list of all sub-vector type names.
DataType max_abs_element() const
Retrieve the absolute maximum value of this vector.
void read_from(FileMode mode, std::istream &file)
Read in vector from stream.
static String name()
Returns a descriptive string for this container.
Index size() const
Returns the total size of this tuple-vector.
TupleVector & operator=(TupleVector &&other)
move-assign operator
ContainerType< DataType2_, IndexType2_ > ContainerTypeByDI
this typedef lets you create a vector container with different Data and Index types
static constexpr int num_blocks
number of vector blocks
Pseudo-Random Number Generator.
Definition: random.hpp:54
String class implementation.
Definition: string.hpp:46
@ other
generic/other permutation strategy
T_ sqrt(T_ x)
Returns the square-root of a value.
Definition: math.hpp:300
T_ min(T_ a, T_ b)
Returns the minimum of two values.
Definition: math.hpp:123
T_ max(T_ a, T_ b)
Returns the maximum of two values.
Definition: math.hpp:137
@ rest
restriction (multigrid)
FEAT namespace.
Definition: adjactor.hpp:12
String stringify(const T_ &item)
Converts an item into a String.
Definition: string.hpp:944
@ value
specifies whether the space should supply basis function values
std::uint64_t Index
Index data type.
Tuple container element helper class template.