matrixutils.hh
Go to the documentation of this file.00001 #ifndef DUNE_MATRIX_UTILS_HH
00002 #define DUNE_MATRIX_UTILS_HH
00003
00004 #include<dune/common/typetraits.hh>
00005 #include<dune/common/static_assert.hh>
00006 #include"istlexception.hh"
00007
00008 namespace Dune
00009 {
00019 namespace
00020 {
00021
00022 template<int i>
00023 struct NonZeroCounter
00024 {
00025 template<class M>
00026 static typename M::size_type count(const M& matrix)
00027 {
00028 typedef typename M::ConstRowIterator RowIterator;
00029
00030 RowIterator endRow = matrix.end();
00031 typename M::size_type nonZeros = 0;
00032
00033 for(RowIterator row = matrix.begin(); row != endRow; ++row){
00034 typedef typename M::ConstColIterator Entry;
00035 Entry endEntry = row->end();
00036 for(Entry entry = row->begin(); entry != endEntry; ++entry){
00037 nonZeros += NonZeroCounter<i-1>::count(*entry);
00038 }
00039 }
00040 return nonZeros;
00041 }
00042 };
00043
00044 template<>
00045 struct NonZeroCounter<1>
00046 {
00047 template<class M>
00048 static typename M::size_type count(const M& matrix)
00049 {
00050 return matrix.N()*matrix.M();
00051 }
00052 };
00053
00054 }
00055
00060 template<std::size_t blocklevel, std::size_t l=blocklevel>
00061 struct CheckIfDiagonalPresent
00062 {
00067 template<class Matrix>
00068 static void check(const Matrix& mat)
00069 {
00070 #ifdef DUNE_ISTL_WITH_CHECKING
00071 CheckIfDiagonalPresent<blocklevel-1,l>::check(mat);
00072 #endif
00073 }
00074 };
00075
00076 template<std::size_t l>
00077 struct CheckIfDiagonalPresent<0,l>
00078 {
00079 template<class Matrix>
00080 static void check(const Matrix& mat)
00081 {
00082 typedef typename Matrix::ConstRowIterator Row;
00083 for(Row row = mat.begin(); row!=mat.end(); ++row){
00084 if(row->find(row.index())==row->end())
00085 DUNE_THROW(ISTLError, "Missing diagonal value in row "<<row.index()
00086 <<" at block recursion level "<<l);
00087 }
00088 }
00089 };
00090
00102 template<class M>
00103 inline int countNonZeros(const M& matrix)
00104 {
00105 return NonZeroCounter<M::blocklevel>::count(matrix);
00106 }
00107
00108
00109
00110
00111
00113 }
00114 #endif