dune-istl  2.9.0
indicescoarsener.hh
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
2 // SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
3 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
4 // vi: set et ts=4 sw=2 sts=2:
5 #ifndef DUNE_AMG_INDICESCOARSENER_HH
6 #define DUNE_AMG_INDICESCOARSENER_HH
7 
8 #include <dune/common/parallel/indicessyncer.hh>
9 #include <vector>
10 #include "renumberer.hh"
11 
12 #if HAVE_MPI
14 #endif
15 
16 #include "pinfo.hh"
17 
18 namespace Dune
19 {
20  namespace Amg
21  {
22 
34  template<typename T, typename E>
36  {};
37 
38 
39 #if HAVE_MPI
40 
41  template<typename T, typename E>
43  {
44  public:
48  typedef E ExcludedAttributes;
49 
54 
55  typedef typename ParallelInformation::ParallelIndexSet ParallelIndexSet;
56 
60  typedef typename ParallelIndexSet::GlobalIndex GlobalIndex;
61 
65  typedef typename ParallelIndexSet::LocalIndex LocalIndex;
66 
70  typedef typename LocalIndex::Attribute Attribute;
71 
75  typedef Dune::RemoteIndices<ParallelIndexSet> RemoteIndices;
76 
88  template<typename Graph, typename VM>
89  static typename Graph::VertexDescriptor
91  Graph& fineGraph,
92  VM& visitedMap,
94  ParallelInformation& coarseInfo,
95  typename Graph::VertexDescriptor noAggregates);
96 
97  private:
98  template<typename G, typename I>
99  class ParallelAggregateRenumberer : public AggregateRenumberer<G>
100  {
101  typedef typename G::VertexDescriptor Vertex;
102 
103  typedef I GlobalLookupIndexSet;
104 
105  typedef typename GlobalLookupIndexSet::IndexPair IndexPair;
106 
107  typedef typename IndexPair::GlobalIndex GlobalIndex;
108 
109  public:
111  : AggregateRenumberer<G>(aggregates), isPublic_(false), lookup_(lookup),
112  globalIndex_(std::numeric_limits<GlobalIndex>::max())
113  {}
114 
115 
116  void operator()(const typename G::ConstEdgeIterator& edge)
117  {
119  const IndexPair* pair= lookup_.pair(edge.target());
120  if(pair!=0) {
121  globalIndex(pair->global());
122  attribute(pair->local().attribute());
123  isPublic(pair->local().isPublic());
124  }
125  }
126 
127  Vertex operator()([[maybe_unused]] const GlobalIndex& global)
128  {
129  Vertex current = this->number_;
130  this->operator++();
131  return current;
132  }
133 
134  bool isPublic()
135  {
136  return isPublic_;
137  }
138 
139  void isPublic(bool b)
140  {
141  isPublic_ = isPublic_ || b;
142  }
143 
144  void reset()
145  {
146  globalIndex_ = std::numeric_limits<GlobalIndex>::max();
147  isPublic_=false;
148  }
149 
150  void attribute(const Attribute& attribute)
151  {
152  attribute_=attribute;
153  }
154 
156  {
157  return attribute_;
158  }
159 
160  const GlobalIndex& globalIndex() const
161  {
162  return globalIndex_;
163  }
164 
165  void globalIndex(const GlobalIndex& global)
166  {
167  globalIndex_ = global;
168  }
169 
170  private:
171  bool isPublic_;
172  Attribute attribute_;
173  const GlobalLookupIndexSet& lookup_;
174  GlobalIndex globalIndex_;
175  };
176 
177  template<typename Graph, typename VM, typename I>
178  static void buildCoarseIndexSet(const ParallelInformation& pinfo,
179  Graph& fineGraph,
180  VM& visitedMap,
182  ParallelIndexSet& coarseIndices,
183  ParallelAggregateRenumberer<Graph,I>& renumberer);
184 
185  template<typename Graph,typename I>
186  static void buildCoarseRemoteIndices(const RemoteIndices& fineRemote,
188  ParallelIndexSet& coarseIndices,
189  RemoteIndices& coarseRemote,
190  ParallelAggregateRenumberer<Graph,I>& renumberer);
191 
192  };
193 
197  template<typename G, typename L, typename E>
199  : public ParallelIndicesCoarsener<OwnerOverlapCopyCommunication<G,L>,E>
200  {};
201 
202 
203 #endif
204 
211  template<typename E>
213  {
214  public:
215  template<typename Graph, typename VM>
216  static typename Graph::VertexDescriptor
217  coarsen(const SequentialInformation & fineInfo,
218  Graph& fineGraph,
219  VM& visitedMap,
221  SequentialInformation& coarseInfo,
222  typename Graph::VertexDescriptor noAggregates);
223  };
224 
225 #if HAVE_MPI
226  template<typename T, typename E>
227  template<typename Graph, typename VM>
228  inline typename Graph::VertexDescriptor
230  Graph& fineGraph,
231  VM& visitedMap,
233  ParallelInformation& coarseInfo,
234  [[maybe_unused]] typename Graph::VertexDescriptor noAggregates)
235  {
236  ParallelAggregateRenumberer<Graph,typename ParallelInformation::GlobalLookupIndexSet> renumberer(aggregates, fineInfo.globalLookup());
237  buildCoarseIndexSet(fineInfo, fineGraph, visitedMap, aggregates,
238  coarseInfo.indexSet(), renumberer);
239  buildCoarseRemoteIndices(fineInfo.remoteIndices(), aggregates, coarseInfo.indexSet(),
240  coarseInfo.remoteIndices(), renumberer);
241 
242  return renumberer;
243  }
244 
245  template<typename T, typename E>
246  template<typename Graph, typename VM, typename I>
247  void ParallelIndicesCoarsener<T,E>::buildCoarseIndexSet(const ParallelInformation& pinfo,
248  Graph& fineGraph,
249  VM& visitedMap,
251  ParallelIndexSet& coarseIndices,
252  ParallelAggregateRenumberer<Graph,I>& renumberer)
253  {
254  // fineGraph is the local subgraph corresponding to the vertices the process owns.
255  // i.e. no overlap/copy vertices can be visited traversing the graph
256  typedef typename Graph::ConstVertexIterator Iterator;
257  typedef typename ParallelInformation::GlobalLookupIndexSet GlobalLookupIndexSet;
258 
259  Iterator end = fineGraph.end();
260  const GlobalLookupIndexSet& lookup = pinfo.globalLookup();
261 
262  coarseIndices.beginResize();
263 
264  // Setup the coarse index set and renumber the aggregate consecutively
265  // ascending from zero according to the minimum global index belonging
266  // to the aggregate
267  for(Iterator index = fineGraph.begin(); index != end; ++index) {
269  // Isolated vertices will not be represented on the next level.
270  // These should only be there if skipIsolated is activiated in
271  // the coarsening criterion as otherwise they will be aggregated
272  // and should have real aggregate number in the map right now.
273  if(!get(visitedMap, *index)) {
274  // This vertex was not visited by breadthFirstSearch yet.
275  typedef typename GlobalLookupIndexSet::IndexPair IndexPair;
276  const IndexPair* pair= lookup.pair(*index);
277 
278  renumberer.reset(); // reset attribute and global index.
279  if(pair!=0) {
280  // vertex is in the index set. Note that not all vertices have
281  // to be in the index set, just the ones where communication
282  // will happen.
283  assert(!ExcludedAttributes::contains(pair->local().attribute()));
284  renumberer.attribute(pair->local().attribute());
285  renumberer.isPublic(pair->local().isPublic());
286  renumberer.globalIndex(pair->global());
287  }
288 
289  // Reconstruct aggregate and mark vertices as visited
290  aggregates.template breadthFirstSearch<false>(*index, aggregates[*index],
291  fineGraph, renumberer, visitedMap);
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:70
void operator()(const typename G::ConstEdgeIterator &edge)
Definition: indicescoarsener.hh:116
void isPublic(bool b)
Definition: indicescoarsener.hh:139
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:55
bool isPublic()
Definition: indicescoarsener.hh:134
const GlobalIndex & globalIndex() const
Definition: indicescoarsener.hh:160
ParallelIndexSet::LocalIndex LocalIndex
The type of the local index.
Definition: indicescoarsener.hh:65
T ParallelInformation
The type of the parallel information.
Definition: indicescoarsener.hh:53
Attribute attribute()
Definition: indicescoarsener.hh:155
static const V ISOLATED
Identifier of isolated vertices.
Definition: aggregates.hh:571
ParallelIndexSet::GlobalIndex GlobalIndex
The type of the global index.
Definition: indicescoarsener.hh:60
void attribute(const Attribute &attribute)
Definition: indicescoarsener.hh:150
E ExcludedAttributes
The set of excluded attributes.
Definition: indicescoarsener.hh:48
void globalIndex(const GlobalIndex &global)
Definition: indicescoarsener.hh:165
Dune::RemoteIndices< ParallelIndexSet > RemoteIndices
The type of the remote indices.
Definition: indicescoarsener.hh:75
Vertex operator()([[maybe_unused]] const GlobalIndex &global)
Definition: indicescoarsener.hh:127
ParallelAggregateRenumberer(AggregatesMap< Vertex > &aggregates, const I &lookup)
Definition: indicescoarsener.hh:110
Definition: allocator.hh:11
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:293
A class setting up standard communication for a two-valued attribute set with owner/overlap/copy sema...
Definition: owneroverlapcopy.hh:174
Class providing information about the mapping of the vertices onto aggregates.
Definition: aggregates.hh:560
Definition: indicescoarsener.hh:36
Definition: indicescoarsener.hh:43
Definition: pinfo.hh:28
Definition: renumberer.hh:16
void operator++()
Definition: renumberer.hh:57
void operator()(const typename G::ConstEdgeIterator &edge)
Definition: renumberer.hh:51
Vertex number_
Definition: renumberer.hh:35