Dune Core Modules (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>
10 #include <dune/common/unused.hh>
11 #include <dune/common/timer.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>
47  class LevelIterator;
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 
77  typedef typename ConstructionTraits<T>::Arguments Arguments;
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 
102  void addRedistributedOnCoarsest(Arguments& args);
103 
108  void addFiner(Arguments& args);
109 
116  template<class C, class T1>
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 
205  void deleteRedistributed()
206  {
207  element_->redistributed_ = nullptr;
208  }
209 
210  private:
211  std::shared_ptr<Element> element_;
212  };
213 
216 
219 
225 
231 
232 
238 
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>
327  void Hierarchy<T,A>::addRedistributedOnCoarsest(Arguments& args)
328  {
329  coarsest_->redistributed_ = ConstructionTraits<MemberType>::construct(args);
330  }
331 
332  template<class T, class A>
333  void Hierarchy<T,A>::addCoarser(Arguments& args)
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>
355  void Hierarchy<T,A>::addFiner(Arguments& args)
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>
395  {
396  return ConstIterator(coarsest_);
397  }
399  } // namespace Amg
400 } // namespace Dune
401 
402 #endif
Portable very large unsigned integers.
Iterator over the levels in the hierarchy.
Definition: hierarchy.hh:119
LevelIterator(const LevelIterator< typename std::remove_const< C >::type, typename std::remove_const< T1 >::type > &other)
Copy constructor.
Definition: hierarchy.hh:135
bool equals(const LevelIterator< typename std::remove_const< C >::type, typename std::remove_const< T1 >::type > &other) const
Equality check.
Definition: hierarchy.hh:149
bool isRedistributed() const
Check whether there was a redistribution at the current level.
Definition: hierarchy.hh:186
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
void increment()
Move to the next coarser level.
Definition: hierarchy.hh:171
T1 & getRedistributed() const
Get the redistributed container.
Definition: hierarchy.hh:195
LevelIterator(const LevelIterator< const typename std::remove_const< C >::type, const typename std::remove_const< T1 >::type > &other)
Copy constructor.
Definition: hierarchy.hh:141
void decrement()
Move to the next fine level.
Definition: hierarchy.hh:177
LevelIterator()
Constructor.
Definition: hierarchy.hh:127
T1 & dereference() const
Dereference the iterator.
Definition: hierarchy.hh:165
A hierarchy of containers (e.g. matrices or vectors)
Definition: hierarchy.hh:39
T MemberType
The type of the container we store.
Definition: hierarchy.hh:44
LevelIterator< Hierarchy< T, A >, T > Iterator
Type of the mutable iterator.
Definition: hierarchy.hh:215
LevelIterator< const Hierarchy< T, A >, const T > ConstIterator
Type of the const iterator.
Definition: hierarchy.hh:218
A::template rebind< Element >::other Allocator
The allocator to use for the list elements.
Definition: hierarchy.hh:75
Hierarchy()
Construct an empty hierarchy.
Definition: hierarchy.hh:88
Facade class for stl conformant bidirectional iterators.
Definition: iteratorfacades.hh:272
Helper classes for the construction of classes without empty constructor.
Hierarchy(const Hierarchy &other)
Copy constructor (deep copy!).
Definition: hierarchy.hh:281
std::size_t levels() const
Get the number of levels in the hierarchy.
Definition: hierarchy.hh:321
ConstIterator coarsest() const
Get an iterator positioned at the coarsest level.
Definition: hierarchy.hh:394
void addCoarser(Arguments &args)
Add an element on a coarser level.
Definition: hierarchy.hh:333
void addFiner(Arguments &args)
Add an element on a finer level.
Definition: hierarchy.hh:355
Hierarchy(const std::shared_ptr< MemberType > &first)
Construct a new hierarchy.
Definition: hierarchy.hh:269
const void * Arguments
A type holding all the arguments needed to call the constructor.
Definition: construction.hh:44
static std::shared_ptr< T > construct(Arguments &args)
Construct an object with the specified arguments.
Definition: construction.hh:52
Iterator coarsest()
Get an iterator positioned at the coarsest level.
Definition: hierarchy.hh:382
ConstIterator finest() const
Get an iterator positioned at the finest level.
Definition: hierarchy.hh:388
Iterator finest()
Get an iterator positioned at the finest level.
Definition: hierarchy.hh:376
Dune namespace.
Definition: alignedallocator.hh:14
Standard Dune debug streams.
A simple timing class.
Definition of the DUNE_UNUSED macro for the case that config.h is not available.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 16, 22:29, 2024)