dune-istl  2.8.0
indicescoarsener.hh
Go to the documentation of this file.
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 #ifndef DUNE_AMG_INDICESCOARSENER_HH
4 #define DUNE_AMG_INDICESCOARSENER_HH
5 
6 #include <dune/common/parallel/indicessyncer.hh>
7 #include <vector>
8 #include "renumberer.hh"
9 
10 #if HAVE_MPI
12 #endif
13 
14 #include "pinfo.hh"
15 
16 namespace Dune
17 {
18  namespace Amg
19  {
20 
32  template<typename T, typename E>
34  {};
35 
36 
37 #if HAVE_MPI
38 
39  template<typename T, typename E>
41  {
42  public:
46  typedef E ExcludedAttributes;
47 
52 
53  typedef typename ParallelInformation::ParallelIndexSet ParallelIndexSet;
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
89  Graph& fineGraph,
90  VM& visitedMap,
92  ParallelInformation& coarseInfo,
93  typename Graph::VertexDescriptor noAggregates);
94 
95  private:
96  template<typename G, typename I>
97  class ParallelAggregateRenumberer : public AggregateRenumberer<G>
98  {
99  typedef typename G::VertexDescriptor Vertex;
100 
101  typedef I GlobalLookupIndexSet;
102 
103  typedef typename GlobalLookupIndexSet::IndexPair IndexPair;
104 
105  typedef typename IndexPair::GlobalIndex GlobalIndex;
106 
107  public:
109  : AggregateRenumberer<G>(aggregates), isPublic_(false), lookup_(lookup),
110  globalIndex_(std::numeric_limits<GlobalIndex>::max())
111  {}
112 
113 
114  void operator()(const typename G::ConstEdgeIterator& edge)
115  {
117  const IndexPair* pair= lookup_.pair(edge.target());
118  if(pair!=0) {
119  globalIndex(pair->global());
120  attribute(pair->local().attribute());
121  isPublic(pair->local().isPublic());
122  }
123  }
124 
125  Vertex operator()([[maybe_unused]] const GlobalIndex& global)
126  {
127  Vertex current = this->number_;
128  this->operator++();
129  return current;
130  }
131 
132  bool isPublic()
133  {
134  return isPublic_;
135  }
136 
137  void isPublic(bool b)
138  {
139  isPublic_ = isPublic_ || b;
140  }
141 
142  void reset()
143  {
144  globalIndex_ = std::numeric_limits<GlobalIndex>::max();
145  isPublic_=false;
146  }
147 
148  void attribute(const Attribute& attribute)
149  {
150  attribute_=attribute;
151  }
152 
154  {
155  return attribute_;
156  }
157 
158  const GlobalIndex& globalIndex() const
159  {
160  return globalIndex_;
161  }
162 
163  void globalIndex(const GlobalIndex& global)
164  {
165  globalIndex_ = global;
166  }
167 
168  private:
169  bool isPublic_;
170  Attribute attribute_;
171  const GlobalLookupIndexSet& lookup_;
172  GlobalIndex globalIndex_;
173  };
174 
175  template<typename Graph, typename VM, typename I>
176  static void buildCoarseIndexSet(const ParallelInformation& pinfo,
177  Graph& fineGraph,
178  VM& visitedMap,
180  ParallelIndexSet& coarseIndices,
181  ParallelAggregateRenumberer<Graph,I>& renumberer);
182 
183  template<typename Graph,typename I>
184  static void buildCoarseRemoteIndices(const RemoteIndices& fineRemote,
186  ParallelIndexSet& coarseIndices,
187  RemoteIndices& coarseRemote,
188  ParallelAggregateRenumberer<Graph,I>& renumberer);
189 
190  };
191 
195  template<typename G, typename L, typename E>
197  : public ParallelIndicesCoarsener<OwnerOverlapCopyCommunication<G,L>,E>
198  {};
199 
200 
201 #endif
202 
209  template<typename E>
211  {
212  public:
213  template<typename Graph, typename VM>
214  static typename Graph::VertexDescriptor
215  coarsen(const SequentialInformation & fineInfo,
216  Graph& fineGraph,
217  VM& visitedMap,
219  SequentialInformation& coarseInfo,
220  typename Graph::VertexDescriptor noAggregates);
221  };
222 
223 #if HAVE_MPI
224  template<typename T, typename E>
225  template<typename Graph, typename VM>
226  inline typename Graph::VertexDescriptor
228  Graph& fineGraph,
229  VM& visitedMap,
231  ParallelInformation& coarseInfo,
232  [[maybe_unused]] typename Graph::VertexDescriptor noAggregates)
233  {
234  ParallelAggregateRenumberer<Graph,typename ParallelInformation::GlobalLookupIndexSet> renumberer(aggregates, fineInfo.globalLookup());
235  buildCoarseIndexSet(fineInfo, fineGraph, visitedMap, aggregates,
236  coarseInfo.indexSet(), renumberer);
237  buildCoarseRemoteIndices(fineInfo.remoteIndices(), aggregates, coarseInfo.indexSet(),
238  coarseInfo.remoteIndices(), renumberer);
239 
240  return renumberer;
241  }
242 
243  template<typename T, typename E>
244  template<typename Graph, typename VM, typename I>
245  void ParallelIndicesCoarsener<T,E>::buildCoarseIndexSet(const ParallelInformation& pinfo,
246  Graph& fineGraph,
247  VM& visitedMap,
249  ParallelIndexSet& coarseIndices,
250  ParallelAggregateRenumberer<Graph,I>& renumberer)
251  {
252  // fineGraph is the local subgraph corresponding to the vertices the process owns.
253  // i.e. no overlap/copy vertices can be visited traversing the graph
254  typedef typename Graph::ConstVertexIterator Iterator;
255  typedef typename ParallelInformation::GlobalLookupIndexSet GlobalLookupIndexSet;
256 
257  Iterator end = fineGraph.end();
258  const GlobalLookupIndexSet& lookup = pinfo.globalLookup();
259 
260  coarseIndices.beginResize();
261 
262  // Setup the coarse index set and renumber the aggregate consecutively
263  // ascending from zero according to the minimum global index belonging
264  // to the aggregate
265  for(Iterator index = fineGraph.begin(); index != end; ++index) {
267  // Isolated vertices will not be represented on the next level.
268  // These should only be there if skipIsolated is activiated in
269  // the coarsening criterion as otherwise they will be aggregated
270  // and should have real aggregate number in the map right now.
271  if(!get(visitedMap, *index)) {
272  // This vertex was not visited by breadthFirstSearch yet.
273  typedef typename GlobalLookupIndexSet::IndexPair IndexPair;
274  const IndexPair* pair= lookup.pair(*index);
275 
276  renumberer.reset(); // reset attribute and global index.
277  if(pair!=0) {
278  // vertex is in the index set. Note that not all vertices have
279  // to be in the index set, just the ones where communication
280  // will happen.
281  assert(!ExcludedAttributes::contains(pair->local().attribute()));
282  renumberer.attribute(pair->local().attribute());
283  renumberer.isPublic(pair->local().isPublic());
284  renumberer.globalIndex(pair->global());
285  }
286 
287  // Reconstruct aggregate and mark vertices as visited
288  aggregates.template breadthFirstSearch<false>(*index, aggregates[*index],
289  fineGraph, renumberer, visitedMap);
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  auto riEnd = neighbour->second.second->end();
341 
342  for(auto index = neighbour->second.second->begin();
343  index != riEnd; ++index) {
344  if(!E::contains(index->localIndexPair().local().attribute()) &&
345  aggregates[index->localIndexPair().local()] !=
347  {
348  assert(aggregates[index->localIndexPair().local()]<attributes.size());
349  if (attributes[aggregates[index->localIndexPair().local()]] != 3)
350  attributes[aggregates[index->localIndexPair().local()]] = index->attribute();
351  }
352  }
353 
354  // Build remote index list
355  typedef RemoteIndexListModifier<ParallelIndexSet,typename RemoteIndices::Allocator,false> Modifier;
356  typedef typename RemoteIndices::RemoteIndex RemoteIndex;
357  typedef typename ParallelIndexSet::const_iterator IndexIterator;
358 
359  Modifier coarseList = coarseRemote.template getModifier<false,true>(process);
360 
361  IndexIterator iend = coarseIndices.end();
362  for(IndexIterator index = coarseIndices.begin(); index != iend; ++index)
363  if(attributes[index->local()] != std::numeric_limits<char>::max()) {
364  // remote index is present
365  coarseList.insert(RemoteIndex(Attribute(attributes[index->local()]), &(*index)));
366  }
367  //std::cout<<coarseRemote<<std::endl;
368  }
369 
370  // The number of neighbours should not change!
371  assert(coarseRemote.neighbours()==fineRemote.neighbours());
372 
373  // snyc the index set and the remote indices to recompute missing
374  // indices
375  IndicesSyncer<ParallelIndexSet> syncer(coarseIndices, coarseRemote);
376  syncer.sync(renumberer);
377 
378  }
379 
380 #endif
381 
382  template<typename E>
383  template<typename Graph, typename VM>
384  typename Graph::VertexDescriptor
386  [[maybe_unused]] const SequentialInformation& fineInfo,
387  [[maybe_unused]] Graph& fineGraph,
388  [[maybe_unused]] VM& visitedMap,
389  [[maybe_unused]] AggregatesMap<typename Graph::VertexDescriptor>& aggregates,
390  [[maybe_unused]] SequentialInformation& coarseInfo,
391  [[maybe_unused]] typename Graph::VertexDescriptor noAggregates)
392  {
393  return noAggregates;
394  }
395 
396  } //namespace Amg
397 } // namespace Dune
398 #endif
Classes providing communication interfaces for overlapping Schwarz methods.
static Graph::VertexDescriptor coarsen(const SequentialInformation &fineInfo, Graph &fineGraph, VM &visitedMap, AggregatesMap< typename Graph::VertexDescriptor > &aggregates, SequentialInformation &coarseInfo, typename Graph::VertexDescriptor noAggregates)
LocalIndex::Attribute Attribute
The type of the attribute.
Definition: indicescoarsener.hh:68
void operator()(const typename G::ConstEdgeIterator &edge)
Definition: indicescoarsener.hh:114
void isPublic(bool b)
Definition: indicescoarsener.hh:137
static Graph::VertexDescriptor coarsen(ParallelInformation &fineInfo, Graph &fineGraph, VM &visitedMap, AggregatesMap< typename Graph::VertexDescriptor > &aggregates, ParallelInformation &coarseInfo, typename Graph::VertexDescriptor noAggregates)
Build the coarse index set after the aggregatio.
ParallelInformation::ParallelIndexSet ParallelIndexSet
Definition: indicescoarsener.hh:53
bool isPublic()
Definition: indicescoarsener.hh:132
const GlobalIndex & globalIndex() const
Definition: indicescoarsener.hh:158
ParallelIndexSet::LocalIndex LocalIndex
The type of the local index.
Definition: indicescoarsener.hh:63
T ParallelInformation
The type of the parallel information.
Definition: indicescoarsener.hh:51
Attribute attribute()
Definition: indicescoarsener.hh:153
static const V ISOLATED
Identifier of isolated vertices.
Definition: aggregates.hh:569
ParallelIndexSet::GlobalIndex GlobalIndex
The type of the global index.
Definition: indicescoarsener.hh:58
void attribute(const Attribute &attribute)
Definition: indicescoarsener.hh:148
E ExcludedAttributes
The set of excluded attributes.
Definition: indicescoarsener.hh:46
void globalIndex(const GlobalIndex &global)
Definition: indicescoarsener.hh:163
Dune::RemoteIndices< ParallelIndexSet > RemoteIndices
The type of the remote indices.
Definition: indicescoarsener.hh:73
Vertex operator()([[maybe_unused]] const GlobalIndex &global)
Definition: indicescoarsener.hh:125
ParallelAggregateRenumberer(AggregatesMap< Vertex > &aggregates, const I &lookup)
Definition: indicescoarsener.hh:108
Definition: allocator.hh:9
PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > >::Type get([[maybe_unused]] const Amg::VertexVisitedTag &tag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)
Definition: dependency.hh:291
A class setting up standard communication for a two-valued attribute set with owner/overlap/copy sema...
Definition: owneroverlapcopy.hh:172
Class providing information about the mapping of the vertices onto aggregates.
Definition: aggregates.hh:558
Definition: indicescoarsener.hh:34
Definition: indicescoarsener.hh:41
Definition: pinfo.hh:26
Definition: renumberer.hh:14
void operator++()
Definition: renumberer.hh:55
void operator()(const typename G::ConstEdgeIterator &edge)
Definition: renumberer.hh:49
Vertex number_
Definition: renumberer.hh:33