indicescoarsener.hh

Go to the documentation of this file.
00001 // $Id: indicescoarsener.hh 1141 2009-12-04 16:10:03Z mblatt $
00002 #ifndef DUNE_AMG_INDICESCOARSENER_HH
00003 #define DUNE_AMG_INDICESCOARSENER_HH
00004 
00005 #include<dune/istl/indicessyncer.hh>
00006 #include<vector>
00007 #include"renumberer.hh"
00008 
00009 #if HAVE_MPI
00010 #include<dune/istl/owneroverlapcopy.hh>
00011 #endif
00012 
00013 #include"pinfo.hh"
00014 
00015 namespace Dune
00016 {
00017   namespace Amg
00018   {
00019     
00031     template<typename T, typename E>
00032     class IndicesCoarsener
00033     {
00034     };
00035 
00036     
00037 #if HAVE_MPI
00038 
00039     template<typename T, typename E>
00040     class ParallelIndicesCoarsener
00041     {
00042     public:
00046       typedef E ExcludedAttributes;
00047       
00051       typedef T ParallelInformation;
00052       
00053       typedef typename ParallelInformation::ParallelIndexSet ParallelIndexSet;
00054       
00058       typedef typename ParallelIndexSet::GlobalIndex GlobalIndex;
00059       
00063       typedef typename ParallelIndexSet::LocalIndex LocalIndex;
00064 
00068       typedef typename LocalIndex::Attribute Attribute;
00069       
00073       typedef Dune::RemoteIndices<ParallelIndexSet> RemoteIndices;
00074       
00086       template<typename Graph, typename VM>
00087       static typename Graph::VertexDescriptor
00088       coarsen(ParallelInformation& fineInfo,
00089               Graph& fineGraph,
00090               VM& visitedMap,
00091               AggregatesMap<typename Graph::VertexDescriptor>& aggregates,
00092               ParallelInformation& coarseInfo);
00093       
00094     private:
00095       template<typename G, typename I>
00096       class ParallelAggregateRenumberer: public AggregateRenumberer<G>
00097       {
00098         typedef typename G::VertexDescriptor Vertex;
00099 
00100         typedef I GlobalLookupIndexSet;
00101         
00102         typedef typename GlobalLookupIndexSet::IndexPair IndexPair;
00103         
00104         typedef typename IndexPair::GlobalIndex GlobalIndex;
00105         
00106       public:
00107         ParallelAggregateRenumberer(AggregatesMap<Vertex>& aggregates, const I& lookup)
00108           :  AggregateRenumberer<G>(aggregates),  isPublic_(false), lookup_(lookup), 
00109              globalIndex_(std::numeric_limits<GlobalIndex>::max())
00110         {}
00111                 
00112         
00113         void operator()(const typename G::ConstEdgeIterator& edge)
00114         {
00115           AggregateRenumberer<G>::operator()(edge);
00116           const IndexPair* pair= lookup_.pair(edge.target());
00117           if(pair!=0){
00118             globalIndex(pair->global());
00119             attribute(pair->local().attribute());
00120             isPublic(pair->local().isPublic());
00121           }
00122         }
00123         
00124         Vertex operator()(const GlobalIndex& global)
00125         {
00126           Vertex current = this->number_;
00127           this->operator++();
00128           return current;
00129         }
00130         
00131         bool isPublic()
00132         {
00133           return isPublic_;
00134         }
00135         
00136         void isPublic(bool b)
00137         {
00138           isPublic_ = isPublic_ || b;
00139         }
00140         
00141         void reset()
00142         {
00143           globalIndex_ = std::numeric_limits<GlobalIndex>::max();
00144           isPublic_=false;
00145         }
00146 
00147         void attribute(const Attribute& attribute)
00148         {
00149           attribute_=attribute;
00150         }
00151         
00152         Attribute attribute()
00153         {
00154           return attribute_;
00155         }
00156         
00157         const GlobalIndex& globalIndex() const
00158         {
00159           return globalIndex_;
00160         }
00161         
00162         void globalIndex(const GlobalIndex& global)
00163         {
00164           globalIndex_ = global;
00165         }
00166         
00167       private:
00168         bool isPublic_;
00169         Attribute attribute_;
00170         const GlobalLookupIndexSet& lookup_;
00171         GlobalIndex globalIndex_;
00172       };
00173       
00174     template<typename Graph, typename VM, typename I>
00175     static void buildCoarseIndexSet(const ParallelInformation& pinfo,
00176                                     Graph& fineGraph,
00177                                     VM& visitedMap,
00178                                     AggregatesMap<typename Graph::VertexDescriptor>& aggregates,
00179                                     ParallelIndexSet& coarseIndices,
00180                                     ParallelAggregateRenumberer<Graph,I>& renumberer);
00181     
00182       template<typename Graph,typename I>
00183       static void buildCoarseRemoteIndices(const RemoteIndices& fineRemote,
00184                                            const AggregatesMap<typename Graph::VertexDescriptor>& aggregates,
00185                                            ParallelIndexSet& coarseIndices,
00186                                            RemoteIndices& coarseRemote,
00187                                            ParallelAggregateRenumberer<Graph,I>& renumberer);
00188             
00189     };
00190 
00194     template<typename G, typename L, typename E>
00195     class IndicesCoarsener<OwnerOverlapCopyCommunication<G,L>,E>
00196       : public ParallelIndicesCoarsener<OwnerOverlapCopyCommunication<G,L>,E>
00197     {};
00198     
00199 
00200 #endif    
00201 
00208     template<typename E>
00209     class IndicesCoarsener<SequentialInformation,E>
00210     {
00211     public:
00212       template<typename Graph, typename VM>
00213       static typename Graph::VertexDescriptor 
00214       coarsen(const SequentialInformation& fineInfo,
00215               Graph& fineGraph,
00216               VM& visitedMap,
00217               AggregatesMap<typename Graph::VertexDescriptor>& aggregates,
00218               SequentialInformation& coarseInfo);
00219     };
00220 
00221 #if HAVE_MPI
00222     template<typename T, typename E>
00223     template<typename Graph, typename VM>
00224     inline typename Graph::VertexDescriptor 
00225     ParallelIndicesCoarsener<T,E>::coarsen(ParallelInformation& fineInfo,
00226                                    Graph& fineGraph,
00227                                    VM& visitedMap,
00228                                    AggregatesMap<typename Graph::VertexDescriptor>& aggregates,
00229                                    ParallelInformation& coarseInfo)
00230     {
00231       ParallelAggregateRenumberer<Graph,typename ParallelInformation::GlobalLookupIndexSet> renumberer(aggregates, fineInfo.globalLookup());
00232       buildCoarseIndexSet(fineInfo, fineGraph, visitedMap, aggregates, 
00233                           coarseInfo.indexSet(), renumberer);
00234       buildCoarseRemoteIndices(fineInfo.remoteIndices(), aggregates, coarseInfo.indexSet(), 
00235                                coarseInfo.remoteIndices(), renumberer);
00236 
00237       return renumberer;
00238     }
00239     
00240     template<typename T, typename E>
00241     template<typename Graph, typename VM, typename I>
00242     void ParallelIndicesCoarsener<T,E>::buildCoarseIndexSet(const ParallelInformation& pinfo,
00243                                                     Graph& fineGraph,
00244                                                     VM& visitedMap,
00245                                                     AggregatesMap<typename Graph::VertexDescriptor>& aggregates,
00246                                                     ParallelIndexSet& coarseIndices,
00247                                                     ParallelAggregateRenumberer<Graph,I>& renumberer)
00248     {
00249       typedef typename Graph::VertexDescriptor Vertex;       
00250       typedef typename Graph::ConstVertexIterator Iterator;
00251       typedef typename ParallelInformation::GlobalLookupIndexSet GlobalLookupIndexSet;
00252       
00253       Iterator end = fineGraph.end();
00254       const GlobalLookupIndexSet& lookup = pinfo.globalLookup();
00255       
00256       coarseIndices.beginResize();
00257 
00258       // Setup the coarse index set and renumber the aggregate consecutively
00259       // ascending from zero according to the minimum global index belonging
00260       // to the aggregate
00261       for(Iterator index = fineGraph.begin(); index != end; ++index){
00262         if(aggregates[*index]!=AggregatesMap<typename Graph::VertexDescriptor>::ISOLATED)         
00263           if(!get(visitedMap, *index)){
00264             
00265             typedef typename GlobalLookupIndexSet::IndexPair IndexPair;   
00266             const IndexPair* pair= lookup.pair(*index);
00267               
00268             renumberer.reset();
00269             if(pair!=0 && !ExcludedAttributes::contains(pair->local().attribute())){
00270               renumberer.attribute(pair->local().attribute());
00271               renumberer.isPublic(pair->local().isPublic());
00272               renumberer.globalIndex(pair->global());
00273             }
00274              
00275             // Reconstruct aggregate and mark vertices as visited
00276             aggregates.template breadthFirstSearch<false>(*index, aggregates[*index], 
00277                                                             fineGraph, renumberer, visitedMap);
00278             
00279             typedef typename GlobalLookupIndexSet::IndexPair::GlobalIndex GlobalIndex;
00280             
00281             if(renumberer.globalIndex()!=std::numeric_limits<GlobalIndex>::max()){
00282               //std::cout <<" Adding global="<< renumberer.globalIndex()<<" local="<<static_cast<std::size_t>(renumberer)<<std::endl;
00283               coarseIndices.add(renumberer.globalIndex(), 
00284                                 LocalIndex(renumberer, renumberer.attribute(), 
00285                                            renumberer.isPublic()));
00286             }
00287             
00288             aggregates[*index] = renumberer;
00289             ++renumberer;
00290           }
00291       }
00292 
00293       coarseIndices.endResize();
00294 
00295       assert(static_cast<std::size_t>(renumberer) >= coarseIndices.size());
00296       
00297       // Reset the visited flags      
00298       for(Iterator vertex=fineGraph.begin(); vertex != end; ++vertex)
00299         put(visitedMap, *vertex, false);      
00300     }
00301     
00302     template<typename T, typename E>
00303     template<typename Graph, typename I>
00304     void ParallelIndicesCoarsener<T,E>::buildCoarseRemoteIndices(const RemoteIndices& fineRemote,
00305                                                          const AggregatesMap<typename Graph::VertexDescriptor>& aggregates,
00306                                                          ParallelIndexSet& coarseIndices,
00307                                                          RemoteIndices& coarseRemote,
00308                                                          ParallelAggregateRenumberer<Graph,I>& renumberer)
00309     {
00310       std::vector<char> attributes(static_cast<std::size_t>(renumberer));
00311 
00312       GlobalLookupIndexSet<ParallelIndexSet> coarseLookup(coarseIndices, static_cast<std::size_t>(renumberer));
00313       
00314       typedef typename RemoteIndices::const_iterator Iterator;
00315       Iterator end = fineRemote.end();
00316       
00317       for(Iterator neighbour = fineRemote.begin();
00318           neighbour != end; ++neighbour){
00319         int process = neighbour->first;
00320         
00321         assert(neighbour->second.first==neighbour->second.second);
00322         
00323         // Mark all as not known
00324         typedef typename std::vector<char>::iterator CIterator;
00325 
00326         for(CIterator iter=attributes.begin(); iter!= attributes.end(); ++iter)
00327           *iter = std::numeric_limits<char>::max();
00328         
00329         typedef typename RemoteIndices::RemoteIndexList::const_iterator Iterator;
00330         Iterator riEnd = neighbour->second.second->end();
00331 
00332         for(Iterator index = neighbour->second.second->begin();
00333             index != riEnd; ++index){
00334           if(!E::contains(index->localIndexPair().local().attribute()) && 
00335              aggregates[index->localIndexPair().local()] != 
00336              AggregatesMap<typename Graph::VertexDescriptor>::ISOLATED)
00337           {
00338             assert(aggregates[index->localIndexPair().local()]<attributes.size());
00339             assert(attributes[aggregates[index->localIndexPair().local()]] == std::numeric_limits<char>::max()
00340                    || attributes[aggregates[index->localIndexPair().local()]] == index->attribute());
00341             attributes[aggregates[index->localIndexPair().local()]] = index->attribute();
00342           }  
00343         }
00344         
00345         // Build remote index list
00346         typedef RemoteIndexListModifier<ParallelIndexSet,typename RemoteIndices::Allocator,false> Modifier;
00347         typedef typename RemoteIndices::RemoteIndex RemoteIndex;
00348         typedef typename ParallelIndexSet::const_iterator IndexIterator;
00349 
00350         Modifier coarseList = coarseRemote.template getModifier<false,true>(process);
00351         
00352         IndexIterator iend = coarseIndices.end();
00353         for(IndexIterator index = coarseIndices.begin(); index != iend; ++index)
00354           if(attributes[index->local()] != std::numeric_limits<char>::max()){
00355             // remote index is present
00356             coarseList.insert(RemoteIndex(Attribute(attributes[index->local()]), &(*index)));
00357           }
00358         //std::cout<<coarseRemote<<std::endl;
00359       }
00360       
00361       // The number of neighbours should not change!
00362       assert(coarseRemote.neighbours()==fineRemote.neighbours());
00363       
00364       // snyc the index set and the remote indices to recompute missing
00365       // indices
00366       IndicesSyncer<ParallelIndexSet> syncer(coarseIndices, coarseRemote);
00367       syncer.sync(renumberer);
00368       
00369     }
00370 
00371 #endif
00372 
00373     template<typename E>
00374     template<typename Graph, typename VM>
00375     typename Graph::VertexDescriptor 
00376     IndicesCoarsener<SequentialInformation,E>::coarsen(const SequentialInformation& fineInfo,
00377                                                        Graph& fineGraph,
00378                                                        VM& visitedMap,
00379                                                        AggregatesMap<typename Graph::VertexDescriptor>& aggregates,
00380                                                        SequentialInformation& coarseInfo)
00381     {
00382       typedef typename Graph::VertexDescriptor Vertex;
00383       AggregateRenumberer<Graph> renumberer(aggregates);
00384       typedef typename Graph::VertexIterator Iterator;
00385       
00386       for(Iterator vertex=fineGraph.begin(), endVertex=fineGraph.end();
00387           vertex != endVertex; ++vertex)
00388         if(aggregates[*vertex]!=AggregatesMap<Vertex>::ISOLATED && 
00389            !get(visitedMap, *vertex)){
00390 
00391           aggregates.template breadthFirstSearch<false>(*vertex, aggregates[*vertex], 
00392                                                         fineGraph, renumberer, visitedMap);
00393           aggregates[*vertex] = renumberer;
00394           ++renumberer;
00395         }
00396         
00397       for(Iterator vertex=fineGraph.begin(), endVertex=fineGraph.end();
00398           vertex != endVertex; ++vertex)
00399         put(visitedMap, *vertex, false);
00400 
00401       return renumberer;
00402     }
00403     
00404   } //namespace Amg
00405 } // namespace Dune
00406 #endif
Generated on Sat Apr 24 11:13:46 2010 for dune-istl by  doxygen 1.6.3