dune-istl  2.2.0
indicescoarsener.hh
Go to the documentation of this file.
1 // $Id: indicescoarsener.hh 1444 2011-01-23 17:24:33Z rebecca $
2 #ifndef DUNE_AMG_INDICESCOARSENER_HH
3 #define DUNE_AMG_INDICESCOARSENER_HH
4 
5 #include<dune/common/parallel/indicessyncer.hh>
6 #include<vector>
7 #include"renumberer.hh"
8 
9 #if HAVE_MPI
11 #endif
12 
13 #include"pinfo.hh"
14 
15 namespace Dune
16 {
17  namespace Amg
18  {
19 
31  template<typename T, typename E>
33  {
34  };
35 
36 
37 #if HAVE_MPI
38 
39  template<typename T, typename E>
41  {
42  public:
46  typedef E ExcludedAttributes;
47 
52 
54 
58  typedef typename ParallelIndexSet::GlobalIndex GlobalIndex;
59 
63  typedef typename ParallelIndexSet::LocalIndex LocalIndex;
64 
68  typedef typename LocalIndex::Attribute Attribute;
69 
73  typedef Dune::RemoteIndices<ParallelIndexSet> RemoteIndices;
74 
86  template<typename Graph, typename VM>
87  static typename Graph::VertexDescriptor
88  coarsen(ParallelInformation& fineInfo,
89  Graph& fineGraph,
90  VM& visitedMap,
92  ParallelInformation& coarseInfo);
93 
94  private:
95  template<typename G, typename I>
96  class ParallelAggregateRenumberer: public AggregateRenumberer<G>
97  {
98  typedef typename G::VertexDescriptor Vertex;
99 
100  typedef I GlobalLookupIndexSet;
101 
102  typedef typename GlobalLookupIndexSet::IndexPair IndexPair;
103 
104  typedef typename IndexPair::GlobalIndex GlobalIndex;
105 
106  public:
107  ParallelAggregateRenumberer(AggregatesMap<Vertex>& aggregates, const I& lookup)
108  : AggregateRenumberer<G>(aggregates), isPublic_(false), lookup_(lookup),
109  globalIndex_(std::numeric_limits<GlobalIndex>::max())
110  {}
111 
112 
113  void operator()(const typename G::ConstEdgeIterator& edge)
114  {
116  const IndexPair* pair= lookup_.pair(edge.target());
117  if(pair!=0){
118  globalIndex(pair->global());
119  attribute(pair->local().attribute());
120  isPublic(pair->local().isPublic());
121  }
122  }
123 
124  Vertex operator()(const GlobalIndex& global)
125  {
126  Vertex current = this->number_;
127  this->operator++();
128  return current;
129  }
130 
131  bool isPublic()
132  {
133  return isPublic_;
134  }
135 
136  void isPublic(bool b)
137  {
138  isPublic_ = isPublic_ || b;
139  }
140 
141  void reset()
142  {
143  globalIndex_ = std::numeric_limits<GlobalIndex>::max();
144  isPublic_=false;
145  }
146 
147  void attribute(const Attribute& attribute)
148  {
149  attribute_=attribute;
150  }
151 
152  Attribute attribute()
153  {
154  return attribute_;
155  }
156 
157  const GlobalIndex& globalIndex() const
158  {
159  return globalIndex_;
160  }
161 
162  void globalIndex(const GlobalIndex& global)
163  {
164  globalIndex_ = global;
165  }
166 
167  private:
168  bool isPublic_;
169  Attribute attribute_;
170  const GlobalLookupIndexSet& lookup_;
171  GlobalIndex globalIndex_;
172  };
173 
174  template<typename Graph, typename VM, typename I>
175  static void buildCoarseIndexSet(const ParallelInformation& pinfo,
176  Graph& fineGraph,
177  VM& visitedMap,
179  ParallelIndexSet& coarseIndices,
180  ParallelAggregateRenumberer<Graph,I>& renumberer);
181 
182  template<typename Graph,typename I>
183  static void buildCoarseRemoteIndices(const RemoteIndices& fineRemote,
185  ParallelIndexSet& coarseIndices,
186  RemoteIndices& coarseRemote,
187  ParallelAggregateRenumberer<Graph,I>& renumberer);
188 
189  };
190 
194  template<typename G, typename L, typename E>
196  : public ParallelIndicesCoarsener<OwnerOverlapCopyCommunication<G,L>,E>
197  {};
198 
199 
200 #endif
201 
208  template<typename E>
210  {
211  public:
212  template<typename Graph, typename VM>
213  static typename Graph::VertexDescriptor
214  coarsen(const SequentialInformation& fineInfo,
215  Graph& fineGraph,
216  VM& visitedMap,
218  SequentialInformation& coarseInfo);
219  };
220 
221 #if HAVE_MPI
222  template<typename T, typename E>
223  template<typename Graph, typename VM>
224  inline typename Graph::VertexDescriptor
226  Graph& fineGraph,
227  VM& visitedMap,
229  ParallelInformation& coarseInfo)
230  {
231  ParallelAggregateRenumberer<Graph,typename ParallelInformation::GlobalLookupIndexSet> renumberer(aggregates, fineInfo.globalLookup());
232  buildCoarseIndexSet(fineInfo, fineGraph, visitedMap, aggregates,
233  coarseInfo.indexSet(), renumberer);
234  buildCoarseRemoteIndices(fineInfo.remoteIndices(), aggregates, coarseInfo.indexSet(),
235  coarseInfo.remoteIndices(), renumberer);
236 
237  return renumberer;
238  }
239 
240  template<typename T, typename E>
241  template<typename Graph, typename VM, typename I>
242  void ParallelIndicesCoarsener<T,E>::buildCoarseIndexSet(const ParallelInformation& pinfo,
243  Graph& fineGraph,
244  VM& visitedMap,
246  ParallelIndexSet& coarseIndices,
247  ParallelAggregateRenumberer<Graph,I>& renumberer)
248  {
249  // fineGraph is the local subgraph corresponding to the vertices the process owns.
250  // i.e. no overlap/copy vertices can be visited traversing the graph
251  typedef typename Graph::VertexDescriptor Vertex;
252  typedef typename Graph::ConstVertexIterator Iterator;
253  typedef typename ParallelInformation::GlobalLookupIndexSet GlobalLookupIndexSet;
254 
255  Iterator end = fineGraph.end();
256  const GlobalLookupIndexSet& lookup = pinfo.globalLookup();
257 
258  coarseIndices.beginResize();
259 
260  // Setup the coarse index set and renumber the aggregate consecutively
261  // ascending from zero according to the minimum global index belonging
262  // to the aggregate
263  for(Iterator index = fineGraph.begin(); index != end; ++index){
265  // Isolated vertices will not be represented on the next level.
266  // These should only be there if skipIsolated is activiated in
267  // the coarsening criterion as otherwise they will be aggregated
268  // and should have real aggregate number in the map right now.
269  if(!get(visitedMap, *index)){
270  // This vertex was not visited by breadthFirstSearch yet.
271  typedef typename GlobalLookupIndexSet::IndexPair IndexPair;
272  const IndexPair* pair= lookup.pair(*index);
273 
274  renumberer.reset(); // reset attribute and global index.
275  if(pair!=0){
276  // vertex is in the index set. Note that not all vertices have
277  // to be in the index set, just the ones where communication
278  // will happen.
279  assert(!ExcludedAttributes::contains(pair->local().attribute()));
280  renumberer.attribute(pair->local().attribute());
281  renumberer.isPublic(pair->local().isPublic());
282  renumberer.globalIndex(pair->global());
283  }
284 
285  // Reconstruct aggregate and mark vertices as visited
286  aggregates.template breadthFirstSearch<false>(*index, aggregates[*index],
287  fineGraph, renumberer, visitedMap);
288 
289  typedef typename GlobalLookupIndexSet::IndexPair::GlobalIndex GlobalIndex;
290 
291  if(renumberer.globalIndex()!=std::numeric_limits<GlobalIndex>::max()){
292  // vertex is in the index set.
293  //std::cout <<" Adding global="<< renumberer.globalIndex()<<" local="<<static_cast<std::size_t>(renumberer)<<std::endl;
294  coarseIndices.add(renumberer.globalIndex(),
295  LocalIndex(renumberer, renumberer.attribute(),
296  renumberer.isPublic()));
297  }
298 
299  aggregates[*index] = renumberer;
300  ++renumberer;
301  }
302  }
303 
304  coarseIndices.endResize();
305 
306  assert(static_cast<std::size_t>(renumberer) >= coarseIndices.size());
307 
308  // Reset the visited flags
309  for(Iterator vertex=fineGraph.begin(); vertex != end; ++vertex)
310  put(visitedMap, *vertex, false);
311  }
312 
313  template<typename T, typename E>
314  template<typename Graph, typename I>
315  void ParallelIndicesCoarsener<T,E>::buildCoarseRemoteIndices(const RemoteIndices& fineRemote,
316  const AggregatesMap<typename Graph::VertexDescriptor>& aggregates,
317  ParallelIndexSet& coarseIndices,
318  RemoteIndices& coarseRemote,
319  ParallelAggregateRenumberer<Graph,I>& renumberer)
320  {
321  std::vector<char> attributes(static_cast<std::size_t>(renumberer));
322 
323  GlobalLookupIndexSet<ParallelIndexSet> coarseLookup(coarseIndices, static_cast<std::size_t>(renumberer));
324 
325  typedef typename RemoteIndices::const_iterator Iterator;
326  Iterator end = fineRemote.end();
327 
328  for(Iterator neighbour = fineRemote.begin();
329  neighbour != end; ++neighbour){
330  int process = neighbour->first;
331 
332  assert(neighbour->second.first==neighbour->second.second);
333 
334  // Mark all as not known
335  typedef typename std::vector<char>::iterator CIterator;
336 
337  for(CIterator iter=attributes.begin(); iter!= attributes.end(); ++iter)
338  *iter = std::numeric_limits<char>::max();
339 
340  typedef typename RemoteIndices::RemoteIndexList::const_iterator Iterator;
341  Iterator riEnd = neighbour->second.second->end();
342 
343  for(Iterator index = neighbour->second.second->begin();
344  index != riEnd; ++index){
345  if(!E::contains(index->localIndexPair().local().attribute()) &&
346  aggregates[index->localIndexPair().local()] !=
347  AggregatesMap<typename Graph::VertexDescriptor>::ISOLATED)
348  {
349  assert(aggregates[index->localIndexPair().local()]<attributes.size());
350  if (attributes[aggregates[index->localIndexPair().local()]] != 3)
351  attributes[aggregates[index->localIndexPair().local()]] = index->attribute();
352  }
353  }
354 
355  // Build remote index list
356  typedef RemoteIndexListModifier<ParallelIndexSet,typename RemoteIndices::Allocator,false> Modifier;
357  typedef typename RemoteIndices::RemoteIndex RemoteIndex;
358  typedef typename ParallelIndexSet::const_iterator IndexIterator;
359 
360  Modifier coarseList = coarseRemote.template getModifier<false,true>(process);
361 
362  IndexIterator iend = coarseIndices.end();
363  for(IndexIterator index = coarseIndices.begin(); index != iend; ++index)
364  if(attributes[index->local()] != std::numeric_limits<char>::max()){
365  // remote index is present
366  coarseList.insert(RemoteIndex(Attribute(attributes[index->local()]), &(*index)));
367  }
368  //std::cout<<coarseRemote<<std::endl;
369  }
370 
371  // The number of neighbours should not change!
372  assert(coarseRemote.neighbours()==fineRemote.neighbours());
373 
374  // snyc the index set and the remote indices to recompute missing
375  // indices
376  IndicesSyncer<ParallelIndexSet> syncer(coarseIndices, coarseRemote);
377  syncer.sync(renumberer);
378 
379  }
380 
381 #endif
382 
383  template<typename E>
384  template<typename Graph, typename VM>
385  typename Graph::VertexDescriptor
387  Graph& fineGraph,
388  VM& visitedMap,
390  SequentialInformation& coarseInfo)
391  {
392  typedef typename Graph::VertexDescriptor Vertex;
393  AggregateRenumberer<Graph> renumberer(aggregates);
394  typedef typename Graph::VertexIterator Iterator;
395 
396  for(Iterator vertex=fineGraph.begin(), endVertex=fineGraph.end();
397  vertex != endVertex; ++vertex)
398  if(aggregates[*vertex]!=AggregatesMap<Vertex>::ISOLATED &&
399  !get(visitedMap, *vertex)){
400 
401  aggregates.template breadthFirstSearch<false>(*vertex, aggregates[*vertex],
402  fineGraph, renumberer, visitedMap);
403  aggregates[*vertex] = renumberer;
404  ++renumberer;
405  }
406 
407  for(Iterator vertex=fineGraph.begin(), endVertex=fineGraph.end();
408  vertex != endVertex; ++vertex)
409  put(visitedMap, *vertex, false);
410 
411  return renumberer;
412  }
413 
414  } //namespace Amg
415 } // namespace Dune
416 #endif