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  typedef typename GlobalLookupIndexSet::IndexPair::GlobalIndex GlobalIndex;
292 
293  if(renumberer.globalIndex()!=std::numeric_limits<GlobalIndex>::max()) {
294  // vertex is in the index set.
295  //std::cout <<" Adding global="<< renumberer.globalIndex()<<" local="<<static_cast<std::size_t>(renumberer)<<std::endl;
296  coarseIndices.add(renumberer.globalIndex(),
297  LocalIndex(renumberer, renumberer.attribute(),
298  renumberer.isPublic()));
299  }
300 
301  aggregates[*index] = renumberer;
302  ++renumberer;
303  }
304  }
305 
306  coarseIndices.endResize();
307 
308  assert(static_cast<std::size_t>(renumberer) >= coarseIndices.size());
309 
310  // Reset the visited flags
311  for(Iterator vertex=fineGraph.begin(); vertex != end; ++vertex)
312  put(visitedMap, *vertex, false);
313  }
314 
315  template<typename T, typename E>
316  template<typename Graph, typename I>
317  void ParallelIndicesCoarsener<T,E>::buildCoarseRemoteIndices(const RemoteIndices& fineRemote,
318  const AggregatesMap<typename Graph::VertexDescriptor>& aggregates,
319  ParallelIndexSet& coarseIndices,
320  RemoteIndices& coarseRemote,
321  ParallelAggregateRenumberer<Graph,I>& renumberer)
322  {
323  std::vector<char> attributes(static_cast<std::size_t>(renumberer));
324 
325  GlobalLookupIndexSet<ParallelIndexSet> coarseLookup(coarseIndices, static_cast<std::size_t>(renumberer));
326 
327  typedef typename RemoteIndices::const_iterator Iterator;
328  Iterator end = fineRemote.end();
329 
330  for(Iterator neighbour = fineRemote.begin();
331  neighbour != end; ++neighbour) {
332  int process = neighbour->first;
333 
334  assert(neighbour->second.first==neighbour->second.second);
335 
336  // Mark all as not known
337  typedef typename std::vector<char>::iterator CIterator;
338 
339  for(CIterator iter=attributes.begin(); iter!= attributes.end(); ++iter)
340  *iter = std::numeric_limits<char>::max();
341 
342  auto riEnd = neighbour->second.second->end();
343 
344  for(auto index = neighbour->second.second->begin();
345  index != riEnd; ++index) {
346  if(!E::contains(index->localIndexPair().local().attribute()) &&
347  aggregates[index->localIndexPair().local()] !=
349  {
350  assert(aggregates[index->localIndexPair().local()]<attributes.size());
351  if (attributes[aggregates[index->localIndexPair().local()]] != 3)
352  attributes[aggregates[index->localIndexPair().local()]] = index->attribute();
353  }
354  }
355 
356  // Build remote index list
357  typedef RemoteIndexListModifier<ParallelIndexSet,typename RemoteIndices::Allocator,false> Modifier;
358  typedef typename RemoteIndices::RemoteIndex RemoteIndex;
359  typedef typename ParallelIndexSet::const_iterator IndexIterator;
360 
361  Modifier coarseList = coarseRemote.template getModifier<false,true>(process);
362 
363  IndexIterator iend = coarseIndices.end();
364  for(IndexIterator index = coarseIndices.begin(); index != iend; ++index)
365  if(attributes[index->local()] != std::numeric_limits<char>::max()) {
366  // remote index is present
367  coarseList.insert(RemoteIndex(Attribute(attributes[index->local()]), &(*index)));
368  }
369  //std::cout<<coarseRemote<<std::endl;
370  }
371 
372  // The number of neighbours should not change!
373  assert(coarseRemote.neighbours()==fineRemote.neighbours());
374 
375  // snyc the index set and the remote indices to recompute missing
376  // indices
377  IndicesSyncer<ParallelIndexSet> syncer(coarseIndices, coarseRemote);
378  syncer.sync(renumberer);
379 
380  }
381 
382 #endif
383 
384  template<typename E>
385  template<typename Graph, typename VM>
386  typename Graph::VertexDescriptor
388  [[maybe_unused]] const SequentialInformation& fineInfo,
389  [[maybe_unused]] Graph& fineGraph,
390  [[maybe_unused]] VM& visitedMap,
391  [[maybe_unused]] AggregatesMap<typename Graph::VertexDescriptor>& aggregates,
392  [[maybe_unused]] SequentialInformation& coarseInfo,
393  [[maybe_unused]] typename Graph::VertexDescriptor noAggregates)
394  {
395  return noAggregates;
396  }
397 
398  } //namespace Amg
399 } // namespace Dune
400 #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