Reference documentation for deal.II version 8.4.2
precondition_block.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1999 - 2016 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__precondition_block_h
17 #define dealii__precondition_block_h
18 
19 
20 #include <deal.II/base/config.h>
21 #include <deal.II/base/exceptions.h>
22 #include <deal.II/base/subscriptor.h>
23 #include <deal.II/base/smartpointer.h>
24 #include <deal.II/lac/precondition_block_base.h>
25 
26 #include <vector>
27 
28 DEAL_II_NAMESPACE_OPEN
29 
30 template<typename MatrixType, typename inverse_type>
32 
83 template<typename MatrixType, typename inverse_type = typename MatrixType::value_type>
85  : public virtual Subscriptor,
86  protected PreconditionBlockBase<inverse_type>
87 {
88 private:
92  typedef typename MatrixType::value_type number;
93 
97  typedef inverse_type value_type;
98 
99 public:
104 
109  {
110  public:
115  AdditionalData (const size_type block_size,
116  const double relaxation = 1.,
117  const bool invert_diagonal = true,
118  const bool same_diagonal = false);
119 
123  double relaxation;
124 
128  size_type block_size;
129 
134 
143 
149  double threshold;
150  };
151 
152 
156  PreconditionBlock(bool store_diagonals = false);
157 
162 
170  void initialize (const MatrixType &A,
171  const AdditionalData parameters);
172 protected:
184  void initialize (const MatrixType &A,
185  const std::vector<size_type> &permutation,
186  const std::vector<size_type> &inverse_permutation,
187  const AdditionalData parameters);
188 
212  void set_permutation(const std::vector<size_type> &permutation,
213  const std::vector<size_type> &inverse_permutation);
214 
218  void invert_permuted_diagblocks(const std::vector<size_type> &permutation,
219  const std::vector<size_type> &inverse_permutation);
220 public:
226  void clear();
227 
231  bool empty () const;
232 
237  value_type el(size_type i,
238  size_type j) const;
239 
255  void invert_diagblocks();
256 
268  template <typename number2>
269  void forward_step (Vector<number2> &dst,
270  const Vector<number2> &prev,
271  const Vector<number2> &src,
272  const bool transpose_diagonal) const;
273 
285  template <typename number2>
286  void backward_step (Vector<number2> &dst,
287  const Vector<number2> &prev,
288  const Vector<number2> &src,
289  const bool transpose_diagonal) const;
290 
291 
295  size_type block_size () const;
296 
301  std::size_t memory_consumption () const;
302 
312  DeclException2 (ExcWrongBlockSize,
313  int, int,
314  << "The blocksize " << arg1
315  << " and the size of the matrix " << arg2
316  << " do not match.");
317 
321  DeclException0 (ExcInverseMatricesAlreadyExist);
322 
324 
325 protected:
330  size_type blocksize;
331 
342  double relaxation;
343 
347  std::vector<size_type> permutation;
348 
352  std::vector<size_type> inverse_permutation;
353 };
354 
355 
356 
370 template<typename MatrixType, typename inverse_type = typename MatrixType::value_type>
371 class PreconditionBlockJacobi : public virtual Subscriptor,
372  private PreconditionBlock<MatrixType, inverse_type>
373 {
374 private:
378  typedef typename MatrixType::value_type number;
379 
380 public:
385 
390  {
391  private:
395  class Accessor
396  {
397  public:
403  const size_type row);
404 
408  size_type row() const;
409 
413  size_type column() const;
414 
418  inverse_type value() const;
419 
420  protected:
425 
429  size_type bs;
430 
434  size_type a_block;
435 
440 
445 
449  friend class const_iterator;
450  };
451 
452  public:
457  const size_type row);
458 
462  const_iterator &operator++ ();
463 
467  const_iterator &operator++ (int);
468 
472  const Accessor &operator* () const;
473 
477  const Accessor *operator-> () const;
478 
482  bool operator == (const const_iterator &) const;
486  bool operator != (const const_iterator &) const;
487 
492  bool operator < (const const_iterator &) const;
493 
494  private:
499  };
500 
517 
525  template <typename number2>
526  void vmult (Vector<number2> &, const Vector<number2> &) const;
527 
531  template <typename number2>
532  void Tvmult (Vector<number2> &, const Vector<number2> &) const;
540  template <typename number2>
541  void vmult_add (Vector<number2> &, const Vector<number2> &) const;
542 
546  template <typename number2>
547  void Tvmult_add (Vector<number2> &, const Vector<number2> &) const;
548 
552  template <typename number2>
553  void step (Vector<number2> &dst, const Vector<number2> &rhs) const;
554 
558  template <typename number2>
559  void Tstep (Vector<number2> &dst, const Vector<number2> &rhs) const;
560 
564  const_iterator begin () const;
565 
569  const_iterator end () const;
570 
574  const_iterator begin (const size_type r) const;
575 
579  const_iterator end (const size_type r) const;
580 
581 
582 private:
589  template <typename number2>
590  void do_vmult (Vector<number2> &,
591  const Vector<number2> &,
592  bool adding) const;
593 
594  friend class Accessor;
595  friend class const_iterator;
596 };
597 
598 
599 
635 template<typename MatrixType, typename inverse_type = typename MatrixType::value_type>
636 class PreconditionBlockSOR : public virtual Subscriptor,
637  protected PreconditionBlock<MatrixType, inverse_type>
638 {
639 public:
644 
649 
653  typedef typename MatrixType::value_type number;
654 
671 
682  template <typename number2>
683  void vmult (Vector<number2> &, const Vector<number2> &) const;
684 
695  template <typename number2>
696  void vmult_add (Vector<number2> &, const Vector<number2> &) const;
697 
706  template <typename number2>
707  void Tvmult (Vector<number2> &, const Vector<number2> &) const;
708 
719  template <typename number2>
720  void Tvmult_add (Vector<number2> &, const Vector<number2> &) const;
721 
725  template <typename number2>
726  void step (Vector<number2> &dst, const Vector<number2> &rhs) const;
727 
731  template <typename number2>
732  void Tstep (Vector<number2> &dst, const Vector<number2> &rhs) const;
733 
734 protected:
738  PreconditionBlockSOR(bool store);
739 
749  template <typename number2>
750  void forward (Vector<number2> &,
751  const Vector<number2> &,
752  const bool transpose_diagonal,
753  const bool adding) const;
754 
764  template <typename number2>
765  void backward (Vector<number2> &,
766  const Vector<number2> &,
767  const bool transpose_diagonal,
768  const bool adding) const;
769 };
770 
771 
793 template<typename MatrixType, typename inverse_type = typename MatrixType::value_type>
794 class PreconditionBlockSSOR : public virtual Subscriptor,
795  private PreconditionBlockSOR<MatrixType, inverse_type>
796 {
797 public:
802 
806  typedef typename MatrixType::value_type number;
807 
812 
813  // Keep AdditionalData accessible
815 
816  // The following are the
817  // functions of the base classes
818  // which we want to keep
819  // accessible.
835 
843  template <typename number2>
844  void vmult (Vector<number2> &, const Vector<number2> &) const;
845 
849  template <typename number2>
850  void Tvmult (Vector<number2> &, const Vector<number2> &) const;
851 
855  template <typename number2>
856  void step (Vector<number2> &dst, const Vector<number2> &rhs) const;
857 
861  template <typename number2>
862  void Tstep (Vector<number2> &dst, const Vector<number2> &rhs) const;
863 };
864 
866 //---------------------------------------------------------------------------
867 
868 #ifndef DOXYGEN
869 
870 template<typename MatrixType, typename inverse_type>
871 inline bool
873 {
874  if (A == 0)
875  return true;
876  return A->empty();
877 }
878 
879 
880 template<typename MatrixType, typename inverse_type>
881 inline inverse_type
883  size_type i,
884  size_type j) const
885 {
886  const size_type bs = blocksize;
887  const unsigned int nb = i/bs;
888 
889  const FullMatrix<inverse_type> &B = this->inverse(nb);
890 
891  const size_type ib = i % bs;
892  const size_type jb = j % bs;
893 
894  if (jb + nb*bs != j)
895  {
896  return 0.;
897  }
898 
899  return B(ib, jb);
900 }
901 
902 //---------------------------------------------------------------------------
903 
904 template<typename MatrixType, typename inverse_type>
905 inline
908  const size_type row)
909  :
910  matrix(matrix),
911  b_iterator(&matrix->inverse(0), 0, 0),
912  b_end(&matrix->inverse(0), 0, 0)
913 {
914  bs = matrix->block_size();
915  a_block = row / bs;
916 
917  // This is the end accessor, which
918  // does not have a valid block.
919  if (a_block == matrix->size())
920  return;
921 
922  const size_type r = row % bs;
923 
924  b_iterator = matrix->inverse(a_block).begin(r);
925  b_end = matrix->inverse(a_block).end();
926 
927  Assert (a_block < matrix->size(),
928  ExcIndexRange(a_block, 0, matrix->size()));
929 }
930 
931 
932 template<typename MatrixType, typename inverse_type>
933 inline
936 {
937  Assert (a_block < matrix->size(),
938  ExcIteratorPastEnd());
939 
940  return bs * a_block + b_iterator->row();
941 }
942 
943 
944 template<typename MatrixType, typename inverse_type>
945 inline
948 {
949  Assert (a_block < matrix->size(),
950  ExcIteratorPastEnd());
951 
952  return bs * a_block + b_iterator->column();
953 }
954 
955 
956 template<typename MatrixType, typename inverse_type>
957 inline
958 inverse_type
960 {
961  Assert (a_block < matrix->size(),
962  ExcIteratorPastEnd());
963 
964  return b_iterator->value();
965 }
966 
967 
968 template<typename MatrixType, typename inverse_type>
969 inline
972  const size_type row)
973  :
974  accessor(matrix, row)
975 {}
976 
977 
978 template<typename MatrixType, typename inverse_type>
979 inline
982 {
983  Assert (*this != accessor.matrix->end(), ExcIteratorPastEnd());
984 
985  ++accessor.b_iterator;
986  if (accessor.b_iterator == accessor.b_end)
987  {
988  ++accessor.a_block;
989 
990  if (accessor.a_block < accessor.matrix->size())
991  {
992  accessor.b_iterator = accessor.matrix->inverse(accessor.a_block).begin();
993  accessor.b_end = accessor.matrix->inverse(accessor.a_block).end();
994  }
995  }
996  return *this;
997 }
998 
999 
1000 template<typename MatrixType, typename inverse_type>
1001 inline
1004 {
1005  return accessor;
1006 }
1007 
1008 
1009 template<typename MatrixType, typename inverse_type>
1010 inline
1013 {
1014  return &accessor;
1015 }
1016 
1017 
1018 template<typename MatrixType, typename inverse_type>
1019 inline
1020 bool
1022 operator == (const const_iterator &other) const
1023 {
1024  if (accessor.a_block == accessor.matrix->size() &&
1025  accessor.a_block == other.accessor.a_block)
1026  return true;
1027 
1028  if (accessor.a_block != other.accessor.a_block)
1029  return false;
1030 
1031  return (accessor.row() == other.accessor.row() &&
1032  accessor.column() == other.accessor.column());
1033 }
1034 
1035 
1036 template<typename MatrixType, typename inverse_type>
1037 inline
1038 bool
1040 operator != (const const_iterator &other) const
1041 {
1042  return ! (*this == other);
1043 }
1044 
1045 
1046 template<typename MatrixType, typename inverse_type>
1047 inline
1048 bool
1050 operator < (const const_iterator &other) const
1051 {
1052  return (accessor.row() < other.accessor.row() ||
1053  (accessor.row() == other.accessor.row() &&
1054  accessor.column() < other.accessor.column()));
1055 }
1056 
1057 
1058 template<typename MatrixType, typename inverse_type>
1059 inline
1062 {
1063  return const_iterator(this, 0);
1064 }
1065 
1066 
1067 template<typename MatrixType, typename inverse_type>
1068 inline
1071 {
1072  return const_iterator(this, this->size() * this->block_size());
1073 }
1074 
1075 
1076 template<typename MatrixType, typename inverse_type>
1077 inline
1080  const size_type r) const
1081 {
1082  Assert (r < this->A->m(), ExcIndexRange(r, 0, this->A->m()));
1083  return const_iterator(this, r);
1084 }
1085 
1086 
1087 
1088 template<typename MatrixType, typename inverse_type>
1089 inline
1092  const size_type r) const
1093 {
1094  Assert (r < this->A->m(), ExcIndexRange(r, 0, this->A->m()));
1095  return const_iterator(this, r+1);
1096 }
1097 
1098 #endif // DOXYGEN
1099 
1100 DEAL_II_NAMESPACE_CLOSE
1101 
1102 #endif
FullMatrix< inverse_type >::const_iterator b_end
std::size_t memory_consumption() const
types::global_dof_index size_type
void set_permutation(const std::vector< size_type > &permutation, const std::vector< size_type > &inverse_permutation)
FullMatrix< inverse_type >::const_iterator b_iterator
AdditionalData(const size_type block_size, const double relaxation=1., const bool invert_diagonal=true, const bool same_diagonal=false)
const Accessor * operator->() const
const_iterator begin() const
const_iterator end() const
DeclException2(ExcWrongBlockSize, int, int,<< "The blocksize "<< arg1<< " and the size of the matrix "<< arg2<< " do not match.")
Accessor(const PreconditionBlockJacobi< MatrixType, inverse_type > *matrix, const size_type row)
void backward_step(Vector< number2 > &dst, const Vector< number2 > &prev, const Vector< number2 > &src, const bool transpose_diagonal) const
types::global_dof_index size_type
void invert_permuted_diagblocks(const std::vector< size_type > &permutation, const std::vector< size_type > &inverse_permutation)
void initialize(const MatrixType &A, const AdditionalData parameters)
std::vector< size_type > inverse_permutation
const_iterator(const PreconditionBlockJacobi< MatrixType, inverse_type > *matrix, const size_type row)
size_type block_size() const
MatrixType::value_type number
FullMatrix< inverse_type > & inverse(size_type i)
bool operator!=(const const_iterator &) const
bool operator==(const const_iterator &) const
unsigned int global_dof_index
Definition: types.h:88
types::global_dof_index size_type
#define Assert(cond, exc)
Definition: exceptions.h:294
value_type el(size_type i, size_type j) const
MatrixType::value_type number
PreconditionBlockBase< inverse_type >::Inversion inversion
const_iterator begin() const
PreconditionBlock(bool store_diagonals=false)
const_iterator end() const
void forward_step(Vector< number2 > &dst, const Vector< number2 > &prev, const Vector< number2 > &src, const bool transpose_diagonal) const
DeclException0(ExcInverseMatricesAlreadyExist)
types::global_dof_index size_type
MatrixType::value_type number
void invert_diagblocks()
std::vector< size_type > permutation
bool empty() const
const Accessor & operator*() const
const PreconditionBlockJacobi< MatrixType, inverse_type > * matrix
inverse_type value_type
SmartPointer< const MatrixType, PreconditionBlock< MatrixType, inverse_type > > A
bool operator<(const const_iterator &) const
MatrixType::value_type number