Dune Core Modules (2.6.0)

vbvector.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_ISTL_VBVECTOR_HH
4#define DUNE_ISTL_VBVECTOR_HH
5
6#include <cmath>
7#include <complex>
8#include <iostream>
9#include <memory>
10
12#include "istlexception.hh"
13#include "bvector.hh"
14
19namespace Dune {
20
36 template<class B, class A=std::allocator<B> >
37 class VariableBlockVector : public Imp::block_vector_unmanaged<B,A>
38 // this derivation gives us all the blas level 1 and norms
39 // on the large array. However, access operators have to be
40 // overwritten.
41 {
42 // just a shorthand
43 typedef Imp::BlockVectorWindow<B,A> window_type;
44
45 public:
46
47 //===== type definitions and constants
48
50 typedef typename B::field_type field_type;
51
53 typedef A allocator_type;
54
59 typedef window_type& reference;
60
65 typedef const window_type& const_reference;
66
68 typedef typename A::size_type size_type;
69
76
80
84 enum {
86 blocklevel = B::blocklevel+2
87 };
88
89 //===== constructors and such
90
94 VariableBlockVector () : Imp::block_vector_unmanaged<B,A>()
95 {
96 // nothing is known ...
97 nblocks = 0;
98 block = nullptr;
99 initialized = false;
100 }
101
105 explicit VariableBlockVector (size_type _nblocks) : Imp::block_vector_unmanaged<B,A>()
106 {
107 // we can allocate the windows now
108 nblocks = _nblocks;
109 if (nblocks>0)
110 {
111 block = windowAllocator_.allocate(nblocks);
112 new (block) window_type[nblocks];
113 }
114 else
115 {
116 nblocks = 0;
117 block = nullptr;
118 }
119
120 // Note: memory in base class still not allocated
121 // the vector not usable
122 initialized = false;
123 }
124
131 VariableBlockVector (size_type _nblocks, size_type m) : Imp::block_vector_unmanaged<B,A>()
132 {
133 // and we can allocate the big array in the base class
134 this->n = _nblocks*m;
135 if (this->n>0)
136 {
137 this->p = allocator_.allocate(this->n);
138 new (this->p)B[this->n];
139 }
140 else
141 {
142 this->n = 0;
143 this->p = nullptr;
144 }
145
146 // we can allocate the windows now
147 nblocks = _nblocks;
148 if (nblocks>0)
149 {
150 // allocate and construct the windows
151 block = windowAllocator_.allocate(nblocks);
152 new (block) window_type[nblocks];
153
154 // set the windows into the big array
155 for (size_type i=0; i<nblocks; ++i)
156 block[i].set(m,this->p+(i*m));
157 }
158 else
159 {
160 nblocks = 0;
161 block = nullptr;
162 }
163
164 // and the vector is usable
165 initialized = true;
166 }
167
170 {
171 // allocate the big array in the base class
172 this->n = a.n;
173 if (this->n>0)
174 {
175 // allocate and construct objects
176 this->p = allocator_.allocate(this->n);
177 new (this->p)B[this->n];
178
179 // copy data
180 for (size_type i=0; i<this->n; i++) this->p[i]=a.p[i];
181 }
182 else
183 {
184 this->n = 0;
185 this->p = nullptr;
186 }
187
188 // we can allocate the windows now
189 nblocks = a.nblocks;
190 if (nblocks>0)
191 {
192 // alloc
193 block = windowAllocator_.allocate(nblocks);
194 new (block) window_type[nblocks];
195
196 // and we must set the windows
197 block[0].set(a.block[0].getsize(),this->p); // first block
198 for (size_type i=1; i<nblocks; ++i) // and the rest
199 block[i].set(a.block[i].getsize(),block[i-1].getptr()+block[i-1].getsize());
200 }
201 else
202 {
203 nblocks = 0;
204 block = nullptr;
205 }
206
207 // and we have a usable vector
208 initialized = true;
209 }
210
213 {
214 if (this->n>0) {
215 size_type i=this->n;
216 while (i)
217 this->p[--i].~B();
218 allocator_.deallocate(this->p,this->n);
219 }
220 if (nblocks>0) {
221 size_type i=nblocks;
222 while (i)
223 block[--i].~window_type();
224 windowAllocator_.deallocate(block,nblocks);
225 }
226
227 }
228
229
231 void resize (size_type _nblocks)
232 {
233 // deconstruct objects and deallocate memory if necessary
234 if (this->n>0) {
235 size_type i=this->n;
236 while (i)
237 this->p[--i].~B();
238 allocator_.deallocate(this->p,this->n);
239 }
240 if (nblocks>0) {
241 size_type i=nblocks;
242 while (i)
243 block[--i].~window_type();
244 windowAllocator_.deallocate(block,nblocks);
245 }
246 this->n = 0;
247 this->p = nullptr;
248
249 // we can allocate the windows now
250 nblocks = _nblocks;
251 if (nblocks>0)
252 {
253 block = windowAllocator_.allocate(nblocks);
254 new (block) window_type[nblocks];
255 }
256 else
257 {
258 nblocks = 0;
259 block = nullptr;
260 }
261
262 // and the vector not fully usable
263 initialized = false;
264 }
265
267 void resize (size_type _nblocks, size_type m)
268 {
269 // deconstruct objects and deallocate memory if necessary
270 if (this->n>0) {
271 size_type i=this->n;
272 while (i)
273 this->p[--i].~B();
274 allocator_.deallocate(this->p,this->n);
275 }
276 if (nblocks>0) {
277 size_type i=nblocks;
278 while (i)
279 block[--i].~window_type();
280 windowAllocator_.deallocate(block,nblocks);
281 }
282
283 // and we can allocate the big array in the base class
284 this->n = _nblocks*m;
285 if (this->n>0)
286 {
287 this->p = allocator_.allocate(this->n);
288 new (this->p)B[this->n];
289 }
290 else
291 {
292 this->n = 0;
293 this->p = nullptr;
294 }
295
296 // we can allocate the windows now
297 nblocks = _nblocks;
298 if (nblocks>0)
299 {
300 // allocate and construct objects
301 block = windowAllocator_.allocate(nblocks);
302 new (block) window_type[nblocks];
303
304 // set the windows into the big array
305 for (size_type i=0; i<nblocks; ++i)
306 block[i].set(m,this->p+(i*m));
307 }
308 else
309 {
310 nblocks = 0;
311 block = nullptr;
312 }
313
314 // and the vector is usable
315 initialized = true;
316 }
317
320 {
321 if (&a!=this) // check if this and a are different objects
322 {
323 // reallocate arrays if necessary
324 // Note: still the block sizes may vary !
325 if (this->n!=a.n || nblocks!=a.nblocks)
326 {
327 // deconstruct objects and deallocate memory if necessary
328 if (this->n>0) {
329 size_type i=this->n;
330 while (i)
331 this->p[--i].~B();
332 allocator_.deallocate(this->p,this->n);
333 }
334 if (nblocks>0) {
335 size_type i=nblocks;
336 while (i)
337 block[--i].~window_type();
338 windowAllocator_.deallocate(block,nblocks);
339 }
340
341 // allocate the big array in the base class
342 this->n = a.n;
343 if (this->n>0)
344 {
345 // allocate and construct objects
346 this->p = allocator_.allocate(this->n);
347 new (this->p)B[this->n];
348 }
349 else
350 {
351 this->n = 0;
352 this->p = nullptr;
353 }
354
355 // we can allocate the windows now
356 nblocks = a.nblocks;
357 if (nblocks>0)
358 {
359 // alloc
360 block = windowAllocator_.allocate(nblocks);
361 new (block) window_type[nblocks];
362 }
363 else
364 {
365 nblocks = 0;
366 block = nullptr;
367 }
368 }
369
370 // copy block structure, might be different although
371 // sizes are the same !
372 if (nblocks>0)
373 {
374 block[0].set(a.block[0].getsize(),this->p); // first block
375 for (size_type i=1; i<nblocks; ++i) // and the rest
376 block[i].set(a.block[i].getsize(),block[i-1].getptr()+block[i-1].getsize());
377 }
378
379 // and copy the data
380 for (size_type i=0; i<this->n; i++) this->p[i]=a.p[i];
381 }
382
383 // and we have a usable vector
384 initialized = true;
385
386 return *this; // Gebe Referenz zurueck damit a=b=c; klappt
387 }
388
389
390 //===== assignment from scalar
391
394 {
395 (static_cast<Imp::block_vector_unmanaged<B,A>&>(*this)) = k;
396 return *this;
397 }
398
399
400 //===== the creation interface
401
404 {
405 public:
408 {
409 i = _i;
410 k = 0;
411 n = 0;
412 }
413
416 {
417 // we are at block i and the blocks size is known
418
419 // set the blocks size to current k
420 v.block[i].setsize(k);
421
422 // accumulate total size
423 n += k;
424
425 // go to next block
426 ++i;
427
428 // reset block size
429 k = 0;
430
431 // if we are past the last block, finish off
432 if (i==v.nblocks)
433 {
434 // now we can allocate the big array in the base class of v
435 v.n = n;
436 if (n>0)
437 {
438 // allocate and construct objects
439 v.p = v.allocator_.allocate(n);
440 new (v.p)B[n];
441 }
442 else
443 {
444 v.n = 0;
445 v.p = nullptr;
446 }
447
448 // and we set the window pointer
449 if (v.nblocks>0)
450 {
451 v.block[0].setptr(v.p); // pointer tofirst block
452 for (size_type j=1; j<v.nblocks; ++j) // and the rest
453 v.block[j].setptr(v.block[j-1].getptr()+v.block[j-1].getsize());
454 }
455
456 // and the vector is ready
457 v.initialized = true;
458
459 //std::cout << "made vbvector with " << v.n << " components" << std::endl;
460 }
461
462 return *this;
463 }
464
466 bool operator!= (const CreateIterator& it) const
467 {
468 return (i!=it.i) || (&v!=&it.v);
469 }
470
472 bool operator== (const CreateIterator& it) const
473 {
474 return (i==it.i) && (&v==&it.v);
475 }
476
479 {
480 return i;
481 }
482
485 {
486 k = _k;
487 }
488
489 private:
490 VariableBlockVector& v; // my vector
491 size_type i; // current block to be defined
492 size_type k; // size of current block to be defined
493 size_type n; // total number of elements to be allocated
494 };
495
496 // CreateIterator wants to set all the arrays ...
497 friend class CreateIterator;
498
501 {
502#ifdef DUNE_ISTL_WITH_CHECKING
503 if (initialized) DUNE_THROW(ISTLError,"no CreateIterator in initialized state");
504#endif
505 return CreateIterator(*this,0);
506 }
507
510 {
511 return CreateIterator(*this,nblocks);
512 }
513
514
515 //===== access to components
516 // has to be overwritten from base class because it must
517 // return access to the windows
518
520 window_type& operator[] (size_type i)
521 {
522#ifdef DUNE_ISTL_WITH_CHECKING
523 if (i>=nblocks) DUNE_THROW(ISTLError,"index out of range");
524#endif
525 return block[i];
526 }
527
529 const window_type& operator[] (size_type i) const
530 {
531#ifdef DUNE_ISTL_WITH_CHECKING
532 if (i<0 || i>=nblocks) DUNE_THROW(ISTLError,"index out of range");
533#endif
534 return block[i];
535 }
536
538 template <class T, class R>
540 : public RandomAccessIteratorFacade<RealIterator<T,R>, T, R>
541 {
542 public:
545 {
546 p = nullptr;
547 i = 0;
548 }
549
551 RealIterator (window_type* _p, size_type _i)
552 : p(_p), i(_i)
553 {}
554
557 {
558 ++i;
559 }
560
563 {
564 --i;
565 }
566
568 bool equals (const RealIterator& it) const
569 {
570 return (p+i)==(it.p+it.i);
571 }
572
574 window_type& dereference () const
575 {
576 return p[i];
577 }
578
579 void advance(std::ptrdiff_t d)
580 {
581 i+=d;
582 }
583
584 std::ptrdiff_t distanceTo(const RealIterator& o) const
585 {
586 return o.i-i;
587 }
588
589 // Needed for operator[] of the iterator
590 window_type& elementAt (std::ptrdiff_t offset) const
591 {
592 return p[i+offset];
593 }
594
597 {
598 return i;
599 }
600
601 private:
602 window_type* p;
603 size_type i;
604 };
605
606 using Iterator = RealIterator<value_type,window_type&>;
607
610 {
611 return Iterator(block,0);
612 }
613
616 {
617 return Iterator(block,nblocks);
618 }
619
623 {
624 return Iterator(block,nblocks-1);
625 }
626
630 {
631 return Iterator(block,-1);
632 }
633
636
639
642
645 {
646 return ConstIterator(block,0);
647 }
648
651 {
652 return ConstIterator(block,nblocks);
653 }
654
658 {
659 return ConstIterator(block,nblocks-1);
660 }
661
664 {
665 return ConstIterator(block,-1);
666 }
667
670 {
671 return Iterator(block,std::min(i,nblocks));
672 }
673
676 {
677 return ConstIterator(block,std::min(i,nblocks));
678 }
679
680 //===== sizes
681
683 size_type N () const
684 {
685 return nblocks;
686 }
687
693 {
694 return nblocks;
695 }
696
697
698 private:
699 size_type nblocks; // number of blocks in vector
700 window_type* block; // array of blocks pointing to the array in the base class
701 bool initialized; // true if vector has been initialized
702
703 A allocator_;
704
705 typename A::template rebind<window_type>::other windowAllocator_;
706 };
707
708
709
712} // end namespace
713
714#endif
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:317
derive error class from the base class in common
Definition: istlexception.hh:16
Base class for stl conformant forward iterators.
Definition: iteratorfacades.hh:433
Iterator class for sequential creation of blocks.
Definition: vbvector.hh:404
bool operator==(const CreateIterator &it) const
equality
Definition: vbvector.hh:472
size_type index() const
dereferencing
Definition: vbvector.hh:478
bool operator!=(const CreateIterator &it) const
inequality
Definition: vbvector.hh:466
void setblocksize(size_type _k)
set size of current block
Definition: vbvector.hh:484
CreateIterator(VariableBlockVector &_v, int _i)
constructor
Definition: vbvector.hh:407
CreateIterator & operator++()
prefix increment
Definition: vbvector.hh:415
Iterator class for sequential access.
Definition: vbvector.hh:541
RealIterator(window_type *_p, size_type _i)
constructor
Definition: vbvector.hh:551
bool equals(const RealIterator &it) const
equality
Definition: vbvector.hh:568
size_type index() const
Return the index of the entry this iterator is pointing to.
Definition: vbvector.hh:596
void decrement()
prefix decrement
Definition: vbvector.hh:562
void increment()
prefix increment
Definition: vbvector.hh:556
RealIterator()
constructor, no arguments
Definition: vbvector.hh:544
window_type & dereference() const
dereferencing
Definition: vbvector.hh:574
A Vector of blocks with different blocksizes.
Definition: vbvector.hh:41
VariableBlockVector()
Definition: vbvector.hh:94
@ blocklevel
The number of blocklevels this vector contains.
Definition: vbvector.hh:86
A allocator_type
export the allocator type
Definition: vbvector.hh:53
VariableBlockVector(size_type _nblocks, size_type m)
Definition: vbvector.hh:131
size_type size() const
Definition: vbvector.hh:692
size_type N() const
number of blocks in the vector (are of variable size here)
Definition: vbvector.hh:683
VariableBlockVector(const VariableBlockVector &a)
copy constructor, has copy semantics
Definition: vbvector.hh:169
VariableBlockVector(size_type _nblocks)
Definition: vbvector.hh:105
~VariableBlockVector()
free dynamic memory
Definition: vbvector.hh:212
window_type & operator[](size_type i)
random access to blocks
Definition: vbvector.hh:520
CreateIterator createend()
get create iterator pointing to one after the last block
Definition: vbvector.hh:509
B::field_type field_type
export the type representing the field
Definition: vbvector.hh:50
Iterator beforeBegin() const
Definition: vbvector.hh:629
CreateIterator createbegin()
get initial create iterator
Definition: vbvector.hh:500
VariableBlockVector & operator=(const VariableBlockVector &a)
assignment
Definition: vbvector.hh:319
ConstIterator rend() const
end ConstIterator
Definition: vbvector.hh:663
A::size_type size_type
The size type for the index access.
Definition: vbvector.hh:68
ConstIterator find(size_type i) const
random access returning iterator (end if not contained)
Definition: vbvector.hh:675
ConstIterator beforeEnd() const
Definition: vbvector.hh:657
Iterator find(size_type i)
random access returning iterator (end if not contained)
Definition: vbvector.hh:669
const window_type & const_reference
Export type used for const references to container entries.
Definition: vbvector.hh:65
RealIterator< const value_type, const window_type & > ConstIterator
Const iterator.
Definition: vbvector.hh:638
Iterator end()
end Iterator
Definition: vbvector.hh:615
ConstIterator begin() const
begin ConstIterator
Definition: vbvector.hh:644
BlockVector< B, A > value_type
Type of the elements of the outer vector, i.e., dynamic vectors of B.
Definition: vbvector.hh:75
ConstIterator end() const
end ConstIterator
Definition: vbvector.hh:650
BlockVector< B, A > block_type
Same as value_type, here for historical reasons.
Definition: vbvector.hh:79
void resize(size_type _nblocks, size_type m)
same effect as constructor with same argument
Definition: vbvector.hh:267
window_type & reference
Export type used for references to container entries.
Definition: vbvector.hh:59
void resize(size_type _nblocks)
same effect as constructor with same argument
Definition: vbvector.hh:231
Iterator beforeEnd()
Definition: vbvector.hh:622
Iterator begin()
begin Iterator
Definition: vbvector.hh:609
#define DUNE_THROW(E, m)
Definition: exceptions.hh:216
This file implements iterator facade classes for writing stl conformant iterators.
Dune namespace.
Definition: alignedallocator.hh:10
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 24, 23:30, 2024)