indicescoarsener.hh

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

Generated on 6 Nov 2008 with Doxygen (ver 1.5.6) [logfile].