indicescoarsener.hh

Go to the documentation of this file.
00001 // $Id: indicescoarsener.hh 1036 2009-07-02 15:36:45Z mnolte $
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 
00191     template<typename G, typename L, typename E>
00192     class IndicesCoarsener<OwnerOverlapCopyCommunication<G,L>,E>
00193       : public ParallelIndicesCoarsener<OwnerOverlapCopyCommunication<G,L>,E>
00194     {};
00195     
00196     template<typename T,typename E>
00197     class IndicesCoarsener<ParallelInformation<T>,E>
00198       : public ParallelIndicesCoarsener<ParallelInformation<T>,E>
00199     {};
00200     
00201 
00202 #endif    
00203 
00210     template<typename E>
00211     class IndicesCoarsener<SequentialInformation,E>
00212     {
00213     public:
00214       template<typename Graph, typename VM>
00215       static typename Graph::VertexDescriptor 
00216       coarsen(const SequentialInformation& fineInfo,
00217               Graph& fineGraph,
00218               VM& visitedMap,
00219               AggregatesMap<typename Graph::VertexDescriptor>& aggregates,
00220               SequentialInformation& coarseInfo);
00221     };
00222 
00223 #if HAVE_MPI
00224     template<typename T, typename E>
00225     template<typename Graph, typename VM>
00226     inline typename Graph::VertexDescriptor 
00227     ParallelIndicesCoarsener<T,E>::coarsen(ParallelInformation& fineInfo,
00228                                    Graph& fineGraph,
00229                                    VM& visitedMap,
00230                                    AggregatesMap<typename Graph::VertexDescriptor>& aggregates,
00231                                    ParallelInformation& coarseInfo)
00232     {
00233       ParallelAggregateRenumberer<Graph,typename ParallelInformation::GlobalLookupIndexSet> renumberer(aggregates, fineInfo.globalLookup());
00234       buildCoarseIndexSet(fineInfo, fineGraph, visitedMap, aggregates, 
00235                           coarseInfo.indexSet(), renumberer);
00236       buildCoarseRemoteIndices(fineInfo.remoteIndices(), aggregates, coarseInfo.indexSet(), 
00237                                coarseInfo.remoteIndices(), renumberer);
00238 
00239       return renumberer;
00240     }
00241     
00242     template<typename T, typename E>
00243     template<typename Graph, typename VM, typename I>
00244     void ParallelIndicesCoarsener<T,E>::buildCoarseIndexSet(const ParallelInformation& pinfo,
00245                                                     Graph& fineGraph,
00246                                                     VM& visitedMap,
00247                                                     AggregatesMap<typename Graph::VertexDescriptor>& aggregates,
00248                                                     ParallelIndexSet& coarseIndices,
00249                                                     ParallelAggregateRenumberer<Graph,I>& renumberer)
00250     {
00251       typedef typename Graph::VertexDescriptor Vertex;       
00252       typedef typename Graph::ConstVertexIterator Iterator;
00253       typedef typename ParallelInformation::GlobalLookupIndexSet GlobalLookupIndexSet;
00254       
00255       Iterator end = fineGraph.end();
00256       const GlobalLookupIndexSet& lookup = pinfo.globalLookup();
00257       
00258       coarseIndices.beginResize();
00259 
00260       // Setup the coarse index set and renumber the aggregate consecutively
00261       // ascending from zero according to the minimum global index belonging
00262       // to the aggregate
00263       for(Iterator index = fineGraph.begin(); index != end; ++index){
00264         if(aggregates[*index]!=AggregatesMap<typename Graph::VertexDescriptor>::ISOLATED)         
00265           if(!get(visitedMap, *index)){
00266             
00267             typedef typename GlobalLookupIndexSet::IndexPair IndexPair;   
00268             const IndexPair* pair= lookup.pair(*index);
00269               
00270             renumberer.reset();
00271             if(pair!=0 && !ExcludedAttributes::contains(pair->local().attribute())){
00272               renumberer.attribute(pair->local().attribute());
00273               renumberer.isPublic(pair->local().isPublic());
00274               renumberer.globalIndex(pair->global());
00275             }
00276              
00277             // Reconstruct aggregate and mark vertices as visited
00278             aggregates.template breadthFirstSearch<false>(*index, aggregates[*index], 
00279                                                             fineGraph, renumberer, visitedMap);
00280             
00281             typedef typename GlobalLookupIndexSet::IndexPair::GlobalIndex GlobalIndex;
00282             
00283             if(renumberer.globalIndex()!=std::numeric_limits<GlobalIndex>::max()){
00284               //std::cout <<" Adding global="<< renumberer.globalIndex()<<" local="<<static_cast<std::size_t>(renumberer)<<std::endl;
00285               coarseIndices.add(renumberer.globalIndex(), 
00286                                 LocalIndex(renumberer, renumberer.attribute(), 
00287                                            renumberer.isPublic()));
00288             }
00289             
00290             aggregates[*index] = renumberer;
00291             ++renumberer;
00292           }
00293       }
00294 
00295       coarseIndices.endResize();
00296 
00297       assert(static_cast<std::size_t>(renumberer) >= coarseIndices.size());
00298       
00299       // Reset the visited flags      
00300       for(Iterator vertex=fineGraph.begin(); vertex != end; ++vertex)
00301         put(visitedMap, *vertex, false);      
00302     }
00303     
00304     template<typename T, typename E>
00305     template<typename Graph, typename I>
00306     void ParallelIndicesCoarsener<T,E>::buildCoarseRemoteIndices(const RemoteIndices& fineRemote,
00307                                                          const AggregatesMap<typename Graph::VertexDescriptor>& aggregates,
00308                                                          ParallelIndexSet& coarseIndices,
00309                                                          RemoteIndices& coarseRemote,
00310                                                          ParallelAggregateRenumberer<Graph,I>& renumberer)
00311     {
00312       std::vector<char> attributes(static_cast<std::size_t>(renumberer));
00313 
00314       GlobalLookupIndexSet<ParallelIndexSet> coarseLookup(coarseIndices, static_cast<std::size_t>(renumberer));
00315       
00316       typedef typename RemoteIndices::const_iterator Iterator;
00317       Iterator end = fineRemote.end();
00318       
00319       for(Iterator neighbour = fineRemote.begin();
00320           neighbour != end; ++neighbour){
00321         int process = neighbour->first;
00322         
00323         assert(neighbour->second.first==neighbour->second.second);
00324         
00325         // Mark all as not known
00326         typedef typename std::vector<char>::iterator CIterator;
00327 
00328         for(CIterator iter=attributes.begin(); iter!= attributes.end(); ++iter)
00329           *iter = std::numeric_limits<char>::max();
00330         
00331         typedef typename RemoteIndices::RemoteIndexList::const_iterator Iterator;
00332         Iterator riEnd = neighbour->second.second->end();
00333 
00334         for(Iterator index = neighbour->second.second->begin();
00335             index != riEnd; ++index){
00336           if(!E::contains(index->localIndexPair().local().attribute()) && 
00337              aggregates[index->localIndexPair().local()] != 
00338              AggregatesMap<typename Graph::VertexDescriptor>::ISOLATED)
00339           {
00340             assert(aggregates[index->localIndexPair().local()]<(int)attributes.size());
00341             assert(attributes[aggregates[index->localIndexPair().local()]] == std::numeric_limits<char>::max()
00342                    || attributes[aggregates[index->localIndexPair().local()]] == index->attribute());
00343             attributes[aggregates[index->localIndexPair().local()]] = index->attribute();
00344           }  
00345         }
00346         
00347         // Build remote index list
00348         typedef RemoteIndexListModifier<ParallelIndexSet,false> Modifier;
00349         typedef typename RemoteIndices::RemoteIndex RemoteIndex;
00350         typedef typename ParallelIndexSet::const_iterator IndexIterator;
00351 
00352         Modifier coarseList = coarseRemote.template getModifier<false,true>(process);
00353         
00354         IndexIterator iend = coarseIndices.end();
00355         for(IndexIterator index = coarseIndices.begin(); index != iend; ++index)
00356           if(attributes[index->local()] != std::numeric_limits<char>::max()){
00357             // remote index is present
00358             coarseList.insert(RemoteIndex(Attribute(attributes[index->local()]), &(*index)));
00359           }
00360         //std::cout<<coarseRemote<<std::endl;
00361       }
00362       
00363       // The number of neighbours should not change!
00364       assert(coarseRemote.neighbours()==fineRemote.neighbours());
00365       
00366       // snyc the index set and the remote indices to recompute missing
00367       // indices
00368       IndicesSyncer<ParallelIndexSet> syncer(coarseIndices, coarseRemote);
00369       syncer.sync(renumberer);
00370       
00371     }
00372 
00373 #endif
00374 
00375     template<typename E>
00376     template<typename Graph, typename VM>
00377     typename Graph::VertexDescriptor 
00378     IndicesCoarsener<SequentialInformation,E>::coarsen(const SequentialInformation& fineInfo,
00379                                                        Graph& fineGraph,
00380                                                        VM& visitedMap,
00381                                                        AggregatesMap<typename Graph::VertexDescriptor>& aggregates,
00382                                                        SequentialInformation& coarseInfo)
00383     {
00384       typedef typename Graph::VertexDescriptor Vertex;
00385       AggregateRenumberer<Graph> renumberer(aggregates);
00386       typedef typename Graph::VertexIterator Iterator;
00387       
00388       for(Iterator vertex=fineGraph.begin(), endVertex=fineGraph.end();
00389           vertex != endVertex; ++vertex)
00390         if(aggregates[*vertex]!=AggregatesMap<Vertex>::ISOLATED && 
00391            !get(visitedMap, *vertex)){
00392 
00393           aggregates.template breadthFirstSearch<false>(*vertex, aggregates[*vertex], 
00394                                                         fineGraph, renumberer, visitedMap);
00395           aggregates[*vertex] = renumberer;
00396           ++renumberer;
00397         }
00398         
00399       for(Iterator vertex=fineGraph.begin(), endVertex=fineGraph.end();
00400           vertex != endVertex; ++vertex)
00401         put(visitedMap, *vertex, false);
00402 
00403       return renumberer;
00404     }
00405     
00406   } //namespace Amg
00407 } // namespace Dune
00408 #endif

Generated on Sun Nov 15 22:29:36 2009 for dune-istl by  doxygen 1.5.6