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
16namespace Dune
17{
18 namespace Amg
19 {
38 template<typename T, typename A=std::allocator<T> >
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
173 {
174 element_ = element_->coarser_.lock();
175 }
176
179 {
180 element_ = element_->finer_;
181 }
182
187 bool isRedistributed() const
188 {
189 return (bool)element_->redistributed_;
190 }
191
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>
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
T1 & dereference() const
Dereference the iterator.
Definition: hierarchy.hh:166
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
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
T1 & getRedistributed() const
Get the redistributed container.
Definition: hierarchy.hh:196
LevelIterator()
Constructor.
Definition: hierarchy.hh:128
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
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 (Dec 21, 23:30, 2024)