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
547 void dump(std::ostream& os) const
548 {
549 os << this->first() << ",";
550 this->rest().dump(os);
551 }
552 }; // class TupleVector<...>
553
555 template<typename First_>
556 class TupleVector<First_>
557 {
558 private:
559 template<typename,typename...>
560 friend class TupleVector;
561
563 void _read_from_binary(std::istream& file)
564 {
565 //process first
566 _first.read_from(FileMode::fm_binary, file);
567 }
568
570 void _write_out_binary(std::ostream& file) const
571 {
572 //process first
573 _first.write_out(FileMode::fm_binary, file);
574 }
575
576 public:
577 static constexpr int num_blocks = 1;
578
579 typedef typename First_::DataType DataType;
580 typedef typename First_::IndexType IndexType;
581
582 template <typename DT2_ = DataType, typename IT2_ = IndexType>
583 using ContainerType = TupleVector<typename First_::template ContainerType<DT2_, IT2_> >;
584
586 template <typename DataType2_, typename IndexType2_>
587 using ContainerTypeByDI = ContainerType<DataType2_, IndexType2_>;
588
589 protected:
590 First_ _first;
591
592 static String sub_name_list()
593 {
594 return First_::name();
595 }
596
597 public:
598 TupleVector()
599 {
600 }
601
602 explicit TupleVector(First_&& the_first) :
603 _first(std::forward<First_>(the_first))
604 {
605 }
606
608 TupleVector(TupleVector&& other) :
609 _first(std::forward<First_>(other._first))
610 {
611 }
612
614 TupleVector& operator=(TupleVector&& other)
615 {
616 if(this != &other)
617 {
618 _first = std::forward<First_>(other._first);
619 }
620 return *this;
621 }
622
624 TupleVector(const TupleVector&) = delete;
626 TupleVector& operator=(const TupleVector&) = delete;
627
635 TupleVector clone(LAFEM::CloneMode mode = LAFEM::CloneMode::Weak) const
636 {
637 return TupleVector(_first.clone(mode));
638 }
639
647 void clone(const TupleVector& other, CloneMode clone_mode)
648 {
649 _first.clone(other._first, clone_mode);
650 }
651
658 void clone(const TupleVector& other)
659 {
660 _first.clone(other._first);
661 }
662
663 First_& first()
664 {
665 return _first;
666 }
667
668 const First_& first() const
669 {
670 return _first;
671 }
672
674 std::uint64_t get_checkpoint_size(SerialConfig& config)
675 {
676 return _first.get_checkpoint_size(config);
677 }
678
680 void restore_from_checkpoint_data(std::vector<char> & data)
681 {
682 _first.restore_from_checkpoint_data(data);
683 }
684
686 std::uint64_t set_checkpoint_data(std::vector<char>& data, SerialConfig& config)
687 {
688 return _first.set_checkpoint_data(data, config);
689 }
690
691 template <Perspective perspective_ = Perspective::native>
692 Index size() const
693 {
694 return _first.template size<perspective_>();
695 }
696
698 int blocks() const
699 {
700 return num_blocks;
701 }
702
704 static String name()
705 {
706 return String("TupleVector<") + sub_name_list() + ">";
707 }
708
709 template<int i_>
710 typename TupleElement<i_, First_>::Type& at()
711 {
712 static_assert(i_ == 0, "invalid sub-vector index");
713 return first();
714 }
715
716 template<int i_>
717 typename TupleElement<i_, First_>::Type const& at() const
718 {
719 static_assert(i_ == 0, "invalid sub-vector index");
720 return first();
721 }
722
723 void format(DataType value = DataType(0))
724 {
725 _first.format(value);
726 }
727
728 void format(Random & rng, DataType min, DataType max)
729 {
730 first().format(rng, min, max);
731 }
732
733 void clear()
734 {
735 _first.clear();
736 }
737
738 //template<typename First2_>
739 void copy(const TupleVector/*<First2_>*/& x, bool full = false)
740 {
741 first().copy(x.first(), full);
742 }
743
744 void axpy(const TupleVector& x, DataType alpha = DataType(1))
745 {
746 first().axpy(x.first(), alpha);
747 }
748
749 void component_product(const TupleVector & x, const TupleVector & y)
750 {
751 first().component_product(x.first(), y.first());
752 }
753
754 void component_invert(const TupleVector& x, DataType alpha = DataType(1))
755 {
756 first().component_invert(x.first(), alpha);
757 }
758
759 void scale(const TupleVector& x, DataType alpha)
760 {
761 first().scale(x.first(), alpha);
762 }
763
764 DataType dot(const TupleVector& x) const
765 {
766 return first().dot(x.first());
767 }
768
769 DataType triple_dot(const TupleVector& x, const TupleVector& y) const
770 {
771 return first().triple_dot(x.first(), y.first());
772 }
773
774 DataType triple_dot_i(const TupleVector& x, const TupleVector& y) const
775 {
776 return first().triple_dot_i(x.first(), y.first());
777 }
778
779 DataType norm2sqr() const
780 {
781 return first().norm2sqr();
782 }
783
784 DataType norm2() const
785 {
786 return first().norm2();
787 }
788
790 {
791 return first().max_abs_element();
792 }
793
795 {
796 return first().min_abs_element();
797 }
798
799 DataType max_element() const
800 {
801 return first().max_element();
802 }
803
804 DataType min_element() const
805 {
806 return first().min_element();
807 }
808
809 const typename First_::DataType operator()(Index index) const
810 {
811 ASSERT(index < size());
812 return first()(index);
813 }
814
815 void operator()(Index index, typename First_::DataType value)
816 {
817 ASSERT(index < size());
818 first()(index, value);
819 }
820
821 void set_vec(DataType * const pval_set) const
822 {
823 this->first().set_vec(pval_set);
824 }
825
826 void set_vec_inv(const DataType * const pval_set)
827 {
828 this->first().set_vec_inv(pval_set);
829 }
830
838 template <typename First2_>
839 void convert(const TupleVector<First2_>& other)
840 {
841 this->first().convert(other.first());
842 }
843
845 std::size_t bytes() const
846 {
847 return _first.bytes();
848 }
849
856 void read_from(FileMode mode, const String& filename)
857 {
858 switch(mode)
859 {
861 read_from_binary(filename);
862 break;
863 default:
864 XABORTM("Filemode not supported!");
865 }
866 }
867
874 void read_from(FileMode mode, std::istream& file)
875 {
876 switch(mode)
877 {
879 read_from_binary(file);
880 break;
881 default:
882 XABORTM("Filemode not supported!");
883 }
884 }
885
891 void read_from_binary(const String& filename)
892 {
893 std::ifstream file(filename.c_str(), std::ifstream::in | std::ifstream::binary);
894 if (! file.is_open())
895 XABORTM("Unable to open Vector file " + filename);
896 read_from_binary(file);
897 file.close();
898 }
899
905 void read_from_binary(std::istream& file)
906 {
907 std::uint64_t magic; // magic_number
908 file.read((char *)&magic, (long)(sizeof(std::uint64_t)));
909 if (magic != 101)
910 XABORTM("Given file or file component is no TupleVector!");
911 std::uint64_t count; // subvector count
912 file.read((char *)&count, (long)(sizeof(std::uint64_t)));
913 if (count != 1)
914 XABORTM("PowerVector file read in component count mismatch: class has 1 - " + stringify(count) + " read in!");
915
916 _read_from_binary(file);
917 }
918
925 void write_out(FileMode mode, const String& filename) const
926 {
927 switch(mode)
928 {
930 write_out_binary(filename);
931 break;
932 default:
933 XABORTM("Filemode not supported!");
934 }
935 }
936
943 void write_out(FileMode mode, std::ostream& file) const
944 {
945 switch(mode)
946 {
948 write_out_binary(file);
949 break;
950 default:
951 XABORTM("Filemode not supported!");
952 }
953 }
954
960 void write_out_binary(const String& filename) const
961 {
962 std::ofstream file(filename.c_str(), std::ofstream::out | std::ofstream::binary);
963 if (! file.is_open())
964 XABORTM("Unable to open Vector file " + filename);
965 write_out_binary(file);
966 file.close();
967 }
968
976 void write_out_binary(std::ostream& file) const
977 {
978 size_t gsize(2 * sizeof(std::uint64_t)); // magic_number and subvector count
979 std::vector<char> result(gsize);
980 char * array(result.data());
981 std::uint64_t * uiarray(reinterpret_cast<std::uint64_t *>(array));
982 uiarray[0] = 101;
983 uiarray[1] = 1; //fixed num_blocks for tuple vector specialization
984
985 file.write(result.data(), long(result.size()));
986
987 _write_out_binary(file);
988 }
989
991 void dump(std::ostream& os) const
992 {
993 os << this->first();
994 }
995 };
996
997 template <typename First_, typename... Rest_>
998 inline std::ostream& operator<< (std::ostream & os, const TupleVector<First_, Rest_...>& x)
999 {
1000 os << "[";
1001 x.dump(os);
1002 os << "]";
1003 return os;
1004 }
1006 } // namespace LAFEM
1007} // 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
void dump(std::ostream &os) const
auxiliary function for operator<< implementation
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:47
@ 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:993
@ value
specifies whether the space should supply basis function values
std::uint64_t Index
Index data type.
Tuple container element helper class template.