00001
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
00261
00262
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
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
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
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
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
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
00358 coarseList.insert(RemoteIndex(Attribute(attributes[index->local()]), &(*index)));
00359 }
00360
00361 }
00362
00363
00364 assert(coarseRemote.neighbours()==fineRemote.neighbours());
00365
00366
00367
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 }
00407 }
00408 #endif