dune-istl  2.8.0
hierarchy.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_AMGHIERARCHY_HH
4 #define DUNE_AMGHIERARCHY_HH
5 
6 #include <list>
7 #include <memory>
8 #include <limits>
9 #include <dune/common/stdstreams.hh>
10 #include <dune/common/timer.hh>
11 #include <dune/common/bigunsignedint.hh>
13 
14 namespace Dune
15 {
16  namespace Amg
17  {
36  template<typename T, typename A=std::allocator<T> >
37  class Hierarchy
38  {
39  public:
43  typedef T MemberType;
44 
45  template<typename T1, typename T2>
46  class LevelIterator;
47 
48  private:
52  struct Element
53  {
54  friend class LevelIterator<Hierarchy<T,A>, T>;
55  friend class LevelIterator<const Hierarchy<T,A>, const T>;
56 
58  std::weak_ptr<Element> coarser_;
59 
61  std::shared_ptr<Element> finer_;
62 
64  std::shared_ptr<MemberType> element_;
65 
67  std::shared_ptr<MemberType> redistributed_;
68  };
69  public:
70 
74  using Allocator = typename std::allocator_traits<A>::template rebind_alloc<Element>;
75 
77 
82  Hierarchy(const std::shared_ptr<MemberType> & first);
83 
87  Hierarchy() : levels_(0)
88  {}
89 
93  Hierarchy(const Hierarchy& other);
94 
99  void addCoarser(Arguments& args);
100 
102 
107  void addFiner(Arguments& args);
108 
115  template<class C, class T1>
117  : public BidirectionalIteratorFacade<LevelIterator<C,T1>,T1,T1&>
118  {
119  friend class LevelIterator<typename std::remove_const<C>::type,
120  typename std::remove_const<T1>::type >;
121  friend class LevelIterator<const typename std::remove_const<C>::type,
122  const typename std::remove_const<T1>::type >;
123 
124  public:
127  {}
128 
129  LevelIterator(std::shared_ptr<Element> element)
130  : element_(element)
131  {}
132 
134  LevelIterator(const LevelIterator<typename std::remove_const<C>::type,
135  typename std::remove_const<T1>::type>& other)
136  : element_(other.element_)
137  {}
138 
140  LevelIterator(const LevelIterator<const typename std::remove_const<C>::type,
141  const typename std::remove_const<T1>::type>& other)
142  : element_(other.element_)
143  {}
144 
148  bool equals(const LevelIterator<typename std::remove_const<C>::type,
149  typename std::remove_const<T1>::type>& other) const
150  {
151  return element_ == other.element_;
152  }
153 
157  bool equals(const LevelIterator<const typename std::remove_const<C>::type,
158  const typename std::remove_const<T1>::type>& other) const
159  {
160  return element_ == other.element_;
161  }
162 
164  T1& dereference() const
165  {
166  return *(element_->element_);
167  }
168 
170  void increment()
171  {
172  element_ = element_->coarser_.lock();
173  }
174 
176  void decrement()
177  {
178  element_ = element_->finer_;
179  }
180 
185  bool isRedistributed() const
186  {
187  return (bool)element_->redistributed_;
188  }
189 
194  T1& getRedistributed() const
195  {
196  assert(element_->redistributed_);
197  return *element_->redistributed_;
198  }
199  void addRedistributed(std::shared_ptr<T1> t)
200  {
201  element_->redistributed_ = t;
202  }
203 
205  {
206  element_->redistributed_ = nullptr;
207  }
208 
209  private:
210  std::shared_ptr<Element> element_;
211  };
212 
215 
218 
224 
230 
231 
237 
243 
248  std::size_t levels() const;
249 
250  private:
256  std::shared_ptr<MemberType> originalFinest_;
258  std::shared_ptr<Element> finest_;
260  std::shared_ptr<Element> coarsest_;
262  Allocator allocator_;
264  int levels_;
265  };
266 
267  template<class T, class A>
268  Hierarchy<T,A>::Hierarchy(const std::shared_ptr<MemberType> & first)
269  : originalFinest_(first)
270  {
271  finest_ = std::allocate_shared<Element>(allocator_);
272  finest_->element_ = originalFinest_;
273  coarsest_ = finest_;
274  levels_ = 1;
275  }
276 
278  //TODO: do we actually want to support this? This might be very expensive?!
279  template<class T, class A>
281  : allocator_(other.allocator_),
282  levels_(other.levels_)
283  {
284  if(!other.finest_)
285  {
286  finest_=coarsest_=nullptr;
287  return;
288  }
289  finest_ = std::allocate_shared<Element>(allocator_);
290  std::shared_ptr<Element> finer_;
291  std::shared_ptr<Element> current_ = finest_;
292  std::weak_ptr<Element> otherWeak_ = other.finest_;
293 
294  while(! otherWeak_.expired())
295  {
296  // create shared_ptr from weak_ptr, we just checked that this is safe
297  std::shared_ptr<Element> otherCurrent_ = std::shared_ptr<Element>(otherWeak_);
298  // clone current level
299  //TODO: should we use the allocator?
300  current_->element_ =
301  std::make_shared<MemberType>(*(otherCurrent_->element_));
302  current_->finer_=finer_;
303  if(otherCurrent_->redistributed_)
304  current_->redistributed_ =
305  std::make_shared<MemberType>(*(otherCurrent_->redistributed_));
306  finer_=current_;
307  if(not otherCurrent_->coarser_.expired())
308  {
309  auto c = std::allocate_shared<Element>(allocator_);
310  current_->coarser_ = c;
311  current_ = c;
312  }
313  // go to coarser level
314  otherWeak_ = otherCurrent_->coarser_;
315  }
316  coarsest_=current_;
317  }
318 
319  template<class T, class A>
320  std::size_t Hierarchy<T,A>::levels() const
321  {
322  return levels_;
323  }
324 
325  template<class T, class A>
327  {
328  coarsest_->redistributed_ = ConstructionTraits<MemberType>::construct(args);
329  }
330 
331  template<class T, class A>
333  {
334  if(!coarsest_) {
335  // we have no levels at all...
336  assert(!finest_);
337  // allocate into the shared_ptr
338  originalFinest_ = ConstructionTraits<MemberType>::construct(args);
339  coarsest_ = std::allocate_shared<Element>(allocator_);
340  coarsest_->element_ = originalFinest_;
341  finest_ = coarsest_;
342  }else{
343  auto old_coarsest = coarsest_;
344  coarsest_ = std::allocate_shared<Element>(allocator_);
345  coarsest_->finer_ = old_coarsest;
346  coarsest_->element_ = ConstructionTraits<MemberType>::construct(args);
347  old_coarsest->coarser_ = coarsest_;
348  }
349  ++levels_;
350  }
351 
352 
353  template<class T, class A>
355  {
356  //TODO: wouldn't it be better to do this in the constructor?'
357  if(!finest_) {
358  // we have no levels at all...
359  assert(!coarsest_);
360  // allocate into the shared_ptr
361  originalFinest_ = ConstructionTraits<MemberType>::construct(args);
362  finest_ = std::allocate_shared<Element>(allocator_);
363  finest_->element = originalFinest_;
364  coarsest_ = finest_;
365  }else{
366  finest_->finer_ = std::allocate_shared<Element>(allocator_);
367  finest_->finer_->coarser_ = finest_;
368  finest_ = finest_->finer_;
369  finest_->element = ConstructionTraits<T>::construct(args);
370  }
371  ++levels_;
372  }
373 
374  template<class T, class A>
376  {
377  return Iterator(finest_);
378  }
379 
380  template<class T, class A>
382  {
383  return Iterator(coarsest_);
384  }
385 
386  template<class T, class A>
388  {
389  return ConstIterator(finest_);
390  }
391 
392  template<class T, class A>
394  {
395  return ConstIterator(coarsest_);
396  }
398  } // namespace Amg
399 } // namespace Dune
400 
401 #endif
Helper classes for the construction of classes without empty constructor.
Hierarchy(const Hierarchy &other)
Copy constructor (deep copy!).
Definition: hierarchy.hh:280
void addRedistributedOnCoarsest(Arguments &args)
Definition: hierarchy.hh:326
std::size_t levels() const
Get the number of levels in the hierarchy.
Definition: hierarchy.hh:320
ConstIterator coarsest() const
Get an iterator positioned at the coarsest level.
Definition: hierarchy.hh:393
void addCoarser(Arguments &args)
Add an element on a coarser level.
Definition: hierarchy.hh:332
void addFiner(Arguments &args)
Add an element on a finer level.
Definition: hierarchy.hh:354
Hierarchy(const std::shared_ptr< MemberType > &first)
Construct a new hierarchy.
Definition: hierarchy.hh:268
const void * Arguments
A type holding all the arguments needed to call the constructor.
Definition: construction.hh:42
static std::shared_ptr< T > construct(Arguments &args)
Construct an object with the specified arguments.
Definition: construction.hh:50
Iterator coarsest()
Get an iterator positioned at the coarsest level.
Definition: hierarchy.hh:381
ConstIterator finest() const
Get an iterator positioned at the finest level.
Definition: hierarchy.hh:387
Iterator finest()
Get an iterator positioned at the finest level.
Definition: hierarchy.hh:375
Definition: allocator.hh:9
A hierarchy of containers (e.g. matrices or vectors)
Definition: hierarchy.hh:38
T MemberType
The type of the container we store.
Definition: hierarchy.hh:43
LevelIterator< Hierarchy< T, A >, T > Iterator
Type of the mutable iterator.
Definition: hierarchy.hh:214
LevelIterator< const Hierarchy< T, A >, const T > ConstIterator
Type of the const iterator.
Definition: hierarchy.hh:217
ConstructionTraits< T >::Arguments Arguments
Definition: hierarchy.hh:76
Hierarchy()
Construct an empty hierarchy.
Definition: hierarchy.hh:87
typename std::allocator_traits< A >::template rebind_alloc< Element > Allocator
The allocator to use for the list elements.
Definition: hierarchy.hh:74
Iterator over the levels in the hierarchy.
Definition: hierarchy.hh:118
LevelIterator(const LevelIterator< typename std::remove_const< C >::type, typename std::remove_const< T1 >::type > &other)
Copy constructor.
Definition: hierarchy.hh:134
void addRedistributed(std::shared_ptr< T1 > t)
Definition: hierarchy.hh:199
bool equals(const LevelIterator< typename std::remove_const< C >::type, typename std::remove_const< T1 >::type > &other) const
Equality check.
Definition: hierarchy.hh:148
bool isRedistributed() const
Check whether there was a redistribution at the current level.
Definition: hierarchy.hh:185
bool equals(const LevelIterator< const typename std::remove_const< C >::type, const typename std::remove_const< T1 >::type > &other) const
Equality check.
Definition: hierarchy.hh:157
void increment()
Move to the next coarser level.
Definition: hierarchy.hh:170
T1 & getRedistributed() const
Get the redistributed container.
Definition: hierarchy.hh:194
LevelIterator(const LevelIterator< const typename std::remove_const< C >::type, const typename std::remove_const< T1 >::type > &other)
Copy constructor.
Definition: hierarchy.hh:140
void deleteRedistributed()
Definition: hierarchy.hh:204
void decrement()
Move to the next fine level.
Definition: hierarchy.hh:176
LevelIterator(std::shared_ptr< Element > element)
Definition: hierarchy.hh:129
T1 & dereference() const
Dereference the iterator.
Definition: hierarchy.hh:164