Reference documentation for deal.II version 9.0.0
matrix_block.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2007 - 2018 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE at
12 // the top level of the deal.II distribution.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii_matrix_block_h
17 #define dealii_matrix_block_h
18 
19 #include <deal.II/base/config.h>
20 #include <deal.II/base/smartpointer.h>
21 #include <deal.II/base/memory_consumption.h>
22 #include <deal.II/base/mg_level_object.h>
23 #include <deal.II/lac/block_indices.h>
24 #include <deal.II/lac/block_sparsity_pattern.h>
25 #include <deal.II/lac/sparse_matrix.h>
26 #include <deal.II/lac/full_matrix.h>
27 #include <deal.II/algorithms/any_data.h>
28 
29 #include <memory>
30 
31 
32 DEAL_II_NAMESPACE_OPEN
33 
34 template <typename MatrixType> class MatrixBlock;
35 
36 namespace internal
37 {
38  template <typename MatrixType>
39  void
40  reinit(MatrixBlock<MatrixType> &v,
41  const BlockSparsityPattern &p);
42 
43  template <typename number>
44  void
45  reinit(MatrixBlock<::SparseMatrix<number> > &v,
46  const BlockSparsityPattern &p);
47 }
48 
104 template <typename MatrixType>
105 class MatrixBlock
106  : public Subscriptor
107 {
108 public:
113 
117  typedef typename MatrixType::value_type value_type;
118 
122  MatrixBlock();
123 
128 
134 
142  void reinit(const BlockSparsityPattern &sparsity);
143 
144  operator MatrixType &();
145  operator const MatrixType &() const;
146 
151  void add (const size_type i,
152  const size_type j,
153  const typename MatrixType::value_type value);
154 
170  template <typename number>
171  void add (const std::vector<size_type> &indices,
172  const FullMatrix<number> &full_matrix,
173  const bool elide_zero_values = true);
174 
189  template <typename number>
190  void add (const std::vector<size_type> &row_indices,
191  const std::vector<size_type> &col_indices,
192  const FullMatrix<number> &full_matrix,
193  const bool elide_zero_values = true);
194 
211  template <typename number>
212  void add (const size_type row_index,
213  const std::vector<size_type> &col_indices,
214  const std::vector<number> &values,
215  const bool elide_zero_values = true);
216 
226  template <typename number>
227  void add (const size_type row,
228  const size_type n_cols,
229  const size_type *col_indices,
230  const number *values,
231  const bool elide_zero_values = true,
232  const bool col_indices_are_sorted = false);
233 
239  template <class VectorType>
240  void vmult (VectorType &w, const VectorType &v) const;
241 
247  template <class VectorType>
248  void vmult_add (VectorType &w, const VectorType &v) const;
249 
255  template <class VectorType>
256  void Tvmult (VectorType &w, const VectorType &v) const;
257 
263  template <class VectorType>
264  void Tvmult_add (VectorType &w, const VectorType &v) const;
265 
269  std::size_t memory_consumption () const;
270 
276  << "Block index " << arg1 << " does not match " << arg2);
277 
288 
292  MatrixType matrix;
293 
294 private:
306 
307  template <class OTHER_MatrixType>
308  friend
309  void ::internal::reinit(MatrixBlock<OTHER_MatrixType> &,
310  const BlockSparsityPattern &);
311 
312  template <typename number>
313  friend
314  void internal::reinit(MatrixBlock<::SparseMatrix<number> > &v,
315  const BlockSparsityPattern &p);
316 };
317 
318 
328 template <typename MatrixType>
330  :
331  private AnyData
332 {
333 public:
338 
343 
348  typedef std::shared_ptr<value_type> ptr_type;
349 
354  void add(size_type row, size_type column, const std::string &name);
355 
360  void reinit(const BlockSparsityPattern &sparsity);
361 
372  void clear (bool really_clean = false);
373 
377  std::size_t memory_consumption () const;
378 
382  const value_type &block(size_type i) const;
383 
388 
392  MatrixType &matrix(size_type i);
393 
397  using AnyData::subscribe;
398  using AnyData::unsubscribe;
399  using AnyData::size;
400  using AnyData::name;
401 };
402 
403 
413 template <typename MatrixType>
415  : public Subscriptor
416 {
417 public:
422 
436  MGMatrixBlockVector(const bool edge_matrices = false,
437  const bool edge_flux_matrices = false);
438 
442  unsigned int size () const;
443 
449  void add(size_type row, size_type column, const std::string &name);
450 
465  void reinit_edge(const MGLevelObject<BlockSparsityPattern> &sparsity);
473 
484  void clear (bool really_clean = false);
485 
489  const value_type &block(size_type i) const;
490 
495 
500  const value_type &block_in(size_type i) const;
501 
506 
511  const value_type &block_out(size_type i) const;
512 
517 
522  const value_type &block_up(size_type i) const;
523 
528 
533  const value_type &block_down(size_type i) const;
534 
539 
543  std::size_t memory_consumption () const;
544 private:
546  void clear_object(AnyData &);
547 
549  const bool edge_matrices;
550 
552  const bool edge_flux_matrices;
553 
564 };
565 
566 
567 //----------------------------------------------------------------------//
568 
569 namespace internal
570 {
571  template <typename MatrixType>
572  void
573  reinit(MatrixBlock<MatrixType> &v,
574  const BlockSparsityPattern &p)
575  {
578  }
579 
580 
581  template <typename number>
582  void
583  reinit(MatrixBlock<::SparseMatrix<number> > &v,
584  const BlockSparsityPattern &p)
585  {
588  v.matrix.reinit(p.block(v.row, v.column));
589  }
590 }
591 
592 
593 template <typename MatrixType>
594 inline
596  :
597  row(numbers::invalid_size_type),
598  column(numbers::invalid_size_type)
599 {}
600 
601 
602 template <typename MatrixType>
603 inline
605  :
606  Subscriptor(),
607  row(M.row),
608  column(M.column),
609  matrix(M.matrix),
610  row_indices(M.row_indices),
611  column_indices(M.column_indices)
612 {}
613 
614 
615 template <typename MatrixType>
616 inline
618  :
619  row(i), column(j)
620 {}
621 
622 
623 template <typename MatrixType>
624 inline
625 void
627 {
628  internal::reinit(*this, sparsity);
629 }
630 
631 
632 template <typename MatrixType>
633 inline
635 {
636  return matrix;
637 }
638 
639 
640 template <typename MatrixType>
641 inline
642 MatrixBlock<MatrixType>::operator const MatrixType &() const
643 {
644  return matrix;
645 }
646 
647 
648 template <typename MatrixType>
649 inline void
651  const size_type gj,
652  const typename MatrixType::value_type value)
653 {
654  Assert(row_indices.size() != 0, ExcNotInitialized());
655  Assert(column_indices.size() != 0, ExcNotInitialized());
656 
657  const std::pair<unsigned int, size_type> bi
658  = row_indices.global_to_local(gi);
659  const std::pair<unsigned int, size_type> bj
660  = column_indices.global_to_local(gj);
661 
662  Assert (bi.first == row, ExcBlockIndexMismatch(bi.first, row));
663  Assert (bj.first == column, ExcBlockIndexMismatch(bj.first, column));
664 
665  matrix.add(bi.second, bj.second, value);
666 }
667 
668 
669 template <typename MatrixType>
670 template <typename number>
671 inline
672 void
673 MatrixBlock<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], c_indices.size(), c_indices.data(), &values(i,0),
686  elide_zero_values);
687 }
688 
689 
690 template <typename MatrixType>
691 template <typename number>
692 inline
693 void
695  const size_type n_cols,
696  const size_type *col_indices,
697  const number *values,
698  const bool,
699  const bool)
700 {
701  Assert(row_indices.size() != 0, ExcNotInitialized());
702  Assert(column_indices.size() != 0, ExcNotInitialized());
703 
704  const std::pair<unsigned int, size_type> bi
705  = row_indices.global_to_local(b_row);
706 
707  // In debug mode, we check whether
708  // all indices are in the correct
709  // block.
710 
711  // Actually, for the time being, we
712  // leave it at this. While it may
713  // not be the most efficient way,
714  // it is at least thread safe.
715 //#ifdef DEBUG
716  Assert(bi.first == row, ExcBlockIndexMismatch(bi.first, row));
717 
718  for (size_type j=0; j<n_cols; ++j)
719  {
720  const std::pair<unsigned int, size_type> bj
721  = column_indices.global_to_local(col_indices[j]);
722  Assert(bj.first == column, ExcBlockIndexMismatch(bj.first, column));
723 
724  matrix.add(bi.second, bj.second, values[j]);
725  }
726 //#endif
727 }
728 
729 
730 template <typename MatrixType>
731 template <typename number>
732 inline
733 void
734 MatrixBlock<MatrixType>::add (const std::vector<size_type> &indices,
735  const FullMatrix<number> &values,
736  const bool elide_zero_values)
737 {
738  Assert(row_indices.size() != 0, ExcNotInitialized());
739  Assert(column_indices.size() != 0, ExcNotInitialized());
740 
741  AssertDimension (indices.size(), values.m());
742  Assert (values.n() == values.m(), ExcNotQuadratic());
743 
744  for (size_type i=0; i<indices.size(); ++i)
745  add (indices[i], indices.size(), indices.data(), &values(i,0),
746  elide_zero_values);
747 }
748 
749 
750 
751 template <typename MatrixType>
752 template <typename number>
753 inline
754 void
756  const std::vector<size_type> &col_indices,
757  const std::vector<number> &values,
758  const bool elide_zero_values)
759 {
760  Assert(row_indices.size() != 0, ExcNotInitialized());
761  Assert(column_indices.size() != 0, ExcNotInitialized());
762 
763  AssertDimension (col_indices.size(), values.size());
764  add (row, col_indices.size(), col_indices.data(), values.data(),
765  elide_zero_values);
766 }
767 
768 
769 template <typename MatrixType>
770 template <class VectorType>
771 inline
772 void
773 MatrixBlock<MatrixType>::vmult (VectorType &w, const VectorType &v) const
774 {
775  matrix.vmult(w,v);
776 }
777 
778 
779 template <typename MatrixType>
780 template <class VectorType>
781 inline
782 void
783 MatrixBlock<MatrixType>::vmult_add (VectorType &w, const VectorType &v) const
784 {
785  matrix.vmult_add(w,v);
786 }
787 
788 
789 template <typename MatrixType>
790 template <class VectorType>
791 inline
792 void
793 MatrixBlock<MatrixType>::Tvmult (VectorType &w, const VectorType &v) const
794 {
795  matrix.Tvmult(w,v);
796 }
797 
798 
799 template <typename MatrixType>
800 template <class VectorType>
801 inline
802 void
803 MatrixBlock<MatrixType>::Tvmult_add (VectorType &w, const VectorType &v) const
804 {
805  matrix.Tvmult_add(w,v);
806 }
807 
808 
809 template <typename MatrixType>
810 inline
811 std::size_t
813 {
814  return (sizeof(*this)
816  - sizeof(matrix));
817 }
818 
819 //----------------------------------------------------------------------//
820 
821 template <typename MatrixType>
822 inline 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 
832 template <typename MatrixType>
833 inline void
835 {
836  for (size_type i=0; i<this->size(); ++i)
837  {
838  block(i).reinit(sparsity);
839  }
840 }
841 
842 
843 template <typename MatrixType>
844 inline void
846 {
847  if (really_clean)
848  {
849  Assert(false, ExcNotImplemented());
850  }
851  else
852  {
853  for (size_type i=0; i<this->size(); ++i)
854  matrix(i).clear();
855  }
856 }
857 
858 
859 
860 template <typename MatrixType>
861 inline const MatrixBlock<MatrixType> &
863 {
864  return *this->read<ptr_type>(i);
865 }
866 
867 
868 template <typename MatrixType>
871 {
872  return *this->entry<ptr_type>(i);
873 }
874 
875 
876 template <typename MatrixType>
877 inline MatrixType &
879 {
880  return this->entry<ptr_type>(i)->matrix;
881 }
882 
883 
884 
885 //----------------------------------------------------------------------//
886 
887 template <typename MatrixType>
888 inline
890  :
891  edge_matrices(e),
892  edge_flux_matrices(f)
893 {}
894 
895 
896 template <typename MatrixType>
897 inline
898 unsigned int
900 {
901  return matrices.size();
902 }
903 
904 
905 template <typename MatrixType>
906 inline void
908  size_type row, size_type column,
909  const std::string &name)
910 {
912  p[0].row = row;
913  p[0].column = column;
914 
915  matrices.add(p, name);
916  if (edge_matrices)
917  {
918  matrices_in.add(p, name);
919  matrices_out.add(p, name);
920  }
921  if (edge_flux_matrices)
922  {
923  flux_matrices_up.add(p, name);
924  flux_matrices_down.add(p, name);
925  }
926 }
927 
928 
929 template <typename MatrixType>
932 {
933  return *matrices.read<const MGLevelObject<MatrixType>* >(i);
934 }
935 
936 
937 template <typename MatrixType>
940 {
941  return *matrices.entry<MGLevelObject<MatrixType>* >(i);
942 }
943 
944 
945 template <typename MatrixType>
948 {
949  return *matrices_in.read<const MGLevelObject<MatrixType>* >(i);
950 }
951 
952 
953 template <typename MatrixType>
956 {
957  return *matrices_in.entry<MGLevelObject<MatrixType>* >(i);
958 }
959 
960 
961 template <typename MatrixType>
964 {
965  return *matrices_out.read<const MGLevelObject<MatrixType>* >(i);
966 }
967 
968 
969 template <typename MatrixType>
972 {
973  return *matrices_out.entry<MGLevelObject<MatrixType>* >(i);
974 }
975 
976 
977 template <typename MatrixType>
980 {
981  return *flux_matrices_up.read<const MGLevelObject<MatrixType>* >(i);
982 }
983 
984 
985 template <typename MatrixType>
988 {
989  return *flux_matrices_up.entry<MGLevelObject<MatrixType>* >(i);
990 }
991 
992 
993 template <typename MatrixType>
996 {
997  return *flux_matrices_down.read<const MGLevelObject<MatrixType>* >(i);
998 }
999 
1000 
1001 template <typename MatrixType>
1004 {
1005  return *flux_matrices_down.entry<MGLevelObject<MatrixType>* >(i);
1006 }
1007 
1008 
1009 template <typename MatrixType>
1010 inline void
1012 {
1013  for (size_type i=0; i<this->size(); ++i)
1014  {
1015  MGLevelObject<MatrixBlock<MatrixType> > &o = block(i);
1016  const size_type row = o[o.min_level()].row;
1017  const size_type col = o[o.min_level()].column;
1018 
1019  o.resize(sparsity.min_level(), sparsity.max_level());
1020  for (size_type level = o.min_level(); level <= o.max_level(); ++level)
1021  {
1022  o[level].row = row;
1023  o[level].column = col;
1024  internal::reinit(o[level], sparsity[level]);
1025  }
1026  }
1027 }
1028 
1029 
1030 template <typename MatrixType>
1031 inline void
1033 {
1034  for (size_type i=0; i<this->size(); ++i)
1035  {
1036  MGLevelObject<MatrixBlock<MatrixType> > &o = block(i);
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 
1055 template <typename MatrixType>
1056 inline void
1059 {
1060  for (size_type i=0; i<this->size(); ++i)
1061  {
1062  MGLevelObject<MatrixBlock<MatrixType> > &o = block(i);
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 
1081 
1082 template <typename MatrixType>
1083 inline void
1085 {
1086  for (size_type i=0; i<mo.size(); ++i)
1087  {
1089  for (size_type level = o.min_level(); level <= o.max_level(); ++level)
1090  o[level].matrix.clear();
1091  }
1092 }
1093 
1094 
1095 template <typename MatrixType>
1096 inline void
1098 {
1099  if (really_clean)
1100  {
1101  Assert(false, ExcNotImplemented());
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 
1115 
1116 
1117 DEAL_II_NAMESPACE_CLOSE
1118 
1119 #endif
void reinit_matrix(const MGLevelObject< BlockSparsityPattern > &sparsity)
unsigned int max_level() const
size_type m() const
const bool edge_matrices
Flag for storing matrices_in and matrices_out.
Definition: matrix_block.h:549
type entry(const std::string &name)
Access to stored data object by name.
Definition: any_data.h:338
AnyData matrices
The level matrices.
Definition: matrix_block.h:555
#define DeclException2(Exception2, type1, type2, outsequence)
Definition: exceptions.h:358
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1248
types::global_dof_index size_type
Definition: matrix_block.h:112
void unsubscribe(const char *identifier=nullptr) const
Definition: subscriptor.cc:177
Contents is actually a matrix.
MatrixBlock< MatrixType > value_type
Definition: matrix_block.h:342
AnyData matrices_out
The matrix from the refinement edge to the interior of a level.
Definition: matrix_block.h:559
MatrixType & matrix(size_type i)
Definition: matrix_block.h:878
const value_type & block(size_type i) const
Definition: matrix_block.h:862
void Tvmult(VectorType &w, const VectorType &v) const
Definition: matrix_block.h:793
void vmult(VectorType &w, const VectorType &v) const
Definition: matrix_block.h:773
const value_type & block(size_type i) const
Definition: matrix_block.h:931
AnyData matrices_in
The matrix from the interior of a level to the refinement edge.
Definition: matrix_block.h:557
types::global_dof_index size_type
Definition: matrix_block.h:337
static ::ExceptionBase & ExcNotInitialized()
void add(const size_type i, const size_type j, const typename MatrixType::value_type value)
Definition: matrix_block.h:650
size_type column
Definition: matrix_block.h:287
MatrixType::value_type value_type
Definition: matrix_block.h:117
unsigned int min_level() const
SparsityPatternType & block(const size_type row, const size_type column)
const bool edge_flux_matrices
Flag for storing flux_matrices_up and flux_matrices_down.
Definition: matrix_block.h:552
void clear(bool really_clean=false)
Definition: matrix_block.h:845
const value_type & block_out(size_type i) const
Definition: matrix_block.h:963
void add(size_type row, size_type column, const std::string &name)
Definition: matrix_block.h:823
void reinit_edge(const MGLevelObject< BlockSparsityPattern > &sparsity)
MGMatrixBlockVector(const bool edge_matrices=false, const bool edge_flux_matrices=false)
Definition: matrix_block.h:889
size_type n() const
unsigned int global_dof_index
Definition: types.h:88
#define Assert(cond, exc)
Definition: exceptions.h:1142
AnyData flux_matrices_down
The DG flux from a level to the lower level.
Definition: matrix_block.h:561
std::shared_ptr< value_type > ptr_type
Definition: matrix_block.h:348
const BlockIndices & get_row_indices() const
std::size_t memory_consumption() const
Definition: matrix_block.h:812
types::global_dof_index size_type
Definition: matrix_block.h:421
BlockIndices column_indices
Definition: matrix_block.h:305
const value_type & block_in(size_type i) const
Definition: matrix_block.h:947
void vmult_add(VectorType &w, const VectorType &v) const
Definition: matrix_block.h:783
BlockIndices row_indices
Definition: matrix_block.h:299
void subscribe(const char *identifier=nullptr) const
Definition: subscriptor.cc:149
MatrixType matrix
Definition: matrix_block.h:292
static ::ExceptionBase & ExcNotQuadratic()
void add(size_type row, size_type column, const std::string &name)
Definition: matrix_block.h:907
static ::ExceptionBase & ExcBlockIndexMismatch(size_type arg1, size_type arg2)
void clear(bool really_clean=false)
unsigned int size() const
Definition: matrix_block.h:899
void reinit_edge_flux(const MGLevelObject< BlockSparsityPattern > &sparsity)
void reinit(const BlockSparsityPattern &sparsity)
Definition: matrix_block.h:834
const value_type & block_up(size_type i) const
Definition: matrix_block.h:979
std::size_t memory_consumption() const
MGLevelObject< MatrixBlock< MatrixType > > value_type
Definition: matrix_block.h:426
void add(type entry, const std::string &name)
Add a new data object.
Definition: any_data.h:427
unsigned int size() const
Number of stored data objects.
Definition: any_data.h:199
void reinit(const BlockSparsityPattern &sparsity)
Definition: matrix_block.h:626
AnyData flux_matrices_up
The DG flux from the lower level to a level.
Definition: matrix_block.h:563
const value_type & block_down(size_type i) const
Definition: matrix_block.h:995
static ::ExceptionBase & ExcNotImplemented()
void resize(const unsigned int new_minlevel, const unsigned int new_maxlevel)
void clear_object(AnyData &)
Clear one of the matrix objects.
const BlockIndices & get_column_indices() const
void Tvmult_add(VectorType &w, const VectorType &v) const
Definition: matrix_block.h:803
const std::string & name(const unsigned int i) const
Name of object at index.
Definition: any_data.h:294
std::size_t memory_consumption() const
std::enable_if< std::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
size_type row
Definition: matrix_block.h:282