DUNE PDELab (2.8)

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/timer.hh>
13
14namespace Dune
15{
16 namespace Amg
17 {
36 template<typename T, typename A=std::allocator<T> >
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
76 typedef typename ConstructionTraits<T>::Arguments Arguments;
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
101 void addRedistributedOnCoarsest(Arguments& args);
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
171 {
172 element_ = element_->coarser_.lock();
173 }
174
177 {
178 element_ = element_->finer_;
179 }
180
185 bool isRedistributed() const
186 {
187 return (bool)element_->redistributed_;
188 }
189
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
204 void deleteRedistributed()
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>
332 void Hierarchy<T,A>::addCoarser(Arguments& args)
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>
354 void Hierarchy<T,A>::addFiner(Arguments& args)
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
Portable very large unsigned integers.
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
T1 & dereference() const
Dereference the iterator.
Definition: hierarchy.hh:164
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
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 decrement()
Move to the next fine level.
Definition: hierarchy.hh:176
T1 & getRedistributed() const
Get the redistributed container.
Definition: hierarchy.hh:194
LevelIterator()
Constructor.
Definition: hierarchy.hh:126
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
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
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:280
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
Dune namespace.
Definition: alignedallocator.hh:11
STL namespace.
Standard Dune debug streams.
A simple timing class.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 27, 22:29, 2024)