DUNE-FEM (unstable)

vbvector.hh
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright © 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_ISTL_VBVECTOR_HH
6#define DUNE_ISTL_VBVECTOR_HH
7
8#include <cmath>
9#include <complex>
10#include <iostream>
11#include <iterator>
12#include <memory>
13
15#include <dune/common/indexediterator.hh>
17#include "istlexception.hh"
18#include "bvector.hh"
19
21
26namespace Dune {
27
43 template<class B, class A=std::allocator<B> >
44 class VariableBlockVector : public Imp::block_vector_unmanaged<B,typename A::size_type>
45 // this derivation gives us all the blas level 1 and norms
46 // on the large array. However, access operators have to be
47 // overwritten.
48 {
49 using Base = Imp::block_vector_unmanaged<B,typename A::size_type>;
50
51 // just a shorthand
52 using window_type = Imp::BlockVectorWindow<B,A>;
53
54 // data-structure holding the windows (but not the actual data)
55 using VectorWindows = std::vector<window_type, typename std::allocator_traits<A>::template rebind_alloc<window_type>>;
56
57 // block type bool is not supported since std::vector<bool> is used for storage
58 static_assert(not std::is_same_v<B,bool>, "Block type 'bool' not supported by VariableBlockVector.");
59
60 public:
61
62 //===== type definitions and constants
63
65 using field_type = typename Imp::BlockTraits<B>::field_type;
66
68 using allocator_type = A;
69
74 using reference = window_type&;
75
80 using const_reference = const window_type&;
81
83 using size_type = typename A::size_type;
84
91
95
96 //===== constructors and such
97
103 Base()
104 {}
105
112 explicit VariableBlockVector (size_type numBlocks) :
113 Base(),
114 block(numBlocks)
115 {}
116
125 VariableBlockVector (size_type numBlocks, size_type blockSize) :
126 Base(),
127 block(numBlocks),
128 storage_(numBlocks*blockSize)
129 {
130 // and we can allocate the big array in the base class
131 syncBaseArray();
132
133 // set the windows into the big array
134 for (size_type i=0; i<numBlocks; ++i)
135 block[i].set(blockSize,this->p+(i*blockSize));
136
137 // and the vector is usable
138 initialized = true;
139 }
140
143 Base(static_cast<const Base&>(a)),
144 block(a.block),
145 storage_(a.storage_)
146 {
147 syncBaseArray();
148
149 // and we must set the windows
150 if (block.size()>0) {
151 block[0].set(block[0].getsize(),this->p); // first block
152 for (size_type i=1; i<block.size(); ++i) // and the rest
153 block[i].set(block[i].getsize(),block[i-1].getptr()+block[i-1].getsize());
154 }
155
156 // and we have a usable vector
157 initialized = a.initialized;
158 }
159
162 Base()
163 {
164 tmp.swap(*this);
165 }
166
167 ~VariableBlockVector () = default;
168
169
172 {
173 tmp.swap(*this);
174 return *this;
175 }
176
178 void swap (VariableBlockVector& other) noexcept
179 {
180 using std::swap;
181 swap(storage_, other.storage_);
182 swap(block, other.block);
183 swap(initialized, other.initialized);
184
185 other.syncBaseArray();
186 syncBaseArray();
187 }
188
190 friend void swap (VariableBlockVector& lhs, VariableBlockVector& rhs) noexcept
191 {
192 lhs.swap(rhs);
193 }
194
196 void resize (size_type numBlocks)
197 {
198 storage_.clear();
199
200 syncBaseArray();
201
202 // we can allocate the windows now
203 block.resize(numBlocks);
204
205 // and the vector not fully usable
206 initialized = false;
207 }
208
210 void resize (size_type numBlocks, size_type blockSize)
211 {
212 // and we can allocate the big array in the base class
213 storage_.resize(numBlocks*blockSize);
214 block.resize(numBlocks);
215 syncBaseArray();
216
217 // set the windows into the big array
218 for (size_type i=0; i<block.size(); ++i)
219 block[i].set(blockSize,this->p+(i*blockSize));
220
221 // and the vector is usable
222 initialized = true;
223 }
224
225 //===== assignment from scalar
226
229 {
230 (static_cast<Imp::block_vector_unmanaged<B,size_type>&>(*this)) = k;
231 return *this;
232 }
233
234
235 //===== the creation interface
236
237 class CreateIterator;
238
239#ifndef DOXYGEN
240
241 // The window_type does not hand out a reference to its size,
242 // so in order to provide a valid iterator, we need a workaround
243 // to make assignment possible. This proxy enables just that by
244 // implicitly converting to the stored size for read access and
245 // tunneling assignment to the accessor method of the window.
246 struct SizeProxy
247 {
248
249 operator size_type () const
250 {
251 return target->getsize();
252 }
253
254 SizeProxy& operator= (size_type size)
255 {
256 target->setsize(size);
257 return *this;
258 }
259
260 private:
261
262 friend class CreateIterator;
263
264 SizeProxy (window_type& t) :
265 target(&t)
266 {}
267
268 window_type* target;
269 };
270
271#endif // DOXYGEN
272
275 {
276 public:
278 using iterator_category = std::output_iterator_tag;
279
282
289 using difference_type = void;
290
293
295 using reference = SizeProxy;
296
298 CreateIterator (VariableBlockVector& _v, int _i, bool _isEnd) :
299 v(&_v),
300 i(_i),
301 isEnd(_isEnd)
302 {}
303
305 {
306 // When the iterator gets destructed, we allocate the memory
307 // for the VariableBlockVector if
308 // 1. the current iterator was not created as enditerator
309 // 2. we're at the last block
310 // 3. the vector hasn't been initialized earlier
311 if (not isEnd && i==v->block.size() && not v->initialized)
312 v->allocate();
313 }
314
317 {
318 // go to next block
319 ++i;
320
321 return *this;
322 }
323
326 {
327 CreateIterator tmp(*this);
328 this->operator++();
329 return tmp;
330 }
331
333 bool operator!= (const CreateIterator& it) const
334 {
335 return not (*this == it);
336 }
337
339 bool operator== (const CreateIterator& it) const
340 {
341 return (i==it.i) && (v==it.v);
342 }
343
346 {
347 return i;
348 }
349
352 {
353 v->block[i].setsize(_k);
354 }
355
357#ifdef DOXYGEN
358 size_type&
359#else
360 SizeProxy
361#endif
363 {
364 return {v->block[i]};
365 }
366
367 private:
368 VariableBlockVector* v; // my vector
369 size_type i; // current block to be defined
370 bool isEnd; // flag if this object was created as the end iterator.
371 };
372
373 // CreateIterator wants to set all the arrays ...
374 friend class CreateIterator;
375
378 {
379#ifdef DUNE_ISTL_WITH_CHECKING
380 if (initialized) DUNE_THROW(ISTLError,"no CreateIterator in initialized state");
381#endif
382 return CreateIterator(*this, 0, false);
383 }
384
387 {
388 return CreateIterator(*this, block.size(), true);
389 }
390
391
392 //===== access to components
393 // has to be overwritten from base class because it must
394 // return access to the windows
395
397 window_type& operator[] (size_type i)
398 {
399#ifdef DUNE_ISTL_WITH_CHECKING
400 if (i>=block.size()) DUNE_THROW(ISTLError,"index out of range");
401#endif
402 return block[i];
403 }
404
406 const window_type& operator[] (size_type i) const
407 {
408#ifdef DUNE_ISTL_WITH_CHECKING
409 if (i<0 || i>=block.size()) DUNE_THROW(ISTLError,"index out of range");
410#endif
411 return block[i];
412 }
413
415
418 {
419 return Iterator{block.begin()};
420 }
421
424 {
425 return Iterator{block.end()};
426 }
427
431 {
432 return Iterator{--block.end()};
433 }
434
438 {
439 return Iterator{--block.begin()};
440 }
441
444
447
450
453 {
454 return ConstIterator{block.begin()};
455 }
456
459 {
460 return ConstIterator{block.end()};
461 }
462
466 {
467 return ConstIterator{--block.end()};
468 }
469
473 {
474 return ConstIterator{--block.begin()};
475 }
476
479 {
480 return ConstIterator{block.rend()};
481 }
482
485 {
486 Iterator tmp = block.begin();
487 tmp+=std::min(i, block.size());
488 return tmp;
489 }
490
493 {
494 ConstIterator tmp = block.begin();
495 tmp+=std::min(i, block.size());
496 return tmp;
497 }
498
499 //===== sizes
500
502 size_type N () const noexcept
503 {
504 return block.size();
505 }
506
511 size_type size () const noexcept
512 {
513 return block.size();
514 }
515
516
517 private:
518
519 void allocate ()
520 {
521 if (this->initialized)
522 DUNE_THROW(ISTLError, "Attempt to re-allocate already initialized VariableBlockVector");
523
524 // calculate space needed:
525 size_type storageNeeded = 0;
526 for(size_type i = 0; i < block.size(); i++)
527 storageNeeded += block[i].size();
528
529 storage_.resize(storageNeeded);
530 syncBaseArray();
531
532 // and we set the window pointers
533 block[0].setptr(this->p); // pointer to first block
534 for (size_type j=1; j<block.size(); ++j) // and the rest
535 block[j].setptr(block[j-1].getptr()+block[j-1].getsize());
536
537 // and the vector is ready
538 this->initialized = true;
539 }
540
541 void syncBaseArray () noexcept
542 {
543 this->p = storage_.data();
544 this->n = storage_.size();
545 }
546
547 VectorWindows block = {}; // vector of blocks pointing to the array in the base class
548 std::vector<B, A> storage_ = {};
549 bool initialized = false; // true if vector has been initialized
550 };
551
555 template<class B, class A>
556 struct FieldTraits< VariableBlockVector<B, A> >
557 {
558 typedef typename FieldTraits<B>::field_type field_type;
559 typedef typename FieldTraits<B>::real_type real_type;
560 };
568} // end namespace
569
570#endif
Helper functions for determining the vector/matrix block level.
This file implements a vector space as a tensor product of a given vector space. The number of compon...
A vector of blocks with memory management.
Definition: bvector.hh:392
derive error class from the base class in common
Definition: istlexception.hh:19
An iterator mixin that adds an index() method returning an enumeration index for the traversal.
Definition: indexediterator.hh:29
Iterator class for sequential creation of blocks.
Definition: vbvector.hh:275
bool operator==(const CreateIterator &it) const
equality
Definition: vbvector.hh:339
size_type index() const
dereferencing
Definition: vbvector.hh:345
SizeProxy reference
reference type
Definition: vbvector.hh:295
size_type * pointer
pointer type
Definition: vbvector.hh:292
bool operator!=(const CreateIterator &it) const
inequality
Definition: vbvector.hh:333
size_type value_type
value type
Definition: vbvector.hh:281
CreateIterator(VariableBlockVector &_v, int _i, bool _isEnd)
constructor
Definition: vbvector.hh:298
void setblocksize(size_type _k)
set size of current block
Definition: vbvector.hh:351
size_type & operator*()
Access size of current block.
Definition: vbvector.hh:362
std::output_iterator_tag iterator_category
iterator category
Definition: vbvector.hh:278
CreateIterator & operator++()
prefix increment
Definition: vbvector.hh:316
void difference_type
difference type (unused)
Definition: vbvector.hh:289
A Vector of blocks with different blocksizes.
Definition: vbvector.hh:48
VariableBlockVector(size_type numBlocks, size_type blockSize)
Construct a vector with given number of blocks each having a constant size.
Definition: vbvector.hh:125
VariableBlockVector()
Constructor without arguments makes an empty vector.
Definition: vbvector.hh:102
friend void swap(VariableBlockVector &lhs, VariableBlockVector &rhs) noexcept
Free function to swap the storage and internal state of lhs with rhs.
Definition: vbvector.hh:190
VariableBlockVector & operator=(VariableBlockVector tmp)
Copy and move assignment.
Definition: vbvector.hh:171
VariableBlockVector(size_type numBlocks)
Construct a vector with given number of blocks, but size of each block is not yet known.
Definition: vbvector.hh:112
typename Imp::BlockTraits< B >::field_type field_type
export the type representing the field
Definition: vbvector.hh:65
typename A::size_type size_type
The size type for the index access.
Definition: vbvector.hh:83
size_type N() const noexcept
number of blocks in the vector (are of variable size here)
Definition: vbvector.hh:502
VariableBlockVector(const VariableBlockVector &a)
Copy constructor, has copy semantics.
Definition: vbvector.hh:142
window_type & operator[](size_type i)
random access to blocks
Definition: vbvector.hh:397
A allocator_type
export the allocator type
Definition: vbvector.hh:68
CreateIterator createend()
get create iterator pointing to one after the last block
Definition: vbvector.hh:386
VariableBlockVector(VariableBlockVector &&tmp)
Move constructor:
Definition: vbvector.hh:161
CreateIterator createbegin()
get initial create iterator
Definition: vbvector.hh:377
window_type & reference
Export type used for references to container entries.
Definition: vbvector.hh:74
ConstIterator rend() const
end ConstIterator
Definition: vbvector.hh:478
const window_type & const_reference
Export type used for const references to container entries.
Definition: vbvector.hh:80
ConstIterator find(size_type i) const
random access returning iterator (end if not contained)
Definition: vbvector.hh:492
ConstIterator beforeEnd() const
Definition: vbvector.hh:465
Iterator find(size_type i)
random access returning iterator (end if not contained)
Definition: vbvector.hh:484
IndexedIterator< typename VectorWindows::const_iterator > ConstIterator
Const iterator.
Definition: vbvector.hh:446
ConstIterator beforeBegin() const
Definition: vbvector.hh:472
void resize(size_type numBlocks)
same effect as constructor with same argument
Definition: vbvector.hh:196
Iterator end()
end Iterator
Definition: vbvector.hh:423
void swap(VariableBlockVector &other) noexcept
Exchange the storage and internal state with other.
Definition: vbvector.hh:178
ConstIterator begin() const
begin ConstIterator
Definition: vbvector.hh:452
size_type size() const noexcept
Definition: vbvector.hh:511
void resize(size_type numBlocks, size_type blockSize)
same effect as constructor with same argument
Definition: vbvector.hh:210
ConstIterator end() const
end ConstIterator
Definition: vbvector.hh:458
Iterator beforeBegin()
Definition: vbvector.hh:437
Iterator beforeEnd()
Definition: vbvector.hh:430
Iterator begin()
begin Iterator
Definition: vbvector.hh:417
Type traits to determine the type of reals (when working with complex numbers)
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
This file implements iterator facade classes for writing stl conformant iterators.
Dune namespace.
Definition: alignedallocator.hh:13
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 21, 23:30, 2024)