FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
power_diag_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// includes, FEAT
9#include <kernel/lafem/power_vector.hpp>
10#include <kernel/lafem/sparse_layout.hpp>
11#include <kernel/lafem/meta_element.hpp>
12#include <kernel/lafem/container.hpp>
13
14
15namespace FEAT
16{
17 namespace LAFEM
18 {
33 template<
34 typename SubType_,
35 int blocks_>
37 {
38 // Note: the case = 1 is specialized below
39 static_assert(blocks_ > 1, "invalid block size");
40
41 // declare this class template as a friend for recursive inheritance
42 template<typename, int>
43 friend class PowerDiagMatrix;
44
46 typedef PowerDiagMatrix<SubType_, blocks_-1> RestClass;
47
48 public:
50 typedef SubType_ SubMatrixType;
52 typedef typename SubMatrixType::DataType DataType;
54 typedef typename SubMatrixType::IndexType IndexType;
56 static constexpr SparseLayoutId layout_id = SubMatrixType::layout_id;
62 template <typename DT2_ = DataType, typename IT2_ = IndexType>
64
66 template <typename DataType2_, typename IndexType2_>
68
70 static constexpr int num_row_blocks = blocks_;
72 static constexpr int num_col_blocks = blocks_;
73
74 protected:
79
81 explicit PowerDiagMatrix(SubMatrixType&& the_first, RestClass&& the_rest) :
82 _first(std::move(the_first)),
83 _rest(std::move(the_rest))
84 {
85 }
86
87 public:
90 {
91 }
92
95 _first(layout),
96 _rest(layout)
97 {
98 }
99
102 _first(std::move(other._first)),
103 _rest(std::move(other._rest))
104 {
105 }
106
115 explicit PowerDiagMatrix(FileMode mode, String filename)
116 {
117 read_from(mode, filename);
118 }
119
130 explicit PowerDiagMatrix(FileMode mode, std::istream& file, String directory = "")
131 {
132 String line;
133 do {
134 if (file.eof())
135 XABORTM("Wrong Input-file");
136 std::getline(file, line);
137 line.trim_me();
138 } while (line.find("%%") == 0 || line == "");
139
140 SubMatrixType tmp_first(mode, directory + line);
141 _first = std::move(tmp_first);
142
143 RestClass tmp_rest(mode, file, directory);
144 _rest = std::move(tmp_rest);
145 }
146
153 void read_from(FileMode mode, String filename)
154 {
155 String directory;
156 auto found = filename.rfind("/");
157 if (found != std::string::npos)
158 {
159 directory = filename.substr(0, found + 1);
160 }
161
162 std::ifstream file(filename.c_str(), std::ifstream::in);
163 if (! file.is_open())
164 XABORTM("Unable to open Matrix file " + filename);
165
166 String line;
167 std::getline(file, line);
168 if (line.find("%%MatrixMarket powerdiagmatrix coordinate real general") == String::npos)
169 XABORTM("Input-file is not a complatible file");
170
171 PowerDiagMatrix other(mode, file, directory);
172
173 _first = std::move(other._first);
174 _rest = std::move(other._rest);
175
176 file.close();
177 }
178
181 {
182 if(this != &other)
183 {
184 _first = std::move(other._first);
185 _rest = std::move(other._rest);
186 }
187 return *this;
188 }
189
194
197 {
198 }
199
206 void write_out(FileMode mode, String filename) const
207 {
208 std::ofstream file(filename.c_str(), std::ofstream::out);
209 if (! file.is_open())
210 XABORTM("Unable to open Matrix file " + filename);
211
212 String suffix, directory;
213 auto found = filename.rfind(".");
214 if (found != std::string::npos)
215 {
216 suffix = filename.substr(found);
217 filename.erase(found);
218 }
219 found = filename.rfind("/");
220 if (found != std::string::npos)
221 {
222 directory = filename.substr(0, found + 1);
223 filename.erase(0, found + 1);
224 }
225
226 file << "%%MatrixMarket powerdiagmatrix coordinate real general\n";
227 for (Index i(1); i <= blocks_; ++i)
228 {
229 file << filename << "_pd" << i << suffix << "\n";
230 }
231
232 file.close();
233
234 this->write_out_submatrices(mode, directory, filename, suffix);
235 }
236
245 void write_out_submatrices(FileMode mode, String directory, String prefix, String suffix, Index length = blocks_) const
246 {
247 _first.write_out(mode, directory + prefix + "_pd" + stringify(length + 1 - blocks_) + suffix);
248 _rest.write_out_submatrices(mode, directory, prefix, suffix, length);
249 }
250
255 {
256 return PowerDiagMatrix(_first.clone(mode), _rest.clone(mode));
257 }
258
267 void clone(const PowerDiagMatrix & other, CloneMode clone_mode = CloneMode::Weak)
268 {
269 (*this)=other.clone(clone_mode);
270 }
271
273 std::size_t bytes() const
274 {
275 return _first.bytes() + _rest.bytes();
276 }
277
282 {
283 return PowerDiagMatrix(_first.transpose(), _rest.transpose());
284 }
285
298 template<int i_, int j_>
300 {
301 static_assert(i_ == j_, "invalid sub-matrix index");
302 static_assert((0 <= i_) && (i_ < blocks_), "invalid sub-matrix index");
304 }
305
307 template<int i_, int j_>
308 const SubMatrixType& at() const
309 {
310 static_assert(i_ == j_, "invalid sub-matrix index");
311 static_assert((0 <= i_) && (i_ < blocks_), "invalid sub-matrix index");
313 }
314
324 SubMatrixType& get(int i, int j)
325 {
326 XASSERTM((i == j) && (0 <= i) && (i < blocks_), "invalid sub-matrix index");
327 return (i == 0) ? _first : _rest.get(i-1, j-1);
328 }
329
331 const SubMatrixType& get(int i, int j) const
332 {
333 XASSERTM((i == j) && (0 <= i) && (i < blocks_), "invalid sub-matrix index");
334 return (i == 0) ? _first : _rest.get(i-1, j-1);
335 }
336
338 std::uint64_t get_checkpoint_size(SerialConfig& config)
339 {
340 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
341 }
342
344 void restore_from_checkpoint_data(std::vector<char> & data)
345 {
346 std::uint64_t isize = *(std::uint64_t*) data.data(); //get size of checkpointed _first
347 std::vector<char>::iterator start = std::begin(data) + sizeof(std::uint64_t);
348 std::vector<char>::iterator last_of_first = std::begin(data) + sizeof(std::uint64_t) + (int) isize;
349 std::vector<char> buffer_first(start, last_of_first);
350 _first.restore_from_checkpoint_data(buffer_first);
351
352 data.erase(std::begin(data), last_of_first);
354 }
355
357 std::uint64_t set_checkpoint_data(std::vector<char>& data, SerialConfig& config)
358 {
359 std::size_t old_size = data.size();
360 data.insert(std::end(data), sizeof(std::uint64_t), 0); //add placeholder
361 std::uint64_t ireal_size = _first.set_checkpoint_data(data, config); //add data of _first to the overall checkpoint and save its size
362 char* csize = reinterpret_cast<char*>(&ireal_size);
363 for(std::size_t i(0) ; i < sizeof(std::uint64_t) ; ++i) //overwrite the guessed datalength
364 {
365 data[old_size + i] = csize[i];
366 }
367
368 return sizeof(std::uint64_t) + ireal_size + _rest.set_checkpoint_data(data, config); //generate and add checkpoint data for the _rest
369 }
370
372 SubMatrixType& first()
373 {
374 return _first;
375 }
376
377 const SubMatrixType& first() const
378 {
379 return _first;
380 }
381
382 RestClass& rest()
383 {
384 return _rest;
385 }
386
387 const RestClass& rest() const
388 {
389 return _rest;
390 }
391
392 int row_blocks() const
393 {
394 return num_row_blocks;
395 }
396
397 int col_blocks() const
398 {
399 return num_col_blocks;
400 }
402
409 template <Perspective perspective_ = Perspective::native>
410 Index rows() const
411 {
412 return first().template rows<perspective_>() + rest().template rows<perspective_>();
413 }
414
421 template <Perspective perspective_ = Perspective::native>
423 {
424 return first().template columns<perspective_>() + rest().template columns<perspective_>();
425 }
426
433 template <Perspective perspective_ = Perspective::native>
435 {
436 return first().template used_elements<perspective_>() + rest().template used_elements<perspective_>();
437 }
438
440 static String name()
441 {
442 return String("PowerDiagMatrix<") + SubMatrixType::name() + "," + stringify(blocks_) + ">";
443 }
444
445 Index size() const
446 {
447 return rows() * columns();
448 }
449
457 {
458 first().format(value);
459 rest().format(value);
460 }
461
465 void clear()
466 {
467 first().clear();
468 rest().clear();
469 }
470
472 void extract_diag(VectorTypeL& diag) const
473 {
474 first().extract_diag(diag.first());
475 rest().extract_diag(diag.rest());
476 }
477
490 void apply(VectorTypeL& r, const VectorTypeR& x) const
491 {
492 first().apply(r.first(), x.first());
493 rest().apply(r.rest(), x.rest());
494 }
495
497 {
498 XASSERTM(r.size() == this->rows(), "Vector size of r does not match!");
499 XASSERTM(x.size() == this->columns(), "Vector size of x does not match!");
500
501 DenseVector<DataType, IndexType> r_first(r, first().rows(), 0);
502 DenseVector<DataType, IndexType> r_rest(r, rest().rows(), first().rows());
503
504 DenseVector<DataType, IndexType> x_first(x, first().columns(), 0);
505 DenseVector<DataType, IndexType> x_rest(x, rest().columns(), first().columns());
506
507 first().apply(r_first, x_first);
508 rest().apply(r_rest, x_rest);
509 }
510
523 void apply_transposed(VectorTypeR& r, const VectorTypeL& x) const
524 {
525 first().apply_transposed(r.first(), x.first());
526 rest().apply_transposed(r.rest(), x.rest());
527 }
528
530 {
531 XASSERTM(r.size() == this->columns(), "Vector size of r does not match!");
532 XASSERTM(x.size() == this->rows(), "Vector size of x does not match!");
533
534 DenseVector<DataType, IndexType> r_first(r, first().columns(), 0);
535 DenseVector<DataType, IndexType> r_rest(r, rest().columns(), first().columns());
536
537 DenseVector<DataType, IndexType> x_first(x, first().rows(), 0);
538 DenseVector<DataType, IndexType> x_rest(x, rest().rows(), first().rows());
539
540 first().apply_transposed(r_first, x_first);
541 rest().apply_transposed(r_rest, x_rest);
542 }
543
560 void apply(VectorTypeL& r, const VectorTypeR& x, const VectorTypeL& y, DataType alpha = DataType(1)) const
561 {
562 first().apply(r.first(), x.first(), y.first(), alpha);
563 rest().apply(r.rest(), x.rest(), y.rest(), alpha);
564 }
565
567 const DenseVector<DataType, IndexType>& y, DataType alpha = DataType(1)) const
568 {
569 XASSERTM(r.size() == this->rows(), "Vector size of r does not match!");
570 XASSERTM(x.size() == this->columns(), "Vector size of x does not match!");
571 XASSERTM(y.size() == this->rows(), "Vector size of y does not match!");
572
573 DenseVector<DataType, IndexType> r_first(r, first().rows(), 0);
574 DenseVector<DataType, IndexType> r_rest(r, rest().rows(), first().rows());
575
576 DenseVector<DataType, IndexType> x_first(x, first().columns(), 0);
577 DenseVector<DataType, IndexType> x_rest(x, rest().columns(), first().columns());
578
579 DenseVector<DataType, IndexType> y_first(y, first().rows(), 0);
580 DenseVector<DataType, IndexType> y_rest(y, rest().rows(), first().rows());
581
582 first().apply(r_first, x_first, y_first, alpha);
583 rest().apply(r_rest, x_rest, y_rest, alpha);
584 }
585
602 void apply_transposed(VectorTypeR& r, const VectorTypeL& x, const VectorTypeR& y, DataType alpha = DataType(1)) const
603 {
604 first().apply_transposed(r.first(), x.first(), y.first(), alpha);
605 rest().apply_transposed(r.rest(), x.rest(), y.rest(), alpha);
606 }
607
609 const DenseVector<DataType, IndexType>& y, DataType alpha = DataType(1)) const
610 {
611 XASSERTM(r.size() == this->columns(), "Vector size of r does not match!");
612 XASSERTM(x.size() == this->rows(), "Vector size of x does not match!");
613 XASSERTM(y.size() == this->columns(), "Vector size of y does not match!");
614
615 DenseVector<DataType, IndexType> r_first(r, first().columns(), 0);
616 DenseVector<DataType, IndexType> r_rest(r, rest().columns(), first().columns());
617
618 DenseVector<DataType, IndexType> x_first(x, first().rows(), 0);
619 DenseVector<DataType, IndexType> x_rest(x, rest().rows(), first().rows());
620
621 DenseVector<DataType, IndexType> y_first(y, first().columns(), 0);
622 DenseVector<DataType, IndexType> y_rest(y, rest().columns(), first().columns());
623
624 first().apply_transposed(r_first, x_first, y_first, alpha);
625 rest().apply_transposed(r_rest, x_rest, y_rest, alpha);
626 }
627
635 {
636 DataType max_rel_diff = Math::max(this->first().max_rel_diff(x.first()), this->rest().max_rel_diff(x.rest()));
637 return max_rel_diff;
638 }
639
648 bool same_layout(const PowerDiagMatrix& x) const
649 {
650 return (this->name() == x.name()) && (this->first().same_layout(x.first())) && (this->rest().same_layout(x.rest()));
651 }
652
655 {
656 return VectorTypeL(first().create_vector_l(), rest().create_vector_l());
657 }
658
661 {
662 return VectorTypeR(first().create_vector_r(), rest().create_vector_r());
663 }
664
665 void scale_rows(const PowerDiagMatrix& a, const VectorTypeL& w)
666 {
667 first().scale_rows(a.first(), w.first());
668 rest().scale_rows(a.rest(), w.rest());
669 }
670
671 void scale_cols(const PowerDiagMatrix& a, const VectorTypeR& w)
672 {
673 first().scale_cols(a.first(), w.first());
674 rest().scale_cols(a.rest(), w.rest());
675 }
676
679 {
680 const Index brows(this->first().template rows<Perspective::pod>());
681
682 if (row < brows)
683 {
684 return this->first().get_length_of_line(row);
685 }
686 else
687 {
688 return this->rest().get_length_of_line(row - brows);
689 }
690 }
691
694 void set_line(const Index row, DataType * const pval_set, IndexType * const pcol_set,
695 const Index col_start, const Index stride = 1) const
696 {
697 const Index brows(this->first().template rows<Perspective::pod>());
698 const Index bcolumns(this->first().template columns<Perspective::pod>());
699
700 if (row < brows)
701 {
702 this->first().set_line(row, pval_set, pcol_set, col_start, stride);
703 }
704 else
705 {
706 this->rest().set_line(row - brows, pval_set, pcol_set, col_start + bcolumns, stride);
707 }
708 }
709
710 void set_line_reverse(const Index row, const DataType * const pval_set, const Index stride = 1)
711 {
712 const Index brows(this->first().template rows<Perspective::pod>());
713
714 if (row < brows)
715 {
716 this->first().set_line_reverse(row, pval_set, stride);
717 }
718 else
719 {
720 this->rest().set_line_reverse(row - brows, pval_set, stride);
721 }
722 }
723
724 Index row_degree(const Index row) const
725 {
726 const Index first_rows = first().template rows<Perspective::pod>();
727 if(row < first_rows)
728 return first().row_degree(row);
729 else
730 return rest().row_degree(row - first_rows);
731 }
732
733 template<typename IT2_>
734 Index get_row_col_indices(const Index row, IT2_* const pcol_idx, const IT2_ col_offset) const
735 {
736 const Index first_rows = first().template rows<Perspective::pod>();
737 const Index first_cols = first().template columns<Perspective::pod>();
738 if(row < first_rows)
739 return first().get_row_col_indices(row, pcol_idx, col_offset);
740 else
741 return rest().get_row_col_indices(row - first_rows, pcol_idx, col_offset + IT2_(first_cols));
742 }
743
744 template<typename DT2_>
745 Index get_row_values(const Index row, DT2_ * const pvals) const
746 {
747 const Index first_rows = first().template rows<Perspective::pod>();
748 if(row < first_rows)
749 return first().get_row_values(row, pvals);
750 else
751 return rest().get_row_values(row - first_rows, pvals);
752 }
753
754 template<typename DT2_>
755 Index set_row_values(const Index row, const DT2_ * const pvals)
756 {
757 const Index first_rows = first().template rows<Perspective::pod>();
758 if(row < first_rows)
759 return first().set_row_values(row, pvals);
760 else
761 return rest().set_row_values(row - first_rows, pvals);
762 }
763
765
773 template <typename SubType2_>
775 {
776 this->first().convert(other.first());
777 this->rest().convert(other.rest());
778 }
779
780 template <typename SubType2_>
781 void convert_reverse(PowerDiagMatrix<SubType2_, blocks_> & other) const
782 {
783 this->first().convert_reverse(other.first());
784 this->rest().convert_reverse(other.rest());
785 }
786 };
787
789 template<typename SubType_>
790 class PowerDiagMatrix<SubType_, 1>
791 {
792 template<typename, int>
793 friend class PowerDiagMatrix;
794
795 public:
796 typedef SubType_ SubMatrixType;
797 typedef typename SubMatrixType::DataType DataType;
798 typedef typename SubMatrixType::IndexType IndexType;
800 static constexpr SparseLayoutId layout_id = SubMatrixType::layout_id;
802 typedef PowerVector<typename SubMatrixType::VectorTypeL, 1> VectorTypeL;
804 typedef PowerVector<typename SubMatrixType::VectorTypeR, 1> VectorTypeR;
806 template <typename DT2_ = DataType, typename IT2_ = IndexType>
807 using ContainerType = PowerDiagMatrix<typename SubType_::template ContainerType<DT2_, IT2_>, 1>;
808
810 template <typename DataType2_, typename IndexType2_>
811 using ContainerTypeByDI = ContainerType<DataType2_, IndexType2_>;
812
813 static constexpr int num_row_blocks = 1;
814 static constexpr int num_col_blocks = 1;
815
816 protected:
818
820 explicit PowerDiagMatrix(SubMatrixType&& the_first) :
821 _first(std::move(the_first))
822 {
823 }
824
825 public:
827 PowerDiagMatrix()
828 {
829 }
830
832 explicit PowerDiagMatrix(const SparseLayout<IndexType, layout_id>& layout) :
833 _first(layout)
834 {
835 }
836
838 PowerDiagMatrix(PowerDiagMatrix&& other) :
839 _first(std::move(other._first))
840 {
841 }
842
844 PowerDiagMatrix& operator=(PowerDiagMatrix&& other)
845 {
846 if(this != &other)
847 {
848 _first = std::move(other._first);
849 }
850 return *this;
851 }
852
854 explicit PowerDiagMatrix(FileMode mode, const String& filename)
855 {
856 read_from(mode, filename);
857 }
858
860 explicit PowerDiagMatrix(FileMode mode, std::istream& file, const String& directory = "")
861 {
862 String line;
863 do {
864 if (file.eof())
865 XABORTM("Wrong Input-file");
866 std::getline(file, line);
867 line.trim_me();
868 } while (line.find("%%") == 0 || line == "");
869
870 SubMatrixType tmp_first(mode, directory + line);
871 _first = std::move(tmp_first);
872 }
873
874 void read_from(FileMode mode, const String& filename)
875 {
876 String directory;
877 auto found = filename.rfind("/");
878 if (found != std::string::npos)
879 {
880 directory = filename.substr(0, found + 1);
881 }
882
883 std::ifstream file(filename.c_str(), std::ifstream::in);
884 if (! file.is_open())
885 XABORTM("Unable to open Matrix file " + filename);
886
887 PowerDiagMatrix other(mode, file, directory);
888
889 _first = std::move(other._first);
890
891 file.close();
892 }
893
895 PowerDiagMatrix(const PowerDiagMatrix&) = delete;
897 PowerDiagMatrix& operator=(const PowerDiagMatrix&) = delete;
898
900 virtual ~PowerDiagMatrix()
901 {
902 }
903
904 void write_out(FileMode mode, String filename) const
905 {
906 std::ofstream file(filename.c_str(), std::ofstream::out);
907 if (! file.is_open())
908 XABORTM("Unable to open Matrix file " + filename);
909
910 String suffix, directory;
911 auto found = filename.rfind(".");
912 if (found != std::string::npos)
913 {
914 suffix = filename.substr(found);
915 filename.erase(found);
916 }
917 found = filename.rfind("/");
918 if (found != std::string::npos)
919 {
920 directory = filename.substr(0, found + 1);
921 filename.erase(0, found + 1);
922 }
923
924 file << "%%MatrixMarket powerdiagmatrix coordinate real general\n";
925 file << filename << "_pd" << 1 << suffix << "\n";
926
927 file.close();
928
929 this->write_out_submatrices(mode, directory, filename, suffix);
930 }
931
932 void write_out_submatrices(FileMode mode, const String& directory, const String& prefix, const String& suffix, Index length = 1) const
933 {
934 _first.write_out(mode, directory + prefix + "_pd" + stringify(length) + suffix);
935 }
936
937 PowerDiagMatrix clone(LAFEM::CloneMode mode = LAFEM::CloneMode::Weak) const
938 {
939 return PowerDiagMatrix(_first.clone(mode));
940 }
941
942 void clone(const PowerDiagMatrix & other, CloneMode clone_mode = CloneMode::Weak)
943 {
944 (*this)=other.clone(clone_mode);
945 }
946
948 std::size_t bytes() const
949 {
950 return _first.bytes();
951 }
952
953 PowerDiagMatrix transpose() const
954 {
955 return PowerDiagMatrix(_first.transpose());
956 }
957
958 template<int i, int j>
960 {
961 static_assert(i == 0, "invalid sub-matrix index");
962 static_assert(j == 0, "invalid sub-matrix index");
963 return _first;
964 }
965
966 template<int i, int j>
967 const SubMatrixType& at() const
968 {
969 static_assert(i == 0, "invalid sub-matrix index");
970 static_assert(j == 0, "invalid sub-matrix index");
971 return _first;
972 }
973
974 SubMatrixType& get(int i, int j)
975 {
976 XASSERTM((i == 0) && (j == 0), "invalid sub-matrix index");
977 return _first;
978 }
979
980 const SubMatrixType& get(int i, int j) const
981 {
982 XASSERTM((i == 0) && (j == 0), "invalid sub-matrix index");
983 return _first;
984 }
985
987 std::uint64_t get_checkpoint_size(SerialConfig& config)
988 {
989 return _first.get_checkpoint_size(config);
990 }
991
993 void restore_from_checkpoint_data(std::vector<char> & data)
994 {
995 _first.restore_from_checkpoint_data(data);
996 }
997
999 std::uint64_t set_checkpoint_data(std::vector<char>& data, SerialConfig& config)
1000 {
1001 return _first.set_checkpoint_data(data, config);
1002 }
1003
1004 SubMatrixType& first()
1005 {
1006 return _first;
1007 }
1008
1009 const SubMatrixType& first() const
1010 {
1011 return _first;
1012 }
1013
1014 int row_blocks() const
1015 {
1016 return 1;
1017 }
1018
1019 int col_blocks() const
1020 {
1021 return 1;
1022 }
1023
1024 template <Perspective perspective_ = Perspective::native>
1025 Index rows() const
1026 {
1027 return first().template rows<perspective_>();
1028 }
1029
1030 template <Perspective perspective_ = Perspective::native>
1031 Index columns() const
1032 {
1033 return first().template columns<perspective_>();
1034 }
1035
1036 template <Perspective perspective_ = Perspective::native>
1037 Index used_elements() const
1038 {
1039 return first().template used_elements<perspective_>();
1040 }
1041
1042 static String name()
1043 {
1044 return String("PowerDiagMatrix<") + SubMatrixType::name() + "," + stringify(1) + ">";
1045 }
1046
1047 template <Perspective perspective_ = Perspective::native>
1048 Index size() const
1049 {
1050 return rows<perspective_>() * columns<perspective_>();
1051 }
1052
1053 void format(DataType value = DataType(0))
1054 {
1055 first().format(value);
1056 }
1057
1058 void clear()
1059 {
1060 first().clear();
1061 }
1062
1063 void extract_diag(VectorTypeL& diag) const
1064 {
1065 first().extract_diag(diag.first());
1066 }
1067
1068 void apply(VectorTypeL& r, const VectorTypeR& x) const
1069 {
1070 first().apply(r.first(), x.first());
1071 }
1072
1073 void apply(DenseVector<DataType, IndexType>& r, const DenseVector<DataType, IndexType>& x) const
1074 {
1075 first().apply(r, x);
1076 }
1077
1078 void apply(VectorTypeL& r, const VectorTypeR& x, const VectorTypeL& y, DataType alpha = DataType(1)) const
1079 {
1080 first().apply(r.first(), x.first(), y.first(), alpha);
1081 }
1082
1083 void apply(DenseVector<DataType, IndexType>& r, const DenseVector<DataType, IndexType>& x,
1084 const DenseVector<DataType, IndexType>& y, DataType alpha = DataType(1)) const
1085 {
1086 first().apply(r, x, y, alpha);
1087 }
1088
1089 void apply_transposed(VectorTypeR& r, const VectorTypeL& x) const
1090 {
1091 first().apply_transposed(r.first(), x.first());
1092 }
1093
1094 void apply_transposed(DenseVector<DataType, IndexType>& r, const DenseVector<DataType, IndexType>& x) const
1095 {
1096 first().apply_transposed(r, x);
1097 }
1098
1099 void apply_transposed(VectorTypeR& r, const VectorTypeL& x, const VectorTypeR& y, DataType alpha = DataType(1)) const
1100 {
1101 first().apply_transposed(r.first(), x.first(), y.first(), alpha);
1102 }
1103
1104 void apply_transposed(DenseVector<DataType, IndexType>& r, const DenseVector<DataType, IndexType>& x,
1105 const DenseVector<DataType, IndexType>& y, DataType alpha = DataType(1)) const
1106 {
1107 first().apply_transposed(r, x, y, alpha);
1108 }
1109
1116 DataType max_rel_diff(const PowerDiagMatrix& x) const
1117 {
1118 return first().max_rel_diff(x.first());
1119 }
1120
1123 {
1124 return VectorTypeL(first().create_vector_l());
1125 }
1126
1129 {
1130 return VectorTypeR(first().create_vector_r());
1131 }
1132
1133 void scale_rows(const PowerDiagMatrix& a, const VectorTypeL& w)
1134 {
1135 first().scale_rows(a.first(), w.first());
1136 }
1137
1138 void scale_cols(const PowerDiagMatrix& a, const VectorTypeR& w)
1139 {
1140 first().scale_cols(a.first(), w.first());
1141 }
1142
1144 Index get_length_of_line(const Index row) const
1145 {
1146 return this->first().get_length_of_line(row);
1147 }
1148
1150 void set_line(const Index row, DataType * const pval_set, IndexType * const pcol_set,
1151 const Index col_start, const Index stride = 1) const
1152 {
1153 this->first().set_line(row, pval_set, pcol_set, col_start, stride);
1154 }
1155
1156 void set_line_reverse(const Index row, const DataType * const pval_set, const Index stride = 1)
1157 {
1158 this->first().set_line_reverse(row, pval_set, stride);
1159 }
1160
1161 Index row_degree(const Index row) const
1162 {
1163 return first().row_degree(row);
1164 }
1165
1166 template<typename IT2_>
1167 Index get_row_col_indices(const Index row, IT2_* const pcol_idx, const IT2_ col_offset) const
1168 {
1169 return first().get_row_col_indices(row, pcol_idx, col_offset);
1170 }
1171
1172 template<typename DT2_>
1173 Index get_row_values(const Index row, DT2_ * const pvals) const
1174 {
1175 return first().get_row_values(row, pvals);
1176 }
1177
1178 template<typename DT2_>
1179 Index set_row_values(const Index row, const DT2_ * const pvals)
1180 {
1181 return first().set_row_values(row, pvals);
1182 }
1183
1191 template <typename SubType2_>
1192 void convert(const PowerDiagMatrix<SubType2_, 1> & other)
1193 {
1194 this->first().convert(other.first());
1195 }
1196
1197 template <typename SubType2_>
1198 void convert_reverse(PowerDiagMatrix<SubType2_, 1> & other) const
1199 {
1200 this->first().convert_reverse(other.first());
1201 }
1202
1211 bool same_layout(const PowerDiagMatrix& x) const
1212 {
1213 return (this->name() == x.name()) && (this->first().same_layout(x.first()));
1214 }
1215 };
1217 } // namespace LAFEM
1218} // namespace FEAT
#define XABORTM(msg)
Abortion macro definition with custom message.
Definition: assertion.hpp:192
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Definition: assertion.hpp:263
Index size() const
Returns the containers size.
Definition: container.hpp:1136
Dense data vector class template.
Power-Diag-Matrix meta class template.
PowerDiagMatrix(SubMatrixType &&the_first, RestClass &&the_rest)
base-class constructor; this one is protected for a reason
PowerDiagMatrix(FileMode mode, std::istream &file, String directory="")
Constructor.
SubMatrixType & at()
Returns a sub-matrix block.
SubMatrixType & get(int i, int j)
Returns a sub-matrix block.
PowerDiagMatrix(PowerDiagMatrix &&other)
move ctor
ContainerType< DataType2_, IndexType2_ > ContainerTypeByDI
this typedef lets you create a matrix container with different Data and Index types
PowerVector< typename SubMatrixType::VectorTypeL, blocks_ > VectorTypeL
Compatible L-vector type.
PowerVector< typename SubMatrixType::VectorTypeR, blocks_ > VectorTypeR
Compatible R-vector type.
PowerDiagMatrix clone(LAFEM::CloneMode mode=LAFEM::CloneMode::Weak) const
Creates and returns a deep copy of this matrix.
static constexpr SparseLayoutId layout_id
sub-matrix layout type
std::uint64_t set_checkpoint_data(std::vector< char > &data, SerialConfig &config)
PowerDiagMatrix & operator=(PowerDiagMatrix &&other)
move-assign operator
const SubMatrixType & at() const
Returns a sub-matrix block.
void restore_from_checkpoint_data(std::vector< char > &data)
Extract object from checkpoint.
SubMatrixType::DataType DataType
sub-matrix data type
PowerDiagMatrix(const PowerDiagMatrix &)=delete
deleted copy-ctor
PowerDiagMatrix(FileMode mode, String filename)
Constructor.
bool same_layout(const PowerDiagMatrix &x) const
Checks if the structural layout of this matrix matches that of another matrix. This excludes comparis...
Index columns() const
Returns the total number of columns in this matrix.
PowerDiagMatrix transpose() const
Creates and returns the transpose of this matrix.
void write_out(FileMode mode, String filename) const
Write out matrix to file.
void clone(const PowerDiagMatrix &other, CloneMode clone_mode=CloneMode::Weak)
Clone operation.
Index rows() const
Returns the total number of rows in this matrix.
static String name()
Returns a descriptive string for this container.
void read_from(FileMode mode, String filename)
Read in matrix from file.
void apply(VectorTypeL &r, const VectorTypeR &x) const
Applies this matrix onto a vector.
SubMatrixType::IndexType IndexType
sub-matrix index type
SubMatrixType _first
the first sub-matrix
std::size_t bytes() const
Returns the total amount of bytes allocated.
std::uint64_t get_checkpoint_size(SerialConfig &config)
Calculate size.
PowerDiagMatrix< SubType_, blocks_-1 > RestClass
rest-class typedef
VectorTypeL create_vector_l() const
Returns a new compatible L-Vector.
PowerDiagMatrix< typename SubType_::template ContainerType< DT2_, IT2_ >, blocks_ > ContainerType
Our 'base' class type.
void write_out_submatrices(FileMode mode, String directory, String prefix, String suffix, Index length=blocks_) const
Write out submatrices to file.
PowerDiagMatrix(const SparseLayout< IndexType, layout_id > &layout)
sub-matrix layout ctor
static constexpr int num_col_blocks
number of column blocks (horizontal size)
void apply(VectorTypeL &r, const VectorTypeR &x, const VectorTypeL &y, DataType alpha=DataType(1)) const
Applies this matrix onto a vector.
void convert(const PowerDiagMatrix< SubType2_, blocks_ > &other)
Conversion method.
SubType_ SubMatrixType
sub-matrix type
const SubMatrixType & get(int i, int j) const
Returns a sub-matrix block.
Index get_length_of_line(const Index row) const
Returns the number of NNZ-elements of the selected row.
void format(DataType value=DataType(0))
Reset all elements of the container to a given value or zero if missing.
void apply_transposed(VectorTypeR &r, const VectorTypeL &x, const VectorTypeR &y, DataType alpha=DataType(1)) const
Applies this matrix onto a vector.
DataType max_rel_diff(const PowerDiagMatrix &x) const
Retrieve the maximum relative difference of this matrix and another one y.max_rel_diff(x) returns .
static constexpr int num_row_blocks
number of row blocks (vertical size)
void clear()
Free all allocated arrays.
VectorTypeR create_vector_r() const
Returns a new compatible R-Vector.
virtual ~PowerDiagMatrix()
virtual destructor
RestClass _rest
the remaining part
void apply_transposed(VectorTypeR &r, const VectorTypeL &x) const
Applies this matrix onto a vector.
void extract_diag(VectorTypeL &diag) const
extract main diagonal vector from matrix
Index used_elements() const
Returns the total number of non-zeros in this matrix.
PowerDiagMatrix & operator=(const PowerDiagMatrix &)=delete
deleted copy-assign operator
Power-Vector meta class template.
Config class for serialize parameter.
Definition: container.hpp:47
Layout scheme for sparse matrix containers.
String class implementation.
Definition: string.hpp:47
String & trim_me(const String &charset)
Trims this string.
Definition: string.hpp:359
@ other
generic/other permutation strategy
SparseLayoutId
Definition: base.hpp:63
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.
Power container element helper class template.