DUNE PDELab (2.7)

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
15namespace Dune
16{
17 namespace Amg
18 {
37 template<typename T, typename A=std::allocator<T> >
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 using Allocator = typename std::allocator_traits<A>::template rebind_alloc<Element>;
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
172 {
173 element_ = element_->coarser_.lock();
174 }
175
178 {
179 element_ = element_->finer_;
180 }
181
186 bool isRedistributed() const
187 {
188 return (bool)element_->redistributed_;
189 }
190
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>
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
T1 & dereference() const
Dereference the iterator.
Definition: hierarchy.hh:165
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
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
T1 & getRedistributed() const
Get the redistributed container.
Definition: hierarchy.hh:195
LevelIterator()
Constructor.
Definition: hierarchy.hh:127
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
Hierarchy()
Construct an empty hierarchy.
Definition: hierarchy.hh:88
typename std::allocator_traits< A >::template rebind_alloc< Element > Allocator
The allocator to use for the list elements.
Definition: hierarchy.hh:75
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
STL namespace.
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.111.3 (Jul 15, 22:36, 2024)