hierarchy.hh

Go to the documentation of this file.
00001 // $Id: hierarchy.hh 997 2009-02-17 05:44:27Z mnolte $
00002 #ifndef DUNE_AMGHIERARCHY_HH
00003 #define DUNE_AMGHIERARCHY_HH
00004 
00005 #include<list>
00006 #include<memory>
00007 #include<limits>
00008 #include<algorithm>
00009 #include"pmatrix.hh"
00010 #include"aggregates.hh"
00011 #include"graph.hh"
00012 #include"galerkin.hh"
00013 #include"renumberer.hh"
00014 #include"graphcreator.hh"
00015 #include<dune/common/stdstreams.hh>
00016 #include<dune/common/timer.hh>
00017 #include<dune/common/tuples.hh>
00018 #include<dune/istl/bvector.hh>
00019 #include<dune/istl/indexset.hh>
00020 #include<dune/istl/paamg/dependency.hh>
00021 #include<dune/istl/paamg/graph.hh>
00022 #include<dune/istl/paamg/indicescoarsener.hh>
00023 #include<dune/istl/paamg/globalaggregates.hh>
00024 #include<dune/istl/paamg/construction.hh>
00025 #include<dune/istl/paamg/smoother.hh>
00026 
00027 namespace Dune
00028 {
00029   namespace Amg
00030   {
00048     template<typename T, typename A=std::allocator<T> >
00049     class Hierarchy
00050     {
00051     public:
00055       typedef T MemberType;
00056 
00057       template<typename T1, typename T2>
00058       class LevelIterator;
00059 
00060     private:
00064       struct Element
00065       {
00066         friend class LevelIterator<Hierarchy<T,A>, T>;
00067         friend class LevelIterator<const Hierarchy<T,A>, const T>;
00068 
00070         Element* coarser_;
00071         
00073         Element* finer_;
00074         
00076         MemberType* element_;
00077         
00079         MemberType* redistributed_;
00080       };
00081     public:
00082 //       enum{
00083 //      /**
00084 //       * @brief If true only the method addCoarser will be usable
00085 //       * otherwise only the method addFiner will be usable.
00086 //       */
00087 //      coarsen = b
00088 //        };
00089       
00093       typedef typename A::template rebind<Element>::other Allocator;
00094 
00095       typedef typename ConstructionTraits<T>::Arguments Arguments;
00096       
00101       Hierarchy(MemberType& first);
00102       
00106       Hierarchy();
00107 
00112       void addCoarser(Arguments& args);
00113       
00114       
00119       void addFiner(Arguments& args);
00120 
00127       template<class C, class T1>
00128       class LevelIterator 
00129         : public BidirectionalIteratorFacade<LevelIterator<C,T1>,T1,T1&>
00130       {
00131         friend class LevelIterator<typename remove_const<C>::type,
00132                                    typename remove_const<T1>::type >;
00133         friend class LevelIterator<const typename remove_const<C>::type, 
00134                                    const typename remove_const<T1>::type >;
00135 
00136       public:
00138         LevelIterator()
00139           : element_(0)
00140         {}
00141         
00142         LevelIterator(Element* element)
00143           : element_(element)
00144         {}
00145         
00147         LevelIterator(const LevelIterator<typename remove_const<C>::type,
00148                       typename remove_const<T1>::type>& other)
00149           : element_(other.element_)
00150         {}
00151         
00153         LevelIterator(const LevelIterator<const typename remove_const<C>::type,
00154                       const typename remove_const<T1>::type>& other)
00155           : element_(other.element_)
00156         {}
00157 
00161         bool equals(const LevelIterator<typename remove_const<C>::type, 
00162                     typename remove_const<T1>::type>& other) const
00163         {
00164           return element_ == other.element_;
00165         }
00166         
00170         bool equals(const LevelIterator<const typename remove_const<C>::type, 
00171                     const typename remove_const<T1>::type>& other) const
00172         {
00173           return element_ == other.element_;
00174         }
00175 
00177         T1& dereference() const
00178         {
00179           return *(element_->element_);
00180         }
00181         
00183         void increment()
00184         {
00185           element_ = element_->coarser_;
00186         }
00187         
00189         void decrement()
00190         {
00191           element_ = element_->finer_;
00192         }
00193         
00198         bool isRedistributed() const
00199         {
00200           return element_->redistributed_;
00201         }
00202         
00207         T1& getRedistributed() const
00208         {
00209           assert(element_->redistributed_);
00210           return *element_->redistributed_;
00211         }
00212         
00213       private:
00214         Element* element_;
00215       };
00216       
00218       typedef LevelIterator<Hierarchy<T,A>,T> Iterator;
00219 
00221       typedef LevelIterator<const Hierarchy<T,A>, const T> ConstIterator;
00222 
00227       Iterator finest();
00228       
00233       Iterator coarsest();
00234       
00235       
00240       ConstIterator finest() const;
00241       
00246       ConstIterator coarsest() const;
00247 
00252       int levels() const;
00253       
00255       ~Hierarchy();
00256       
00257     private:
00259       Element* finest_;
00261       Element* coarsest_;
00263       Element* nonAllocated_;
00265       Allocator allocator_;
00267       int levels_;
00268     };
00269     
00276     template<class M, class PI, class A=std::allocator<M> >
00277     class MatrixHierarchy
00278     {
00279     public:
00281       typedef M MatrixOperator;
00282       
00284       typedef typename MatrixOperator::matrix_type Matrix;
00285 
00287       typedef PI ParallelInformation;
00288       
00290       typedef A Allocator;
00291 
00293       typedef Dune::Amg::AggregatesMap<typename MatrixGraph<Matrix>::VertexDescriptor> AggregatesMap;
00294 
00296       typedef Dune::Amg::Hierarchy<MatrixOperator,Allocator> ParallelMatrixHierarchy;
00297 
00299       typedef Dune::Amg::Hierarchy<ParallelInformation,Allocator> ParallelInformationHierarchy;
00300 
00302       typedef typename Allocator::template rebind<AggregatesMap*>::other AAllocator;
00303       
00305       typedef std::list<AggregatesMap*,AAllocator> AggregatesMapList;
00306 
00312       MatrixHierarchy(const MatrixOperator& fineMatrix,
00313                       const ParallelInformation& pinfo=ParallelInformation());
00314       
00315       
00316       ~MatrixHierarchy();
00317       
00323       template<typename O, typename T>
00324       void build(const T& criterion);
00325 
00333       template<class F>
00334       void recalculateGalerkin(const F& copyFlags);
00335 
00340       template<class V, class TA>
00341       void coarsenVector(Hierarchy<BlockVector<V,TA> >& hierarchy) const;
00342 
00348       template<class S, class TA>
00349       void coarsenSmoother(Hierarchy<S,TA>& smoothers, 
00350                            const typename SmootherTraits<S>::Arguments& args) const;
00351       
00356       int levels() const;
00357 
00362       bool isBuilt() const;
00363 
00368       const ParallelMatrixHierarchy& matrices() const;
00369       
00374       const ParallelInformationHierarchy& parallelInformation() const;
00375       
00380       const AggregatesMapList& aggregatesMaps() const;
00381       
00382     private:
00383       typedef typename ConstructionTraits<MatrixOperator>::Arguments MatrixArgs;
00385       AggregatesMapList aggregatesMaps_;
00387       ParallelMatrixHierarchy matrices_;
00389       ParallelInformationHierarchy parallelInformation_;
00390 
00392       bool built_;
00393 
00397       template<class Matrix, bool print>
00398       struct MatrixStats
00399       {
00400         
00404         static void stats(const Matrix& matrix)
00405         {}
00406       };
00407       
00408       template<class Matrix>
00409       struct MatrixStats<Matrix,true>
00410       {
00411         struct calc
00412         {
00413           typedef typename Matrix::size_type size_type;
00414           typedef typename Matrix::row_type matrix_row;
00415           
00416           calc()
00417           {
00418             min=std::numeric_limits<size_type>::max();
00419             max=0;
00420             sum=0;
00421           }
00422           
00423           void operator()(const matrix_row& row)
00424           {
00425             min=std::min(min, row.size());
00426             max=std::max(max, row.size());
00427             sum += row.size();
00428           }
00429           
00430           size_type min;
00431           size_type max;
00432           size_type sum;
00433         };
00437         static void stats(const Matrix& matrix)
00438         {
00439           calc c= for_each(matrix.begin(), matrix.end(), calc());
00440           dinfo<<"Matrix row: min="<<c.min<<" max="<<c.max
00441                <<" average="<<static_cast<double>(c.sum)/matrix.N()
00442                <<std::endl;
00443         }
00444       };
00445     };
00446 
00450     template<class T>
00451     class CoarsenCriterion : public T
00452     {
00453     public:
00458       typedef T DependencyCriterion;
00459       
00463       void setMaxLevel(int l)
00464       {
00465         maxLevel_ = l;
00466       }
00470       int maxLevel() const
00471       {
00472         return maxLevel_;
00473       }
00474       
00478       void setCoarsenTarget(int nodes)
00479       {
00480         coarsenTarget_ = nodes;
00481       }
00482       
00486       int coarsenTarget() const
00487       {
00488         return coarsenTarget_;
00489       }
00490       
00496       void setMinCoarsenRate(double rate)
00497       {
00498         minCoarsenRate_ = rate;
00499       }
00500       
00504       double minCoarsenRate() const
00505       {
00506         return minCoarsenRate_;
00507       }
00511       bool accumulate() const
00512       {
00513         return false;
00514       }
00515       
00524       CoarsenCriterion(int maxLevel=100, int coarsenTarget=1000, double minCoarsenRate=1.2)
00525         : T(), maxLevel_(maxLevel), coarsenTarget_(coarsenTarget), minCoarsenRate_(minCoarsenRate)
00526       {}
00527       
00528     private:
00532       int maxLevel_;
00536       int coarsenTarget_;
00540       double minCoarsenRate_;
00541     };
00542     
00543 
00544     template<class M, class IS, class A>
00545     MatrixHierarchy<M,IS,A>::MatrixHierarchy(const MatrixOperator& fineOperator,
00546                                              const ParallelInformation& pinfo)
00547       : matrices_(const_cast<MatrixOperator&>(fineOperator)),
00548         parallelInformation_(const_cast<ParallelInformation&>(pinfo))
00549     {
00550       dune_static_assert((static_cast<int>(MatrixOperator::category) == static_cast<int>(SolverCategory::sequential) ||
00551         static_cast<int>(MatrixOperator::category) == static_cast<int>(SolverCategory::overlapping)),
00552                          "MatrixOperator must be of category sequential or overlapping");
00553       dune_static_assert((static_cast<int>(MatrixOperator::category) == static_cast<int>(ParallelInformation::category)),
00554                          "MatrixOperator and ParallelInformation must belong to the same category!");
00555     }
00556     
00557     template<class M, class IS, class A>
00558     template<typename O, typename T>
00559     void MatrixHierarchy<M,IS,A>::build(const T& criterion)
00560     {
00561       typedef O OverlapFlags;
00562       typedef typename ParallelMatrixHierarchy::Iterator MatIterator;
00563       typedef typename ParallelInformationHierarchy::Iterator PInfoIterator;
00564       
00565       GalerkinProduct<ParallelInformation> productBuilder;
00566       MatIterator mlevel = matrices_.finest();
00567       MatrixStats<typename M::matrix_type,MINIMAL_DEBUG_LEVEL>=INFO_DEBUG_LEVEL>::stats(mlevel->getmat());
00568       
00569       PInfoIterator infoLevel = parallelInformation_.finest();
00570       
00571       
00572       int procs = infoLevel->communicator().size();
00573       int level = 0;
00574       int rank = 0;
00575       int unknowns = mlevel->getmat().N();;
00576 
00577       unknowns = infoLevel->communicator().sum(unknowns);
00578       infoLevel->buildGlobalLookup(mlevel->getmat().N());
00579 
00580       for(; level < criterion.maxLevel(); ++level, ++mlevel){
00581 
00582         rank = infoLevel->communicator().rank();
00583         dverb<<infoLevel->communicator().rank()<<": Level "<<level<<" has "<<mlevel->getmat().N()<<" unknows!"<<std::endl;
00584         if(MINIMAL_DEBUG_LEVEL>=INFO_DEBUG_LEVEL && rank==0)
00585             dinfo<<"Level "<<level<<" has "<<unknowns<<" unknowns, "<<unknowns/infoLevel->communicator().size()<<" unknowns per proc"<<std::endl;
00586 
00587         if(unknowns <= criterion.coarsenTarget())
00588            // No further coarsening needed
00589            break;
00590 
00591         typedef PropertiesGraphCreator<MatrixOperator> GraphCreator;
00592         typedef typename GraphCreator::PropertiesGraph PropertiesGraph;
00593         typedef typename GraphCreator::MatrixGraph MatrixGraph;
00594         typedef typename GraphCreator::GraphTuple  GraphTuple;
00595 
00596         typedef typename PropertiesGraph::VertexDescriptor Vertex;
00597         
00598         std::vector<bool> excluded(mlevel->getmat().N(), false);
00599 
00600         GraphTuple graphs = GraphCreator::create(*mlevel, excluded, *infoLevel, OverlapFlags());
00601         
00602         AggregatesMap* aggregatesMap=new AggregatesMap(Element<1>::get(graphs)->maxVertex());
00603 
00604         aggregatesMaps_.push_back(aggregatesMap);
00605                 
00606         Timer watch;
00607         watch.reset();
00608         int noAggregates, isoAggregates, oneAggregates;
00609         
00610         tie(noAggregates, isoAggregates, oneAggregates) =       
00611           aggregatesMap->buildAggregates(mlevel->getmat(), *(Element<1>::get(graphs)), criterion);
00612 
00613 #ifdef TEST_AGGLO
00614  {
00615         // calculate size of local matrix in the distributed direction
00616         int start, end, overlapStart, overlapEnd;
00617         int n = UNKNOWNS/procs; // number of unknowns per process
00618         int bigger = UNKNOWNS%procs; // number of process with n+1 unknows
00619         int procs=infoLevel->communicator().rank();
00620 
00621         // Compute owner region
00622         if(rank<bigger){
00623           start = rank*(n+1);
00624           end   = (rank+1)*(n+1);
00625         }else{
00626           start = bigger + rank * n;
00627           end   = bigger + (rank + 1) * n;
00628         }
00629   
00630         // Compute overlap region
00631         if(start>0)
00632           overlapStart = start - 1;
00633         else
00634           overlapStart = start;
00635         
00636         if(end<UNKNOWNS)
00637           overlapEnd = end + 1;
00638         else
00639           overlapEnd = end;
00640   
00641         int noKnown = overlapEnd-overlapStart;
00642         int offset = start-overlapStart;
00643         int starti = 1;//(start-overlapStart==0)?1:0;
00644         int endi = (overlapEnd-end==0)?end-start-1:end-start;
00645         
00646         for(int j=1; j< UNKNOWNS-1; ++j)
00647           for(int i=starti; i < endi; ++i)
00648             (*aggregatesMap)[j*(overlapEnd-overlapStart)+i+offset]=((j-1)/2)*(endi-starti)/2+((i-starti)/2);
00649         noAggregates=((UNKNOWNS-2)/2)*(endi-starti)/2;
00650  }
00651 #endif
00652         noAggregates = infoLevel->communicator().sum(noAggregates);
00653 
00654         if(MINIMAL_DEBUG_LEVEL>=INFO_DEBUG_LEVEL && rank==0)
00655           dinfo << "Building "<<noAggregates<<" aggregates took "<<watch.elapsed()<<" seconds."<<std::endl;     
00656 
00657         if(!noAggregates || unknowns/noAggregates<criterion.minCoarsenRate())
00658     {
00659           if(procs>1 && criterion.accumulate())
00660             DUNE_THROW(NotImplemented, "Accumulation to fewer processes not yet implemented!");
00661           else{
00662             if(MINIMAL_DEBUG_LEVEL>=INFO_DEBUG_LEVEL && rank==0)
00663         {
00664               if(noAggregates)
00665             dinfo << "Stopped coarsening because of rate breakdown "<<unknowns/noAggregates<<"<"
00666                   <<criterion.minCoarsenRate()<<std::endl;
00667               else
00668             dinfo << "Could not build any aggregates. Probably no connected nodes."<<std::endl;
00669         }
00670             aggregatesMap->free();
00671             delete aggregatesMap;
00672             aggregatesMaps_.pop_back();
00673             break;
00674           }
00675     }
00676         unknowns =  noAggregates;
00677             
00678         if(noAggregates < criterion.coarsenTarget() && procs>1 && criterion.accumulate()){
00679           DUNE_THROW(NotImplemented, "Accumulation to fewer processes not yet implemented!");
00680         }
00681                 
00682         parallelInformation_.addCoarser(infoLevel->communicator());
00683         
00684         PInfoIterator fineInfo = infoLevel++;
00685                 
00686         typename PropertyMapTypeSelector<VertexVisitedTag,PropertiesGraph>::Type visitedMap = 
00687           get(VertexVisitedTag(), *(Element<1>::get(graphs)));
00688   
00689         watch.reset();
00690         int aggregates = IndicesCoarsener<ParallelInformation,OverlapFlags>
00691           ::coarsen(*fineInfo,
00692                     *(Element<1>::get(graphs)),
00693                     visitedMap,
00694                     *aggregatesMap,
00695                     *infoLevel);
00696 
00697         dinfo<< rank<<": agglomeration achieved "<<aggregates<<" aggregates"<<std::endl;
00698         
00699         GraphCreator::free(graphs);
00700         
00701         if(MINIMAL_DEBUG_LEVEL>=INFO_DEBUG_LEVEL){
00702           infoLevel->communicator().barrier();
00703           if(rank==0)
00704             dinfo<<"Coarsening of index sets took "<<watch.elapsed()<<" seconds."<<std::endl;
00705         }
00706         
00707         watch.reset();
00708 
00709         infoLevel->buildGlobalLookup(aggregates);
00710         AggregatesPublisher<Vertex,OverlapFlags,ParallelInformation>::publish(*aggregatesMap,
00711                                                                               *fineInfo,
00712                                                                               infoLevel->globalLookup());
00713         
00714                 
00715         if(MINIMAL_DEBUG_LEVEL>=INFO_DEBUG_LEVEL){
00716           infoLevel->communicator().barrier();
00717           if(rank==0)
00718             dinfo<<"Communicating global aggregate numbers took "<<watch.elapsed()<<" seconds."<<std::endl;
00719         }
00720 
00721         watch.reset();
00722         std::vector<bool>& visited=excluded;
00723         
00724         typedef std::vector<bool>::iterator Iterator;
00725         typedef IteratorPropertyMap<Iterator, IdentityMap> VisitedMap2;
00726         Iterator end = visited.end();
00727         for(Iterator iter= visited.begin(); iter != end; ++iter)
00728           *iter=false;
00729         
00730         VisitedMap2 visitedMap2(visited.begin(), Dune::IdentityMap());
00731 
00732         typename MatrixOperator::matrix_type* coarseMatrix;
00733 
00734         coarseMatrix = productBuilder.build(mlevel->getmat(), *(Element<0>::get(graphs)), visitedMap2, 
00735                                             *fineInfo, 
00736                                             *aggregatesMap,
00737                                             aggregates,
00738                                             OverlapFlags());
00739         
00740         fineInfo->freeGlobalLookup();
00741         
00742         delete Element<0>::get(graphs);
00743         productBuilder.calculate(mlevel->getmat(), *aggregatesMap, *coarseMatrix, *infoLevel, OverlapFlags());
00744         
00745         if(MINIMAL_DEBUG_LEVEL>=INFO_DEBUG_LEVEL){
00746           infoLevel->communicator().barrier();
00747           if(rank==0)
00748             dinfo<<"Calculation of Galerkin product took "<<watch.elapsed()<<" seconds."<<std::endl;
00749         }
00750         
00751         MatrixArgs args(*coarseMatrix, *infoLevel);
00752         
00753         matrices_.addCoarser(args);
00754       }
00755 
00756       infoLevel->freeGlobalLookup();
00757       
00758       built_=true;
00759       AggregatesMap* aggregatesMap=new AggregatesMap(0);
00760       aggregatesMaps_.push_back(aggregatesMap);
00761 
00762       if(MINIMAL_DEBUG_LEVEL>=INFO_DEBUG_LEVEL)
00763         if(level==criterion.maxLevel()){
00764           int unknowns = mlevel->getmat().N();
00765           unknowns = infoLevel->communicator().sum(unknowns);
00766           if(rank==0)
00767             dinfo<<"Level "<<level<<" has "<<unknowns<<" unknowns, "<<unknowns/infoLevel->communicator().size()<<" unknowns per proc"<<std::endl;
00768         }
00769     }
00770     
00771     template<class M, class IS, class A>
00772     const typename MatrixHierarchy<M,IS,A>::ParallelMatrixHierarchy& 
00773     MatrixHierarchy<M,IS,A>::matrices() const
00774     {
00775       return matrices_;
00776     }
00777     
00778     template<class M, class IS, class A>
00779     const typename MatrixHierarchy<M,IS,A>::ParallelInformationHierarchy& 
00780     MatrixHierarchy<M,IS,A>::parallelInformation() const
00781     {
00782       return parallelInformation_;
00783     }
00784     
00785     template<class M, class IS, class A>
00786     const typename MatrixHierarchy<M,IS,A>::AggregatesMapList& 
00787     MatrixHierarchy<M,IS,A>::aggregatesMaps() const
00788     {
00789       return aggregatesMaps_;
00790     }
00791     template<class M, class IS, class A>
00792     MatrixHierarchy<M,IS,A>::~MatrixHierarchy()
00793     {
00794       typedef typename AggregatesMapList::reverse_iterator AggregatesMapIterator;
00795       typedef typename ParallelMatrixHierarchy::Iterator Iterator;
00796       typedef typename ParallelInformationHierarchy::Iterator InfoIterator;
00797       
00798       AggregatesMapIterator amap = aggregatesMaps_.rbegin();
00799       InfoIterator info = parallelInformation_.coarsest();
00800       for(Iterator level=matrices_.coarsest(), finest=matrices_.finest(); level != finest;  --level, --info, ++amap){
00801         (*amap)->free();
00802         delete *amap;
00803         delete &level->getmat();
00804       }
00805       delete *amap;
00806     }
00807 
00808     template<class M, class IS, class A>
00809     template<class V, class TA>
00810     void MatrixHierarchy<M,IS,A>::coarsenVector(Hierarchy<BlockVector<V,TA> >& hierarchy) const
00811     {
00812       assert(hierarchy.levels()==1);
00813       typedef typename ParallelMatrixHierarchy::ConstIterator Iterator;
00814       Iterator coarsest = matrices_.coarsest();
00815       int level=0;
00816       Dune::dvverb<<"Level "<<level<<" has "<<matrices_.finest()->getmat().N()<<" unknows!"<<std::endl;
00817       
00818       for(Iterator matrix = matrices_.finest(); matrix != coarsest;){
00819         ++matrix;
00820         ++level;
00821         Dune::dvverb<<"Level "<<level<<" has "<<matrix->getmat().N()<<" unknows!"<<std::endl;
00822         hierarchy.addCoarser(matrix->getmat().N());
00823       }
00824     }
00825     
00826     template<class M, class IS, class A>
00827     template<class S, class TA>
00828     void MatrixHierarchy<M,IS,A>::coarsenSmoother(Hierarchy<S,TA>& smoothers, 
00829                                                     const typename SmootherTraits<S>::Arguments& sargs) const
00830     {
00831       assert(smoothers.levels()==0);
00832       typedef typename ParallelMatrixHierarchy::ConstIterator MatrixIterator;
00833       typedef typename ParallelInformationHierarchy::ConstIterator PinfoIterator;
00834       typedef typename AggregatesMapList::const_iterator AggregatesIterator;
00835       
00836       typename ConstructionTraits<S>::Arguments cargs;
00837       cargs.setArgs(sargs);
00838       PinfoIterator pinfo = parallelInformation_.finest();
00839       AggregatesIterator aggregates = aggregatesMaps_.begin();
00840       for(MatrixIterator matrix = matrices_.finest(), coarsest = matrices_.coarsest(); 
00841           matrix != coarsest; ++matrix, ++pinfo, ++aggregates){
00842         cargs.setMatrix(matrix->getmat(), **aggregates);
00843         cargs.setComm(*pinfo);
00844         smoothers.addCoarser(cargs);
00845       }
00846     }
00847     
00848     template<class M, class IS, class A>
00849     template<class F>
00850     void MatrixHierarchy<M,IS,A>::recalculateGalerkin(const F& copyFlags)
00851     {
00852       typedef typename AggregatesMapList::iterator AggregatesMapIterator;
00853       typedef typename ParallelMatrixHierarchy::Iterator Iterator;
00854       typedef typename ParallelInformationHierarchy::Iterator InfoIterator;
00855       
00856       AggregatesMapIterator amap = aggregatesMaps_.begin();
00857       BaseGalerkinProduct productBuilder;
00858       InfoIterator info = parallelInformation_.finest();
00859       
00860       for(Iterator level = matrices_.finest(), coarsest=matrices_.coarsest(); level!=coarsest; ++amap){
00861         const Matrix& fine = level->getmat();
00862         ++level;
00863         ++info;
00864         productBuilder.calculate(fine, *(*amap), const_cast<Matrix&>(level->getmat()), *info, copyFlags);
00865         
00866       }
00867     }
00868 
00869     template<class M, class IS, class A>
00870     int MatrixHierarchy<M,IS,A>::levels() const
00871     {
00872       return matrices_.levels();
00873     }
00874 
00875     template<class M, class IS, class A>
00876     bool MatrixHierarchy<M,IS,A>::isBuilt() const
00877     {
00878       return built_;
00879     }
00880     
00881     template<class T, class A>
00882     Hierarchy<T,A>::Hierarchy()
00883       : finest_(0), coarsest_(0), nonAllocated_(0), allocator_(), levels_(0)
00884     {}
00885 
00886     template<class T, class A>
00887     Hierarchy<T,A>::Hierarchy(MemberType& first)
00888       : allocator_()
00889     {
00890       finest_ = allocator_.allocate(1,0);
00891       finest_->element_ = &first;
00892       finest_->redistributed_ = 0;
00893       nonAllocated_ = finest_;
00894       coarsest_ = finest_;
00895       coarsest_->coarser_ = coarsest_->finer_ = 0;
00896       levels_ = 1;
00897     }
00898 
00899     template<class T, class A>
00900     Hierarchy<T,A>::~Hierarchy()
00901     {
00902       while(coarsest_){
00903         Element* current = coarsest_;
00904         coarsest_ = coarsest_->finer_;
00905         if(current != nonAllocated_){
00906           ConstructionTraits<T>::deconstruct(current->element_);
00907         }
00908         allocator_.deallocate(current, 1);
00909         //coarsest_->coarser_ = 0;
00910       }
00911     }
00912 
00913     template<class T, class A>
00914     int Hierarchy<T,A>::levels() const
00915     {
00916       return levels_;
00917     }
00918 
00919     template<class T, class A>
00920     void Hierarchy<T,A>::addCoarser(Arguments& args)
00921     {
00922       if(!coarsest_){
00923         assert(!finest_);
00924         coarsest_ = allocator_.allocate(1,0);
00925         coarsest_->element_ = ConstructionTraits<MemberType>::construct(args);
00926         finest_ = coarsest_;
00927         coarsest_->finer_ = 0;
00928         coarsest_->redistributed_ = 0;
00929       }else{
00930         coarsest_->coarser_ = allocator_.allocate(1,0);
00931         coarsest_->coarser_->finer_ = coarsest_;
00932         coarsest_ = coarsest_->coarser_;
00933         coarsest_->element_ = ConstructionTraits<MemberType>::construct(args);
00934         finest_->redistributed_ = 0;
00935       }
00936       coarsest_->coarser_=0;
00937       ++levels_;
00938     }
00939     
00940     template<class T, class A>
00941     void Hierarchy<T,A>::addFiner(Arguments& args)
00942     {
00943       if(!finest_){
00944         assert(!coarsest_);
00945         finest_ = allocator_.allocate(1,0);
00946         finest_->element = ConstructionTraits<T>::construct(args);
00947         coarsest_ = finest_;
00948         coarsest_->coarser_ = coarsest_->finer_ = 0;
00949       }else{
00950         finest_->finer_ = allocator_.allocate(1,0);
00951         finest_->finer_->coarser_ = finest_;
00952         finest_ = finest_->finer_;
00953         finest_->finer = 0;
00954         finest_->element = ConstructionTraits<T>::construct(args);
00955       }
00956       ++levels_;
00957     }
00958 
00959     template<class T, class A>
00960     typename Hierarchy<T,A>::Iterator Hierarchy<T,A>::finest()
00961     {
00962       return Iterator(finest_);
00963     }
00964 
00965     template<class T, class A>
00966     typename Hierarchy<T,A>::Iterator Hierarchy<T,A>::coarsest()
00967     {
00968       return Iterator(coarsest_);
00969     }
00970 
00971     template<class T, class A>
00972     typename Hierarchy<T,A>::ConstIterator Hierarchy<T,A>::finest() const
00973     {
00974       return ConstIterator(finest_);
00975     }
00976 
00977     template<class T, class A>
00978     typename Hierarchy<T,A>::ConstIterator Hierarchy<T,A>::coarsest() const
00979     {
00980       return ConstIterator(coarsest_);
00981     }
00983   }// namespace Amg
00984 }// namespace Dune
00985 
00986 #endif

Generated on Thu Apr 2 10:40:14 2009 for dune-istl by  doxygen 1.5.6