Dune Core Modules (2.9.0)

hierarchy.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_AMGHIERARCHY_HH
6 #define DUNE_AMGHIERARCHY_HH
7 
8 #include <list>
9 #include <memory>
10 #include <limits>
12 #include <dune/common/timer.hh>
15 
16 namespace Dune
17 {
18  namespace Amg
19  {
38  template<typename T, typename A=std::allocator<T> >
39  class Hierarchy
40  {
41  public:
45  typedef T MemberType;
46 
47  template<typename T1, typename T2>
48  class LevelIterator;
49 
50  private:
54  struct Element
55  {
56  friend class LevelIterator<Hierarchy<T,A>, T>;
57  friend class LevelIterator<const Hierarchy<T,A>, const T>;
58 
60  std::weak_ptr<Element> coarser_;
61 
63  std::shared_ptr<Element> finer_;
64 
66  std::shared_ptr<MemberType> element_;
67 
69  std::shared_ptr<MemberType> redistributed_;
70  };
71  public:
72 
76  using Allocator = typename std::allocator_traits<A>::template rebind_alloc<Element>;
77 
78  typedef typename ConstructionTraits<T>::Arguments Arguments;
79 
84  Hierarchy(const std::shared_ptr<MemberType> & first);
85 
89  Hierarchy() : levels_(0)
90  {}
91 
95  Hierarchy(const Hierarchy& other);
96 
101  void addCoarser(Arguments& args);
102 
103  void addRedistributedOnCoarsest(Arguments& args);
104 
109  void addFiner(Arguments& args);
110 
117  template<class C, class T1>
119  : public BidirectionalIteratorFacade<LevelIterator<C,T1>,T1,T1&>
120  {
121  friend class LevelIterator<typename std::remove_const<C>::type,
122  typename std::remove_const<T1>::type >;
123  friend class LevelIterator<const typename std::remove_const<C>::type,
124  const typename std::remove_const<T1>::type >;
125 
126  public:
129  {}
130 
131  LevelIterator(std::shared_ptr<Element> element)
132  : element_(element)
133  {}
134 
136  LevelIterator(const LevelIterator<typename std::remove_const<C>::type,
137  typename std::remove_const<T1>::type>& other)
138  : element_(other.element_)
139  {}
140 
142  LevelIterator(const LevelIterator<const typename std::remove_const<C>::type,
143  const typename std::remove_const<T1>::type>& other)
144  : element_(other.element_)
145  {}
146 
150  bool equals(const LevelIterator<typename std::remove_const<C>::type,
151  typename std::remove_const<T1>::type>& other) const
152  {
153  return element_ == other.element_;
154  }
155 
159  bool equals(const LevelIterator<const typename std::remove_const<C>::type,
160  const typename std::remove_const<T1>::type>& other) const
161  {
162  return element_ == other.element_;
163  }
164 
166  T1& dereference() const
167  {
168  return *(element_->element_);
169  }
170 
172  void increment()
173  {
174  element_ = element_->coarser_.lock();
175  }
176 
178  void decrement()
179  {
180  element_ = element_->finer_;
181  }
182 
187  bool isRedistributed() const
188  {
189  return (bool)element_->redistributed_;
190  }
191 
196  T1& getRedistributed() const
197  {
198  assert(element_->redistributed_);
199  return *element_->redistributed_;
200  }
201  void addRedistributed(std::shared_ptr<T1> t)
202  {
203  element_->redistributed_ = t;
204  }
205 
206  void deleteRedistributed()
207  {
208  element_->redistributed_ = nullptr;
209  }
210 
211  private:
212  std::shared_ptr<Element> element_;
213  };
214 
217 
220 
226 
232 
233 
239 
245 
250  std::size_t levels() const;
251 
252  private:
258  std::shared_ptr<MemberType> originalFinest_;
260  std::shared_ptr<Element> finest_;
262  std::shared_ptr<Element> coarsest_;
264  Allocator allocator_;
266  int levels_;
267  };
268 
269  template<class T, class A>
270  Hierarchy<T,A>::Hierarchy(const std::shared_ptr<MemberType> & first)
271  : originalFinest_(first)
272  {
273  finest_ = std::allocate_shared<Element>(allocator_);
274  finest_->element_ = originalFinest_;
275  coarsest_ = finest_;
276  levels_ = 1;
277  }
278 
280  //TODO: do we actually want to support this? This might be very expensive?!
281  template<class T, class A>
283  : allocator_(other.allocator_),
284  levels_(other.levels_)
285  {
286  if(!other.finest_)
287  {
288  finest_=coarsest_=nullptr;
289  return;
290  }
291  finest_ = std::allocate_shared<Element>(allocator_);
292  std::shared_ptr<Element> finer_;
293  std::shared_ptr<Element> current_ = finest_;
294  std::weak_ptr<Element> otherWeak_ = other.finest_;
295 
296  while(! otherWeak_.expired())
297  {
298  // create shared_ptr from weak_ptr, we just checked that this is safe
299  std::shared_ptr<Element> otherCurrent_ = std::shared_ptr<Element>(otherWeak_);
300  // clone current level
301  //TODO: should we use the allocator?
302  current_->element_ =
303  std::make_shared<MemberType>(*(otherCurrent_->element_));
304  current_->finer_=finer_;
305  if(otherCurrent_->redistributed_)
306  current_->redistributed_ =
307  std::make_shared<MemberType>(*(otherCurrent_->redistributed_));
308  finer_=current_;
309  if(not otherCurrent_->coarser_.expired())
310  {
311  auto c = std::allocate_shared<Element>(allocator_);
312  current_->coarser_ = c;
313  current_ = c;
314  }
315  // go to coarser level
316  otherWeak_ = otherCurrent_->coarser_;
317  }
318  coarsest_=current_;
319  }
320 
321  template<class T, class A>
322  std::size_t Hierarchy<T,A>::levels() const
323  {
324  return levels_;
325  }
326 
327  template<class T, class A>
328  void Hierarchy<T,A>::addRedistributedOnCoarsest(Arguments& args)
329  {
330  coarsest_->redistributed_ = ConstructionTraits<MemberType>::construct(args);
331  }
332 
333  template<class T, class A>
334  void Hierarchy<T,A>::addCoarser(Arguments& args)
335  {
336  if(!coarsest_) {
337  // we have no levels at all...
338  assert(!finest_);
339  // allocate into the shared_ptr
340  originalFinest_ = ConstructionTraits<MemberType>::construct(args);
341  coarsest_ = std::allocate_shared<Element>(allocator_);
342  coarsest_->element_ = originalFinest_;
343  finest_ = coarsest_;
344  }else{
345  auto old_coarsest = coarsest_;
346  coarsest_ = std::allocate_shared<Element>(allocator_);
347  coarsest_->finer_ = old_coarsest;
348  coarsest_->element_ = ConstructionTraits<MemberType>::construct(args);
349  old_coarsest->coarser_ = coarsest_;
350  }
351  ++levels_;
352  }
353 
354 
355  template<class T, class A>
356  void Hierarchy<T,A>::addFiner(Arguments& args)
357  {
358  //TODO: wouldn't it be better to do this in the constructor?'
359  if(!finest_) {
360  // we have no levels at all...
361  assert(!coarsest_);
362  // allocate into the shared_ptr
363  originalFinest_ = ConstructionTraits<MemberType>::construct(args);
364  finest_ = std::allocate_shared<Element>(allocator_);
365  finest_->element = originalFinest_;
366  coarsest_ = finest_;
367  }else{
368  finest_->finer_ = std::allocate_shared<Element>(allocator_);
369  finest_->finer_->coarser_ = finest_;
370  finest_ = finest_->finer_;
371  finest_->element = ConstructionTraits<T>::construct(args);
372  }
373  ++levels_;
374  }
375 
376  template<class T, class A>
378  {
379  return Iterator(finest_);
380  }
381 
382  template<class T, class A>
384  {
385  return Iterator(coarsest_);
386  }
387 
388  template<class T, class A>
390  {
391  return ConstIterator(finest_);
392  }
393 
394  template<class T, class A>
396  {
397  return ConstIterator(coarsest_);
398  }
400  } // namespace Amg
401 } // namespace Dune
402 
403 #endif
Portable very large unsigned integers.
Iterator over the levels in the hierarchy.
Definition: hierarchy.hh:120
LevelIterator(const LevelIterator< typename std::remove_const< C >::type, typename std::remove_const< T1 >::type > &other)
Copy constructor.
Definition: hierarchy.hh:136
bool equals(const LevelIterator< typename std::remove_const< C >::type, typename std::remove_const< T1 >::type > &other) const
Equality check.
Definition: hierarchy.hh:150
bool isRedistributed() const
Check whether there was a redistribution at the current level.
Definition: hierarchy.hh:187
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:159
void increment()
Move to the next coarser level.
Definition: hierarchy.hh:172
T1 & getRedistributed() const
Get the redistributed container.
Definition: hierarchy.hh:196
LevelIterator(const LevelIterator< const typename std::remove_const< C >::type, const typename std::remove_const< T1 >::type > &other)
Copy constructor.
Definition: hierarchy.hh:142
void decrement()
Move to the next fine level.
Definition: hierarchy.hh:178
LevelIterator()
Constructor.
Definition: hierarchy.hh:128
T1 & dereference() const
Dereference the iterator.
Definition: hierarchy.hh:166
A hierarchy of containers (e.g. matrices or vectors)
Definition: hierarchy.hh:40
T MemberType
The type of the container we store.
Definition: hierarchy.hh:45
LevelIterator< Hierarchy< T, A >, T > Iterator
Type of the mutable iterator.
Definition: hierarchy.hh:216
LevelIterator< const Hierarchy< T, A >, const T > ConstIterator
Type of the const iterator.
Definition: hierarchy.hh:219
Hierarchy()
Construct an empty hierarchy.
Definition: hierarchy.hh:89
typename std::allocator_traits< A >::template rebind_alloc< Element > Allocator
The allocator to use for the list elements.
Definition: hierarchy.hh:76
Facade class for stl conformant bidirectional iterators.
Definition: iteratorfacades.hh:274
Helper classes for the construction of classes without empty constructor.
Hierarchy(const Hierarchy &other)
Copy constructor (deep copy!).
Definition: hierarchy.hh:282
std::size_t levels() const
Get the number of levels in the hierarchy.
Definition: hierarchy.hh:322
ConstIterator coarsest() const
Get an iterator positioned at the coarsest level.
Definition: hierarchy.hh:395
void addCoarser(Arguments &args)
Add an element on a coarser level.
Definition: hierarchy.hh:334
void addFiner(Arguments &args)
Add an element on a finer level.
Definition: hierarchy.hh:356
Hierarchy(const std::shared_ptr< MemberType > &first)
Construct a new hierarchy.
Definition: hierarchy.hh:270
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:383
ConstIterator finest() const
Get an iterator positioned at the finest level.
Definition: hierarchy.hh:389
Iterator finest()
Get an iterator positioned at the finest level.
Definition: hierarchy.hh:377
Dune namespace.
Definition: alignedallocator.hh:13
Standard Dune debug streams.
A simple timing class.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 4, 22:30, 2024)