deal.II version GIT relicensing-6809-ge913b9bb34 2026-09-25 17:20:01+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
matrix_block.h
Go to the documentation of this file.
1// -----------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception OR LGPL-2.1-or-later
4// Copyright (C) 2009 - 2025 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Detailed license information governing the source code and contributions
9// can be found in LICENSE.md and CONTRIBUTING.md at the top level directory.
10//
11// -----------------------------------------------------------------------------
12
13#ifndef dealii_matrix_block_h
14#define dealii_matrix_block_h
15
16#include <deal.II/base/config.h>
17
19
23
28
29#include <memory>
30
31
33
34// Forward declarations
35#ifndef DOXYGEN
36template <typename MatrixType>
37class MatrixBlock;
38#endif
39
40namespace internal
41{
42 template <typename MatrixType>
43 void
45
46 template <typename number>
47 void
49 const BlockSparsityPattern &p);
50} // namespace internal
51
89template <typename MatrixType>
91{
92public:
97
101 using value_type = typename MatrixType::value_type;
102
107
112
118
124
132 void
133 reinit(const BlockSparsityPattern &sparsity);
134
135 operator MatrixType &();
136 operator const MatrixType &() const;
137
142 void
143 add(const size_type i,
144 const size_type j,
145 const typename MatrixType::value_type value);
146
162 template <typename number>
163 void
164 add(const std::vector<size_type> &indices,
165 const FullMatrix<number> &full_matrix,
166 const bool elide_zero_values = true);
167
182 template <typename number>
183 void
184 add(const std::vector<size_type> &row_indices,
185 const std::vector<size_type> &col_indices,
186 const FullMatrix<number> &full_matrix,
187 const bool elide_zero_values = true);
188
205 template <typename number>
206 void
207 add(const size_type row_index,
208 const std::vector<size_type> &col_indices,
209 const std::vector<number> &values,
210 const bool elide_zero_values = true);
211
221 template <typename number>
222 void
224 const size_type n_cols,
225 const size_type *col_indices,
226 const number *values,
227 const bool elide_zero_values = true,
228 const bool col_indices_are_sorted = false);
229
235 template <typename VectorType>
236 void
237 vmult(VectorType &w, const VectorType &v) const;
238
244 template <typename VectorType>
245 void
246 vmult_add(VectorType &w, const VectorType &v) const;
247
253 template <typename VectorType>
254 void
255 Tvmult(VectorType &w, const VectorType &v) const;
256
262 template <typename VectorType>
263 void
264 Tvmult_add(VectorType &w, const VectorType &v) const;
265
269 std::size_t
271
277 size_type,
278 size_type,
279 << "Block index " << arg1 << " does not match " << arg2);
280
291
295 MatrixType matrix;
296
297private:
309
310 template <class OTHER_MatrixType>
311 friend void
312 ::internal::reinit(MatrixBlock<OTHER_MatrixType> &,
313 const BlockSparsityPattern &);
314
315 template <typename number>
316 friend void
318 const BlockSparsityPattern &p);
319};
320
321
330template <typename MatrixType>
332{
333public:
338
343
348 using ptr_type = std::shared_ptr<value_type>;
349
354 void
355 add(size_type row, size_type column, const std::string &name);
356
361 void
362 reinit(const BlockSparsityPattern &sparsity);
363
374 void
375 clear(bool really_clean = false);
376
380 std::size_t
382
386 const value_type &
387 block(size_type i) const;
388
392 value_type &
393 block(size_type i);
394
398 MatrixType &
399 matrix(size_type i);
400
404 using AnyData::name;
405 using AnyData::size;
406};
407
408
417template <typename MatrixType>
419{
420public:
425
439 MGMatrixBlockVector(const bool edge_matrices = false,
440 const bool edge_flux_matrices = false);
441
445 unsigned int
446 size() const;
447
453 void
454 add(size_type row, size_type column, const std::string &name);
455
462 void
471 void
479 void
481
492 void
493 clear(bool really_clean = false);
494
498 const value_type &
499 block(size_type i) const;
500
504 value_type &
505 block(size_type i);
506
511 const value_type &
512 block_in(size_type i) const;
513
517 value_type &
519
524 const value_type &
525 block_out(size_type i) const;
526
530 value_type &
532
537 const value_type &
538 block_up(size_type i) const;
539
543 value_type &
545
550 const value_type &
551 block_down(size_type i) const;
552
556 value_type &
558
562 std::size_t
564
565private:
567 void
569
571 const bool edge_matrices;
572
575
586};
587
588
589//----------------------------------------------------------------------//
590
591namespace internal
592{
593 template <typename MatrixType>
594 void
600
601
602 template <typename number>
603 void
605 const BlockSparsityPattern &p)
606 {
607 v.row_indices = p.get_row_indices();
608 v.column_indices = p.get_column_indices();
609 v.matrix.reinit(p.block(v.row, v.column));
610 }
611} // namespace internal
612
613
614template <typename MatrixType>
616 : row(numbers::invalid_size_type)
617 , column(numbers::invalid_size_type)
618{}
619
620
621template <typename MatrixType>
623 : row(i)
624 , column(j)
625{}
626
627
628template <typename MatrixType>
629inline void
631{
632 internal::reinit(*this, sparsity);
633}
634
635
636template <typename MatrixType>
638{
639 return matrix;
640}
641
642
643template <typename MatrixType>
644inline MatrixBlock<MatrixType>::operator const MatrixType &() const
645{
646 return matrix;
647}
648
649
650template <typename MatrixType>
651inline void
653 const size_type gj,
654 const typename MatrixType::value_type value)
655{
656 Assert(row_indices.size() != 0, ExcNotInitialized());
657 Assert(column_indices.size() != 0, ExcNotInitialized());
658
659 const std::pair<unsigned int, size_type> bi = row_indices.global_to_local(gi);
660 const std::pair<unsigned int, size_type> bj =
661 column_indices.global_to_local(gj);
662
663 Assert(bi.first == row, ExcBlockIndexMismatch(bi.first, row));
664 Assert(bj.first == column, ExcBlockIndexMismatch(bj.first, column));
665
666 matrix.add(bi.second, bj.second, value);
667}
668
669
670template <typename MatrixType>
671template <typename number>
672inline void
673MatrixBlock<MatrixType>::add(const std::vector<size_type> &r_indices,
674 const std::vector<size_type> &c_indices,
675 const FullMatrix<number> &values,
676 const bool elide_zero_values)
677{
678 Assert(row_indices.size() != 0, ExcNotInitialized());
679 Assert(column_indices.size() != 0, ExcNotInitialized());
680
681 AssertDimension(r_indices.size(), values.m());
682 AssertDimension(c_indices.size(), values.n());
683
684 for (size_type i = 0; i < row_indices.size(); ++i)
685 add(r_indices[i],
686 c_indices.size(),
687 c_indices.data(),
688 &values(i, 0),
689 elide_zero_values);
690}
691
692
693template <typename MatrixType>
694template <typename number>
695inline void
697 const size_type n_cols,
698 const size_type *col_indices,
699 const number *values,
700 const bool,
701 const bool)
702{
703 Assert(row_indices.size() != 0, ExcNotInitialized());
704 Assert(column_indices.size() != 0, ExcNotInitialized());
705
706 const std::pair<unsigned int, size_type> bi =
707 row_indices.global_to_local(b_row);
708
709 // In debug mode, we check whether
710 // all indices are in the correct
711 // block.
712
713 // Actually, for the time being, we
714 // leave it at this. While it may
715 // not be the most efficient way,
716 // it is at least thread safe.
717 // if constexpr (running_in_debug_mode()){
718 Assert(bi.first == row, ExcBlockIndexMismatch(bi.first, row));
719
720 for (size_type j = 0; j < n_cols; ++j)
721 {
722 const std::pair<unsigned int, size_type> bj =
723 column_indices.global_to_local(col_indices[j]);
724 Assert(bj.first == column, ExcBlockIndexMismatch(bj.first, column));
725
726 matrix.add(bi.second, bj.second, values[j]);
727 }
728 // }
729}
730
731
732template <typename MatrixType>
733template <typename number>
734inline void
735MatrixBlock<MatrixType>::add(const std::vector<size_type> &indices,
736 const FullMatrix<number> &values,
737 const bool elide_zero_values)
738{
739 Assert(row_indices.size() != 0, ExcNotInitialized());
740 Assert(column_indices.size() != 0, ExcNotInitialized());
741
742 AssertDimension(indices.size(), values.m());
743 Assert(values.n() == values.m(), ExcNotQuadratic());
744
745 for (size_type i = 0; i < indices.size(); ++i)
746 add(indices[i],
747 indices.size(),
748 indices.data(),
749 &values(i, 0),
750 elide_zero_values);
751}
752
753
754
755template <typename MatrixType>
756template <typename number>
757inline void
759 const std::vector<size_type> &col_indices,
760 const std::vector<number> &values,
761 const bool elide_zero_values)
762{
763 Assert(row_indices.size() != 0, ExcNotInitialized());
764 Assert(column_indices.size() != 0, ExcNotInitialized());
765
766 AssertDimension(col_indices.size(), values.size());
767 add(row,
768 col_indices.size(),
769 col_indices.data(),
770 values.data(),
771 elide_zero_values);
772}
773
774
775template <typename MatrixType>
776template <typename VectorType>
777inline void
778MatrixBlock<MatrixType>::vmult(VectorType &w, const VectorType &v) const
779{
780 matrix.vmult(w, v);
781}
782
783
784template <typename MatrixType>
785template <typename VectorType>
786inline void
787MatrixBlock<MatrixType>::vmult_add(VectorType &w, const VectorType &v) const
788{
789 matrix.vmult_add(w, v);
790}
791
792
793template <typename MatrixType>
794template <typename VectorType>
795inline void
796MatrixBlock<MatrixType>::Tvmult(VectorType &w, const VectorType &v) const
797{
798 matrix.Tvmult(w, v);
799}
800
801
802template <typename MatrixType>
803template <typename VectorType>
804inline void
805MatrixBlock<MatrixType>::Tvmult_add(VectorType &w, const VectorType &v) const
806{
807 matrix.Tvmult_add(w, v);
808}
809
810
811template <typename MatrixType>
812inline std::size_t
814{
815 return (sizeof(*this) + MemoryConsumption::memory_consumption(matrix) -
816 sizeof(matrix));
817}
818
819//----------------------------------------------------------------------//
820
821template <typename MatrixType>
822inline void
824 size_type column,
825 const std::string &name)
826{
827 ptr_type p(new value_type(row, column));
828 AnyData::add(p, name);
829}
830
831
832template <typename MatrixType>
833inline void
835{
836 for (size_type i = 0; i < this->size(); ++i)
837 {
838 block(i).reinit(sparsity);
839 }
840}
841
842
843template <typename MatrixType>
844inline void
846{
847 if (really_clean)
848 {
850 }
851 else
852 {
853 for (size_type i = 0; i < this->size(); ++i)
854 matrix(i).clear();
855 }
856}
857
858
859
860template <typename MatrixType>
861inline const MatrixBlock<MatrixType> &
863{
864 return *this->read<ptr_type>(i);
865}
866
867
868template <typename MatrixType>
871{
872 return *this->entry<ptr_type>(i);
873}
874
875
876template <typename MatrixType>
877inline MatrixType &
879{
880 return this->entry<ptr_type>(i)->matrix;
881}
882
883
884
885//----------------------------------------------------------------------//
886
887template <typename MatrixType>
889 const bool f)
890 : edge_matrices(e)
891 , edge_flux_matrices(f)
892{}
893
894
895template <typename MatrixType>
896inline unsigned int
898{
899 return matrices.size();
900}
901
902
903template <typename MatrixType>
904inline void
906 size_type column,
907 const std::string &name)
908{
910 p[0].row = row;
911 p[0].column = column;
912
913 matrices.add(p, name);
914 if (edge_matrices)
915 {
916 matrices_in.add(p, name);
917 matrices_out.add(p, name);
918 }
919 if (edge_flux_matrices)
920 {
921 flux_matrices_up.add(p, name);
922 flux_matrices_down.add(p, name);
923 }
924}
925
926
927template <typename MatrixType>
930{
931 return *matrices.read<const MGLevelObject<MatrixType> *>(i);
932}
933
934
935template <typename MatrixType>
941
942
943template <typename MatrixType>
946{
947 return *matrices_in.read<const MGLevelObject<MatrixType> *>(i);
948}
949
950
951template <typename MatrixType>
954{
955 return *matrices_in.entry<MGLevelObject<MatrixType> *>(i);
956}
957
958
959template <typename MatrixType>
962{
963 return *matrices_out.read<const MGLevelObject<MatrixType> *>(i);
964}
965
966
967template <typename MatrixType>
970{
971 return *matrices_out.entry<MGLevelObject<MatrixType> *>(i);
972}
973
974
975template <typename MatrixType>
978{
979 return *flux_matrices_up.read<const MGLevelObject<MatrixType> *>(i);
980}
981
982
983template <typename MatrixType>
986{
987 return *flux_matrices_up.entry<MGLevelObject<MatrixType> *>(i);
988}
989
990
991template <typename MatrixType>
994{
995 return *flux_matrices_down.read<const MGLevelObject<MatrixType> *>(i);
996}
997
998
999template <typename MatrixType>
1002{
1003 return *flux_matrices_down.entry<MGLevelObject<MatrixType> *>(i);
1004}
1005
1006
1007template <typename MatrixType>
1008inline void
1011{
1012 for (size_type i = 0; i < this->size(); ++i)
1013 {
1015 const size_type row = o[o.min_level()].row;
1016 const size_type col = o[o.min_level()].column;
1017
1018 o.resize(sparsity.min_level(), sparsity.max_level());
1019 for (size_type level = o.min_level(); level <= o.max_level(); ++level)
1020 {
1021 o[level].row = row;
1022 o[level].column = col;
1023 internal::reinit(o[level], sparsity[level]);
1024 }
1025 }
1026}
1027
1028
1029template <typename MatrixType>
1030inline void
1033{
1034 for (size_type i = 0; i < this->size(); ++i)
1035 {
1037 const size_type row = o[o.min_level()].row;
1038 const size_type col = o[o.min_level()].column;
1039
1040 block_in(i).resize(sparsity.min_level(), sparsity.max_level());
1041 block_out(i).resize(sparsity.min_level(), sparsity.max_level());
1042 for (size_type level = o.min_level(); level <= o.max_level(); ++level)
1043 {
1044 block_in(i)[level].row = row;
1045 block_in(i)[level].column = col;
1046 internal::reinit(block_in(i)[level], sparsity[level]);
1047 block_out(i)[level].row = row;
1048 block_out(i)[level].column = col;
1049 internal::reinit(block_out(i)[level], sparsity[level]);
1050 }
1051 }
1052}
1053
1054
1055template <typename MatrixType>
1056inline void
1059{
1060 for (size_type i = 0; i < this->size(); ++i)
1061 {
1063 const size_type row = o[o.min_level()].row;
1064 const size_type col = o[o.min_level()].column;
1065
1066 block_up(i).resize(sparsity.min_level(), sparsity.max_level());
1067 block_down(i).resize(sparsity.min_level(), sparsity.max_level());
1068 for (size_type level = o.min_level(); level <= o.max_level(); ++level)
1069 {
1070 block_up(i)[level].row = row;
1071 block_up(i)[level].column = col;
1072 internal::reinit(block_up(i)[level], sparsity[level]);
1073 block_down(i)[level].row = row;
1074 block_down(i)[level].column = col;
1075 internal::reinit(block_down(i)[level], sparsity[level]);
1076 }
1077 }
1078}
1079
1080
1081template <typename MatrixType>
1082inline void
1084{
1085 for (size_type i = 0; i < mo.size(); ++i)
1086 {
1089 for (size_type level = o.min_level(); level <= o.max_level(); ++level)
1090 o[level].matrix.clear();
1091 }
1092}
1093
1094
1095template <typename MatrixType>
1096inline void
1098{
1099 if (really_clean)
1100 {
1102 }
1103 else
1104 {
1105 clear_object(matrices);
1106 clear_object(matrices_in);
1107 clear_object(matrices_out);
1108 clear_object(flux_matrices_up);
1109 clear_object(flux_matrices_down);
1110 }
1111}
1112
1113
1114
1116
1117#endif
const std::string & name(const unsigned int i) const
Name of object at index.
Definition any_data.h:309
type entry(const std::string &name)
Access to stored data object by name.
Definition any_data.h:349
void add(type entry, const std::string &name)
Add a new data object.
Definition any_data.h:430
unsigned int size() const
Number of stored data objects.
Definition any_data.h:221
void reinit(const unsigned int n_blocks, const size_type n_elements_per_block)
SparsityPatternType & block(const size_type row, const size_type column)
const BlockIndices & get_column_indices() const
const BlockIndices & get_row_indices() const
void resize(const unsigned int new_minlevel, const unsigned int new_maxlevel, Args &&...args)
unsigned int max_level() const
unsigned int min_level() const
AnyData flux_matrices_up
The DG flux from the lower level to a level.
const value_type & block_down(size_type i) const
void clear_object(AnyData &)
Clear one of the matrix objects.
const value_type & block(size_type i) const
void clear(bool really_clean=false)
void reinit_edge_flux(const MGLevelObject< BlockSparsityPattern > &sparsity)
const bool edge_flux_matrices
Flag for storing flux_matrices_up and flux_matrices_down.
AnyData matrices_out
The matrix from the refinement edge to the interior of a level.
void reinit_matrix(const MGLevelObject< BlockSparsityPattern > &sparsity)
const value_type & block_in(size_type i) const
MGMatrixBlockVector(const bool edge_matrices=false, const bool edge_flux_matrices=false)
const value_type & block_out(size_type i) const
std::size_t memory_consumption() const
AnyData flux_matrices_down
The DG flux from a level to the lower level.
AnyData matrices
The level matrices.
void reinit_edge(const MGLevelObject< BlockSparsityPattern > &sparsity)
AnyData matrices_in
The matrix from the interior of a level to the refinement edge.
const bool edge_matrices
Flag for storing matrices_in and matrices_out.
void add(size_type row, size_type column, const std::string &name)
unsigned int size() const
const value_type & block_up(size_type i) const
const std::string & name(const unsigned int i) const
Definition any_data.h:309
std::shared_ptr< value_type > ptr_type
void add(size_type row, size_type column, const std::string &name)
const value_type & block(size_type i) const
void clear(bool really_clean=false)
std::size_t memory_consumption() const
void reinit(const BlockSparsityPattern &sparsity)
MatrixType & matrix(size_type i)
MatrixBlock< MatrixType > & operator=(const MatrixBlock< MatrixType > &)=default
void vmult_add(VectorType &w, const VectorType &v) const
void reinit(const BlockSparsityPattern &sparsity)
BlockIndices column_indices
MatrixBlock(size_type i, size_type j)
void add(const size_type i, const size_type j, const typename MatrixType::value_type value)
std::size_t memory_consumption() const
MatrixType matrix
void add(const std::vector< size_type > &row_indices, const std::vector< size_type > &col_indices, const FullMatrix< number > &full_matrix, const bool elide_zero_values=true)
void Tvmult_add(VectorType &w, const VectorType &v) const
void add(const std::vector< size_type > &indices, const FullMatrix< number > &full_matrix, const bool elide_zero_values=true)
void add(const size_type row_index, const std::vector< size_type > &col_indices, const std::vector< number > &values, const bool elide_zero_values=true)
void vmult(VectorType &w, const VectorType &v) const
void Tvmult(VectorType &w, const VectorType &v) const
BlockIndices row_indices
typename MatrixType::value_type value_type
size_type row
MatrixBlock(const MatrixBlock< MatrixType > &M)=default
size_type column
void add(const size_type row, const size_type n_cols, const size_type *col_indices, const number *values, const bool elide_zero_values=true, const bool col_indices_are_sorted=false)
friend void internal::reinit(MatrixBlock<::SparseMatrix< number > > &v, const BlockSparsityPattern &p)
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
#define DEAL_II_NOT_IMPLEMENTED()
unsigned int level
Definition grid_out.cc:4642
static ::ExceptionBase & ExcBlockIndexMismatch(size_type arg1, size_type arg2)
#define Assert(cond, exc)
#define DeclException2(Exception2, type1, type2, outsequence)
#define AssertDimension(dim1, dim2)
static ::ExceptionBase & ExcNotInitialized()
static ::ExceptionBase & ExcNotQuadratic()
std::size_t size
Definition mpi.cc:733
std::enable_if_t< std::is_fundamental_v< T >, std::size_t > memory_consumption(const T &t)
void reinit(MatrixBlock< MatrixType > &v, const BlockSparsityPattern &p)
unsigned int global_dof_index
Definition types.h:92