dune-istl  2.7.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/unused.hh>
11 #include <dune/common/timer.hh>
12 #include <dune/common/bigunsignedint.hh>
14 
15 namespace Dune
16 {
17  namespace Amg
18  {
37  template<typename T, typename A=std::allocator<T> >
38  class Hierarchy
39  {
40  public:
44  typedef T MemberType;
45 
46  template<typename T1, typename T2>
48 
49  private:
53  struct Element
54  {
55  friend class LevelIterator<Hierarchy<T,A>, T>;
56  friend class LevelIterator<const Hierarchy<T,A>, const T>;
57 
59  std::weak_ptr<Element> coarser_;
60 
62  std::shared_ptr<Element> finer_;
63 
65  std::shared_ptr<MemberType> element_;
66 
68  std::shared_ptr<MemberType> redistributed_;
69  };
70  public:
71 
75  typedef typename A::template rebind<Element>::other Allocator;
76 
78 
83  Hierarchy(const std::shared_ptr<MemberType> & first);
84 
88  Hierarchy() : levels_(0)
89  {}
90 
94  Hierarchy(const Hierarchy& other);
95 
100  void addCoarser(Arguments& args);
101 
103 
108  void addFiner(Arguments& args);
109 
116  template<class C, class T1>
117  class LevelIterator
118  : public BidirectionalIteratorFacade<LevelIterator<C,T1>,T1,T1&>
119  {
120  friend class LevelIterator<typename std::remove_const<C>::type,
121  typename std::remove_const<T1>::type >;
122  friend class LevelIterator<const typename std::remove_const<C>::type,
123  const typename std::remove_const<T1>::type >;
124 
125  public:
128  {}
129 
130  LevelIterator(std::shared_ptr<Element> element)
131  : element_(element)
132  {}
133 
135  LevelIterator(const LevelIterator<typename std::remove_const<C>::type,
136  typename std::remove_const<T1>::type>& other)
137  : element_(other.element_)
138  {}
139 
141  LevelIterator(const LevelIterator<const typename std::remove_const<C>::type,
142  const typename std::remove_const<T1>::type>& other)
143  : element_(other.element_)
144  {}
145 
149  bool equals(const LevelIterator<typename std::remove_const<C>::type,
150  typename std::remove_const<T1>::type>& other) const
151  {
152  return element_ == other.element_;
153  }
154 
158  bool equals(const LevelIterator<const typename std::remove_const<C>::type,
159  const typename std::remove_const<T1>::type>& other) const
160  {
161  return element_ == other.element_;
162  }
163 
165  T1& dereference() const
166  {
167  return *(element_->element_);
168  }
169 
171  void increment()
172  {
173  element_ = element_->coarser_.lock();
174  }
175 
177  void decrement()
178  {
179  element_ = element_->finer_;
180  }
181 
186  bool isRedistributed() const
187  {
188  return (bool)element_->redistributed_;
189  }
190 
195  T1& getRedistributed() const
196  {
197  assert(element_->redistributed_);
198  return *element_->redistributed_;
199  }
200  void addRedistributed(std::shared_ptr<T1> t)
201  {
202  element_->redistributed_ = t;
203  }
204 
206  {
207  element_->redistributed_ = nullptr;
208  }
209 
210  private:
211  std::shared_ptr<Element> element_;
212  };
213 
215  typedef LevelIterator<Hierarchy<T,A>,T> Iterator;
216 
218  typedef LevelIterator<const Hierarchy<T,A>, const T> ConstIterator;
219 
224  Iterator finest();
225 
230  Iterator coarsest();
231 
232 
237  ConstIterator finest() const;
238 
243  ConstIterator coarsest() const;
244 
249  std::size_t levels() const;
250 
251  private:
257  std::shared_ptr<MemberType> originalFinest_;
259  std::shared_ptr<Element> finest_;
261  std::shared_ptr<Element> coarsest_;
263  Allocator allocator_;
265  int levels_;
266  };
267 
268  template<class T, class A>
269  Hierarchy<T,A>::Hierarchy(const std::shared_ptr<MemberType> & first)
270  : originalFinest_(first)
271  {
272  finest_ = std::allocate_shared<Element>(allocator_);
273  finest_->element_ = originalFinest_;
274  coarsest_ = finest_;
275  levels_ = 1;
276  }
277 
279  //TODO: do we actually want to support this? This might be very expensive?!
280  template<class T, class A>
282  : allocator_(other.allocator_),
283  levels_(other.levels_)
284  {
285  if(!other.finest_)
286  {
287  finest_=coarsest_=nullptr;
288  return;
289  }
290  finest_ = std::allocate_shared<Element>(allocator_);
291  std::shared_ptr<Element> finer_;
292  std::shared_ptr<Element> current_ = finest_;
293  std::weak_ptr<Element> otherWeak_ = other.finest_;
294 
295  while(! otherWeak_.expired())
296  {
297  // create shared_ptr from weak_ptr, we just checked that this is safe
298  std::shared_ptr<Element> otherCurrent_ = std::shared_ptr<Element>(otherWeak_);
299  // clone current level
300  //TODO: should we use the allocator?
301  current_->element_ =
302  std::make_shared<MemberType>(*(otherCurrent_->element_));
303  current_->finer_=finer_;
304  if(otherCurrent_->redistributed_)
305  current_->redistributed_ =
306  std::make_shared<MemberType>(*(otherCurrent_->redistributed_));
307  finer_=current_;
308  if(not otherCurrent_->coarser_.expired())
309  {
310  auto c = std::allocate_shared<Element>(allocator_);
311  current_->coarser_ = c;
312  current_ = c;
313  }
314  // go to coarser level
315  otherWeak_ = otherCurrent_->coarser_;
316  }
317  coarsest_=current_;
318  }
319 
320  template<class T, class A>
321  std::size_t Hierarchy<T,A>::levels() const
322  {
323  return levels_;
324  }
325 
326  template<class T, class A>
328  {
329  coarsest_->redistributed_ = ConstructionTraits<MemberType>::construct(args);
330  }
331 
332  template<class T, class A>
334  {
335  if(!coarsest_) {
336  // we have no levels at all...
337  assert(!finest_);
338  // allocate into the shared_ptr
339  originalFinest_ = ConstructionTraits<MemberType>::construct(args);
340  coarsest_ = std::allocate_shared<Element>(allocator_);
341  coarsest_->element_ = originalFinest_;
342  finest_ = coarsest_;
343  }else{
344  auto old_coarsest = coarsest_;
345  coarsest_ = std::allocate_shared<Element>(allocator_);
346  coarsest_->finer_ = old_coarsest;
347  coarsest_->element_ = ConstructionTraits<MemberType>::construct(args);
348  old_coarsest->coarser_ = coarsest_;
349  }
350  ++levels_;
351  }
352 
353 
354  template<class T, class A>
356  {
357  //TODO: wouldn't it be better to do this in the constructor?'
358  if(!finest_) {
359  // we have no levels at all...
360  assert(!coarsest_);
361  // allocate into the shared_ptr
362  originalFinest_ = ConstructionTraits<MemberType>::construct(args);
363  finest_ = std::allocate_shared<Element>(allocator_);
364  finest_->element = originalFinest_;
365  coarsest_ = finest_;
366  }else{
367  finest_->finer_ = std::allocate_shared<Element>(allocator_);
368  finest_->finer_->coarser_ = finest_;
369  finest_ = finest_->finer_;
370  finest_->element = ConstructionTraits<T>::construct(args);
371  }
372  ++levels_;
373  }
374 
375  template<class T, class A>
377  {
378  return Iterator(finest_);
379  }
380 
381  template<class T, class A>
383  {
384  return Iterator(coarsest_);
385  }
386 
387  template<class T, class A>
389  {
390  return ConstIterator(finest_);
391  }
392 
393  template<class T, class A>
394  typename Hierarchy<T,A>::ConstIterator Hierarchy<T,A>::coarsest() const
395  {
396  return ConstIterator(coarsest_);
397  }
399  } // namespace Amg
400 } // namespace Dune
401 
402 #endif
Dune::Amg::Hierarchy::Iterator
LevelIterator< Hierarchy< T, A >, T > Iterator
Type of the mutable iterator.
Definition: hierarchy.hh:215
Dune::Amg::Hierarchy::Arguments
ConstructionTraits< T >::Arguments Arguments
Definition: hierarchy.hh:77
Dune::Amg::Hierarchy::LevelIterator::decrement
void decrement()
Move to the next fine level.
Definition: hierarchy.hh:177
Dune::Amg::Hierarchy::Hierarchy
Hierarchy()
Construct an empty hierarchy.
Definition: hierarchy.hh:88
construction.hh
Helper classes for the construction of classes without empty constructor.
Dune::Amg::ConstructionTraits
Traits class for generically constructing non default constructable types.
Definition: novlpschwarz.hh:251
Dune::Amg::Hierarchy::LevelIterator::isRedistributed
bool isRedistributed() const
Check whether there was a redistribution at the current level.
Definition: hierarchy.hh:186
Dune::Amg::Hierarchy::LevelIterator::equals
bool equals(const LevelIterator< typename std::remove_const< C >::type, typename std::remove_const< T1 >::type > &other) const
Equality check.
Definition: hierarchy.hh:149
Dune::Amg::Hierarchy::LevelIterator::LevelIterator
LevelIterator(const LevelIterator< typename std::remove_const< C >::type, typename std::remove_const< T1 >::type > &other)
Copy constructor.
Definition: hierarchy.hh:135
Dune::Amg::Hierarchy::LevelIterator::LevelIterator
LevelIterator()
Constructor.
Definition: hierarchy.hh:127
Dune::Amg::Hierarchy::LevelIterator::LevelIterator
LevelIterator(std::shared_ptr< Element > element)
Definition: hierarchy.hh:130
Dune::Amg::Hierarchy::LevelIterator::LevelIterator
LevelIterator(const LevelIterator< const typename std::remove_const< C >::type, const typename std::remove_const< T1 >::type > &other)
Copy constructor.
Definition: hierarchy.hh:141
Dune::Amg::Hierarchy::LevelIterator::addRedistributed
void addRedistributed(std::shared_ptr< T1 > t)
Definition: hierarchy.hh:200
Dune::Amg::Hierarchy::LevelIterator
Iterator over the levels in the hierarchy.
Definition: hierarchy.hh:47
Dune::Amg::Hierarchy::LevelIterator::increment
void increment()
Move to the next coarser level.
Definition: hierarchy.hh:171
Dune::Amg::Hierarchy::MemberType
T MemberType
The type of the container we store.
Definition: hierarchy.hh:44
Dune::Amg::Hierarchy::addFiner
void addFiner(Arguments &args)
Add an element on a finer level.
Definition: hierarchy.hh:355
Dune::Amg::Hierarchy::finest
Iterator finest()
Get an iterator positioned at the finest level.
Definition: hierarchy.hh:376
Dune::Amg::Hierarchy::LevelIterator::deleteRedistributed
void deleteRedistributed()
Definition: hierarchy.hh:205
Dune::Amg::Hierarchy::LevelIterator::equals
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:158
Dune
Definition: allocator.hh:7
Dune::Amg::Hierarchy
A hierarchy of containers (e.g. matrices or vectors)
Definition: hierarchy.hh:38
Dune::Amg::Hierarchy::coarsest
Iterator coarsest()
Get an iterator positioned at the coarsest level.
Definition: hierarchy.hh:382
Dune::Amg::Hierarchy::addRedistributedOnCoarsest
void addRedistributedOnCoarsest(Arguments &args)
Definition: hierarchy.hh:327
Dune::Amg::Hierarchy::LevelIterator::dereference
T1 & dereference() const
Dereference the iterator.
Definition: hierarchy.hh:165
Dune::Amg::Hierarchy::Allocator
A::template rebind< Element >::other Allocator
The allocator to use for the list elements.
Definition: hierarchy.hh:75
Dune::Amg::Hierarchy::addCoarser
void addCoarser(Arguments &args)
Add an element on a coarser level.
Definition: hierarchy.hh:333
Dune::Amg::Hierarchy::levels
std::size_t levels() const
Get the number of levels in the hierarchy.
Definition: hierarchy.hh:321
Dune::Amg::Hierarchy::ConstIterator
LevelIterator< const Hierarchy< T, A >, const T > ConstIterator
Type of the const iterator.
Definition: hierarchy.hh:218
Dune::Amg::Hierarchy::LevelIterator::getRedistributed
T1 & getRedistributed() const
Get the redistributed container.
Definition: hierarchy.hh:195