matrixutils.hh

Go to the documentation of this file.
00001 #ifndef DUNE_MATRIX_UTILS_HH
00002 #define DUNE_MATRIX_UTILS_HH
00003 
00004 #include<set>
00005 #include<limits>
00006 #include<dune/common/typetraits.hh>
00007 #include<dune/common/static_assert.hh>
00008 #include"istlexception.hh"
00009 
00010 namespace Dune
00011 {
00021   namespace
00022   {
00023 
00024     template<int i>
00025     struct NonZeroCounter
00026     {
00027       template<class M>
00028       static typename M::size_type count(const M& matrix)
00029       {
00030         typedef typename M::ConstRowIterator RowIterator;
00031 
00032         RowIterator endRow = matrix.end();
00033         typename M::size_type nonZeros = 0;
00034 
00035         for(RowIterator row = matrix.begin(); row != endRow; ++row){
00036           typedef typename M::ConstColIterator Entry;   
00037           Entry endEntry = row->end();
00038           for(Entry entry = row->begin(); entry != endEntry; ++entry){
00039             nonZeros += NonZeroCounter<i-1>::count(*entry);
00040           }
00041         }
00042         return nonZeros;
00043       }
00044     };
00045 
00046     template<>
00047     struct NonZeroCounter<1>
00048     {
00049       template<class M>
00050       static typename M::size_type count(const M& matrix)
00051       {
00052         return matrix.N()*matrix.M();
00053       }
00054     };
00055   
00056   }
00057 
00062   template<std::size_t blocklevel, std::size_t l=blocklevel>
00063   struct CheckIfDiagonalPresent
00064   {
00069     template<class Matrix>
00070     static void check(const Matrix& mat)
00071     {
00072 #ifdef DUNE_ISTL_WITH_CHECKING
00073       CheckIfDiagonalPresent<blocklevel-1,l>::check(mat);
00074 #endif
00075     }
00076   };
00077   
00078   template<std::size_t l>
00079   struct CheckIfDiagonalPresent<0,l>
00080   {  
00081     template<class Matrix>
00082     static void check(const Matrix& mat)
00083     {
00084       typedef typename Matrix::ConstRowIterator Row;
00085       for(Row row = mat.begin(); row!=mat.end(); ++row){
00086         if(row->find(row.index())==row->end())
00087           DUNE_THROW(ISTLError, "Missing diagonal value in row "<<row.index()
00088                      <<" at block recursion level "<<l);
00089       }
00090     }
00091   };
00092   
00104   template<class M>
00105   inline int countNonZeros(const M& matrix)
00106   {
00107     return NonZeroCounter<M::blocklevel>::count(matrix);
00108   }
00109   /*
00110   template<class M>
00111   struct ProcessOnFieldsOfMatrix
00112   */
00113 
00115   namespace
00116   {
00117     struct CompPair{
00118       template<class G,class M>
00119       bool operator()(const std::pair<G,M>& p1, const std::pair<G,M>& p2)
00120       {
00121         return p1.first<p2.first;
00122       }
00123     };
00124     
00125   }
00126   template<class M, class C>
00127   void printGlobalSparseMatrix(const M& mat, C& ooc, std::ostream& os)
00128   {
00129     typedef typename C::ParallelIndexSet::const_iterator IIter;
00130     typedef typename C::OwnerSet OwnerSet;
00131     typedef typename C::ParallelIndexSet::GlobalIndex GlobalIndex;
00132     
00133     GlobalIndex gmax=0;
00134 
00135     for(IIter idx=ooc.indexSet().begin(), eidx=ooc.indexSet().end();
00136         idx!=eidx; ++idx)
00137       gmax=std::max(gmax,idx->global());
00138     
00139     gmax=ooc.communicator().max(gmax);
00140     ooc.buildGlobalLookup();
00141     
00142     for(IIter idx=ooc.indexSet().begin(), eidx=ooc.indexSet().end();
00143         idx!=eidx; ++idx){
00144       if(OwnerSet::contains(idx->local().attribute()))
00145         {
00146           typedef typename  M::block_type Block;
00147           
00148           std::set<std::pair<GlobalIndex,Block>,CompPair> entries;
00149           
00150           // sort rows
00151           typedef typename M::ConstColIterator CIter;
00152           for(CIter c=mat[idx->local()].begin(), cend=mat[idx->local()].end();
00153               c!=cend; ++c){
00154               const typename C::ParallelIndexSet::IndexPair* pair
00155                 =ooc.globalLookup().pair(c.index());
00156               assert(pair);
00157               entries.insert(std::make_pair(pair->global(), *c));
00158           }
00159           
00160           //wait until its the rows turn.
00161           GlobalIndex rowidx = idx->global();
00162           GlobalIndex cur=std::numeric_limits<GlobalIndex>::max();
00163           while(cur!=rowidx)
00164             cur=ooc.communicator().min(rowidx);
00165           
00166           // print rows
00167           typedef typename std::set<std::pair<GlobalIndex,Block>,CompPair>::iterator SIter;
00168           for(SIter s=entries.begin(), send=entries.end(); s!=send; ++s)
00169             os<<idx->global()<<" "<<s->first<<" "<<s->second<<std::endl;
00170           
00171           
00172         }
00173     }
00174 
00175     ooc.freeGlobalLookup();
00176     // Wait until everybody is finished
00177     GlobalIndex cur=std::numeric_limits<GlobalIndex>::max();
00178     while(cur!=ooc.communicator().min(cur));
00179   }
00180   
00181 }
00182 #endif
Generated on Sat Apr 24 11:13:46 2010 for dune-istl by  doxygen 1.6.3