Dune Core Modules (2.4.2)

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 
11 #include "istlexception.hh"
12 #include "bvector.hh"
13 
18 namespace Dune {
19 
35  template<class B, class A=std::allocator<B> >
37  // this derivation gives us all the blas level 1 and norms
38  // on the large array. However, access operators have to be
39  // overwritten.
40  {
41  public:
42 
43  //===== type definitions and constants
44 
46  typedef typename B::field_type field_type;
47 
49  typedef A allocator_type;
50 
52  typedef typename A::size_type size_type;
53 
59 
63  enum {
65  blocklevel = B::blocklevel+2
66  };
67 
68  // just a shorthand
69  typedef BlockVectorWindow<B,A> window_type;
70 
71 
72  //===== constructors and such
73 
78  {
79  // nothing is known ...
80  nblocks = 0;
81  block = 0;
82  initialized = false;
83  }
84 
89  {
90  // we can allocate the windows now
91  nblocks = _nblocks;
92  if (nblocks>0)
93  {
94  block = windowAllocator_.allocate(nblocks);
95  new (block) window_type[nblocks];
96  }
97  else
98  {
99  nblocks = 0;
100  block = 0;;
101  }
102 
103  // Note: memory in base class still not allocated
104  // the vector not usable
105  initialized = false;
106  }
107 
115  {
116  // and we can allocate the big array in the base class
117  this->n = _nblocks*m;
118  if (this->n>0)
119  {
120  this->p = allocator_.allocate(this->n);
121  new (this->p)B[this->n];
122  }
123  else
124  {
125  this->n = 0;
126  this->p = 0;
127  }
128 
129  // we can allocate the windows now
130  nblocks = _nblocks;
131  if (nblocks>0)
132  {
133  // allocate and construct the windows
134  block = windowAllocator_.allocate(nblocks);
135  new (block) window_type[nblocks];
136 
137  // set the windows into the big array
138  for (size_type i=0; i<nblocks; ++i)
139  block[i].set(m,this->p+(i*m));
140  }
141  else
142  {
143  nblocks = 0;
144  block = 0;;
145  }
146 
147  // and the vector is usable
148  initialized = true;
149  }
150 
153  {
154  // allocate the big array in the base class
155  this->n = a.n;
156  if (this->n>0)
157  {
158  // allocate and construct objects
159  this->p = allocator_.allocate(this->n);
160  new (this->p)B[this->n];
161 
162  // copy data
163  for (size_type i=0; i<this->n; i++) this->p[i]=a.p[i];
164  }
165  else
166  {
167  this->n = 0;
168  this->p = 0;
169  }
170 
171  // we can allocate the windows now
172  nblocks = a.nblocks;
173  if (nblocks>0)
174  {
175  // alloc
176  block = windowAllocator_.allocate(nblocks);
177  new (block) window_type[nblocks];
178 
179  // and we must set the windows
180  block[0].set(a.block[0].getsize(),this->p); // first block
181  for (size_type i=1; i<nblocks; ++i) // and the rest
182  block[i].set(a.block[i].getsize(),block[i-1].getptr()+block[i-1].getsize());
183  }
184  else
185  {
186  nblocks = 0;
187  block = 0;;
188  }
189 
190  // and we have a usable vector
191  initialized = true;
192  }
193 
196  {
197  if (this->n>0) {
198  size_type i=this->n;
199  while (i)
200  this->p[--i].~B();
201  allocator_.deallocate(this->p,this->n);
202  }
203  if (nblocks>0) {
204  size_type i=nblocks;
205  while (i)
206  block[--i].~window_type();
207  windowAllocator_.deallocate(block,nblocks);
208  }
209 
210  }
211 
212 
214  void resize (size_type _nblocks)
215  {
216  // deconstruct objects and deallocate memory if necessary
217  if (this->n>0) {
218  size_type i=this->n;
219  while (i)
220  this->p[--i].~B();
221  allocator_.deallocate(this->p,this->n);
222  }
223  if (nblocks>0) {
224  size_type i=nblocks;
225  while (i)
226  block[--i].~window_type();
227  windowAllocator_.deallocate(block,nblocks);
228  }
229  this->n = 0;
230  this->p = 0;
231 
232  // we can allocate the windows now
233  nblocks = _nblocks;
234  if (nblocks>0)
235  {
236  block = windowAllocator_.allocate(nblocks);
237  new (block) window_type[nblocks];
238  }
239  else
240  {
241  nblocks = 0;
242  block = 0;;
243  }
244 
245  // and the vector not fully usable
246  initialized = false;
247  }
248 
250  void resize (size_type _nblocks, size_type m)
251  {
252  // deconstruct objects and deallocate memory if necessary
253  if (this->n>0) {
254  size_type i=this->n;
255  while (i)
256  this->p[--i].~B();
257  allocator_.deallocate(this->p,this->n);
258  }
259  if (nblocks>0) {
260  size_type i=nblocks;
261  while (i)
262  block[--i].~window_type();
263  windowAllocator_.deallocate(block,nblocks);
264  }
265 
266  // and we can allocate the big array in the base class
267  this->n = _nblocks*m;
268  if (this->n>0)
269  {
270  this->p = allocator_.allocate(this->n);
271  new (this->p)B[this->n];
272  }
273  else
274  {
275  this->n = 0;
276  this->p = 0;
277  }
278 
279  // we can allocate the windows now
280  nblocks = _nblocks;
281  if (nblocks>0)
282  {
283  // allocate and construct objects
284  block = windowAllocator_.allocate(nblocks);
285  new (block) window_type[nblocks];
286 
287  // set the windows into the big array
288  for (size_type i=0; i<nblocks; ++i)
289  block[i].set(m,this->p+(i*m));
290  }
291  else
292  {
293  nblocks = 0;
294  block = 0;;
295  }
296 
297  // and the vector is usable
298  initialized = true;
299  }
300 
303  {
304  if (&a!=this) // check if this and a are different objects
305  {
306  // reallocate arrays if necessary
307  // Note: still the block sizes may vary !
308  if (this->n!=a.n || nblocks!=a.nblocks)
309  {
310  // deconstruct objects and deallocate memory if necessary
311  if (this->n>0) {
312  size_type i=this->n;
313  while (i)
314  this->p[--i].~B();
315  allocator_.deallocate(this->p,this->n);
316  }
317  if (nblocks>0) {
318  size_type i=nblocks;
319  while (i)
320  block[--i].~window_type();
321  windowAllocator_.deallocate(block,nblocks);
322  }
323 
324  // allocate the big array in the base class
325  this->n = a.n;
326  if (this->n>0)
327  {
328  // allocate and construct objects
329  this->p = allocator_.allocate(this->n);
330  new (this->p)B[this->n];
331  }
332  else
333  {
334  this->n = 0;
335  this->p = 0;
336  }
337 
338  // we can allocate the windows now
339  nblocks = a.nblocks;
340  if (nblocks>0)
341  {
342  // alloc
343  block = windowAllocator_.allocate(nblocks);
344  new (block) window_type[nblocks];
345  }
346  else
347  {
348  nblocks = 0;
349  block = 0;;
350  }
351  }
352 
353  // copy block structure, might be different although
354  // sizes are the same !
355  if (nblocks>0)
356  {
357  block[0].set(a.block[0].getsize(),this->p); // first block
358  for (size_type i=1; i<nblocks; ++i) // and the rest
359  block[i].set(a.block[i].getsize(),block[i-1].getptr()+block[i-1].getsize());
360  }
361 
362  // and copy the data
363  for (size_type i=0; i<this->n; i++) this->p[i]=a.p[i];
364  }
365 
366  // and we have a usable vector
367  initialized = true;
368 
369  return *this; // Gebe Referenz zurueck damit a=b=c; klappt
370  }
371 
372 
373  //===== assignment from scalar
374 
377  {
378  (static_cast<block_vector_unmanaged<B,A>&>(*this)) = k;
379  return *this;
380  }
381 
382 
383  //===== the creation interface
384 
387  {
388  public:
390  CreateIterator (VariableBlockVector& _v, int _i) : v(_v)
391  {
392  i = _i;
393  k = 0;
394  n = 0;
395  }
396 
399  {
400  // we are at block i and the blocks size is known
401 
402  // set the blocks size to current k
403  v.block[i].setsize(k);
404 
405  // accumulate total size
406  n += k;
407 
408  // go to next block
409  ++i;
410 
411  // reset block size
412  k = 0;
413 
414  // if we are past the last block, finish off
415  if (i==v.nblocks)
416  {
417  // now we can allocate the big array in the base class of v
418  v.n = n;
419  if (n>0)
420  {
421  // allocate and construct objects
422  v.p = v.allocator_.allocate(n);
423  new (v.p)B[n];
424  }
425  else
426  {
427  v.n = 0;
428  v.p = 0;
429  }
430 
431  // and we set the window pointer
432  if (v.nblocks>0)
433  {
434  v.block[0].setptr(v.p); // pointer tofirst block
435  for (size_type j=1; j<v.nblocks; ++j) // and the rest
436  v.block[j].setptr(v.block[j-1].getptr()+v.block[j-1].getsize());
437  }
438 
439  // and the vector is ready
440  v.initialized = true;
441 
442  //std::cout << "made vbvector with " << v.n << " components" << std::endl;
443  }
444 
445  return *this;
446  }
447 
449  bool operator!= (const CreateIterator& it) const
450  {
451  return (i!=it.i) || (&v!=&it.v);
452  }
453 
455  bool operator== (const CreateIterator& it) const
456  {
457  return (i==it.i) && (&v==&it.v);
458  }
459 
461  size_type index () const
462  {
463  return i;
464  }
465 
468  {
469  k = _k;
470  }
471 
472  private:
473  VariableBlockVector& v; // my vector
474  size_type i; // current block to be defined
475  size_type k; // size of current block to be defined
476  size_type n; // total number of elements to be allocated
477  };
478 
479  // CreateIterator wants to set all the arrays ...
480  friend class CreateIterator;
481 
484  {
485 #ifdef DUNE_ISTL_WITH_CHECKING
486  if (initialized) DUNE_THROW(ISTLError,"no CreateIterator in initialized state");
487 #endif
488  return CreateIterator(*this,0);
489  }
490 
493  {
494  return CreateIterator(*this,nblocks);
495  }
496 
497 
498  //===== access to components
499  // has to be overwritten from base class because it must
500  // return access to the windows
501 
504  {
505 #ifdef DUNE_ISTL_WITH_CHECKING
506  if (i>=nblocks) DUNE_THROW(ISTLError,"index out of range");
507 #endif
508  return block[i];
509  }
510 
513  {
514 #ifdef DUNE_ISTL_WITH_CHECKING
515  if (i<0 || i>=nblocks) DUNE_THROW(ISTLError,"index out of range");
516 #endif
517  return block[i];
518  }
519 
520  // forward declaration
521  class ConstIterator;
522 
524  class Iterator
525  {
526  public:
529  {
530  p = 0;
531  i = 0;
532  }
533 
535  Iterator (window_type* _p, size_type _i) : p(_p), i(_i)
536  { }
537 
540  {
541  ++i;
542  return *this;
543  }
544 
547  {
548  --i;
549  return *this;
550  }
551 
553  bool operator== (const Iterator& it) const
554  {
555  return (p+i)==(it.p+it.i);
556  }
557 
559  bool operator!= (const Iterator& it) const
560  {
561  return (p+i)!=(it.p+it.i);
562  }
563 
565  bool operator== (const ConstIterator& it) const
566  {
567  return (p+i)==(it.p+it.i);
568  }
569 
571  bool operator!= (const ConstIterator& it) const
572  {
573  return (p+i)!=(it.p+it.i);
574  }
575 
578  {
579  return p[i];
580  }
581 
584  {
585  return p+i;
586  }
587 
588  // return index corresponding to pointer
589  size_type index () const
590  {
591  return i;
592  }
593 
594  friend class ConstIterator;
595 
596  private:
597  window_type* p;
598  size_type i;
599  };
600 
603  {
604  return Iterator(block,0);
605  }
606 
609  {
610  return Iterator(block,nblocks);
611  }
612 
616  {
617  return Iterator(block,nblocks-1);
618  }
619 
623  {
624  return Iterator(block,-1);
625  }
626 
629  {
630  if (i>=0 && i<nblocks)
631  return Iterator(block,i);
632  else
633  return Iterator(block,nblocks);
634  }
635 
638  {
639  if (i>=0 && i<nblocks)
640  return ConstIterator(block,i);
641  else
642  return ConstIterator(block,nblocks);
643  }
644 
647  {
648  public:
651  {
652  p = 0;
653  i = 0;
654  }
655 
657  ConstIterator (const window_type* _p, size_type _i) : p(_p), i(_i)
658  { }
659 
661  ConstIterator (const Iterator& it) : p(it.p), i(it.i)
662  { }
663 
666  {
667  ++i;
668  return *this;
669  }
670 
673  {
674  --i;
675  return *this;
676  }
677 
679  bool operator== (const ConstIterator& it) const
680  {
681  return (p+i)==(it.p+it.i);
682  }
683 
685  bool operator!= (const ConstIterator& it) const
686  {
687  return (p+i)!=(it.p+it.i);
688  }
689 
691  bool operator== (const Iterator& it) const
692  {
693  return (p+i)==(it.p+it.i);
694  }
695 
697  bool operator!= (const Iterator& it) const
698  {
699  return (p+i)!=(it.p+it.i);
700  }
701 
703  const window_type& operator* () const
704  {
705  return p[i];
706  }
707 
709  const window_type* operator-> () const
710  {
711  return p+i;
712  }
713 
714  // return index corresponding to pointer
715  size_type index () const
716  {
717  return i;
718  }
719 
720  friend class Iterator;
721 
722  private:
723  const window_type* p;
724  size_type i;
725  };
726 
729  {
730  return ConstIterator(block,0);
731  }
732 
735  {
736  return ConstIterator(block,nblocks);
737  }
738 
742  {
743  return ConstIterator(block,nblocks-1);
744  }
745 
748  {
749  return ConstIterator(block,-1);
750  }
751 
752 
753  //===== sizes
754 
756  size_type N () const
757  {
758  return nblocks;
759  }
760 
761 
762  private:
763  size_type nblocks; // number of blocks in vector
764  window_type* block; // array of blocks pointing to the array in the base class
765  bool initialized; // true if vector has been initialized
766 
767  A allocator_;
768 
769  typename A::template rebind<window_type>::other windowAllocator_;
770  };
771 
772 
773 
776 } // end namespace
777 
778 #endif
This file implements a vector space as a tensor product of a given vector space. The number of compon...
Definition: bvector.hh:584
void set(size_type _n, B *_p)
set size and pointer
Definition: bvector.hh:679
B * getptr()
get pointer
Definition: bvector.hh:698
size_type getsize()
get size
Definition: bvector.hh:704
void setsize(size_type _n)
set size only
Definition: bvector.hh:686
void setptr(B *_p)
set pointer only
Definition: bvector.hh:692
A vector of blocks with memory management.
Definition: bvector.hh:253
derive error class from the base class in common
Definition: istlexception.hh:16
ConstIterator class for sequential access.
Definition: vbvector.hh:647
ConstIterator(const Iterator &it)
constructor from non_const iterator
Definition: vbvector.hh:661
ConstIterator & operator--()
prefix decrement
Definition: vbvector.hh:672
ConstIterator & operator++()
prefix increment
Definition: vbvector.hh:665
bool operator!=(const ConstIterator &it) const
inequality
Definition: vbvector.hh:685
bool operator==(const ConstIterator &it) const
equality
Definition: vbvector.hh:679
const window_type * operator->() const
arrow
Definition: vbvector.hh:709
ConstIterator(const window_type *_p, size_type _i)
constructor from pointer
Definition: vbvector.hh:657
ConstIterator()
constructor
Definition: vbvector.hh:650
const window_type & operator*() const
dereferencing
Definition: vbvector.hh:703
Iterator class for sequential creation of blocks.
Definition: vbvector.hh:387
bool operator==(const CreateIterator &it) const
equality
Definition: vbvector.hh:455
size_type index() const
dereferencing
Definition: vbvector.hh:461
CreateIterator & operator++()
prefix increment
Definition: vbvector.hh:398
bool operator!=(const CreateIterator &it) const
inequality
Definition: vbvector.hh:449
void setblocksize(size_type _k)
set size of current block
Definition: vbvector.hh:467
CreateIterator(VariableBlockVector &_v, int _i)
constructor
Definition: vbvector.hh:390
Iterator class for sequential access.
Definition: vbvector.hh:525
bool operator==(const Iterator &it) const
equality
Definition: vbvector.hh:553
window_type & operator*() const
dereferencing
Definition: vbvector.hh:577
Iterator & operator++()
prefix increment
Definition: vbvector.hh:539
Iterator & operator--()
prefix decrement
Definition: vbvector.hh:546
Iterator(window_type *_p, size_type _i)
constructor
Definition: vbvector.hh:535
Iterator()
constructor, no arguments
Definition: vbvector.hh:528
window_type * operator->() const
arrow
Definition: vbvector.hh:583
bool operator!=(const Iterator &it) const
inequality
Definition: vbvector.hh:559
A Vector of blocks with different blocksizes.
Definition: vbvector.hh:40
VariableBlockVector()
Definition: vbvector.hh:77
A allocator_type
export the allocator type
Definition: vbvector.hh:49
VariableBlockVector(size_type _nblocks, size_type m)
Definition: vbvector.hh:114
size_type N() const
number of blocks in the vector (are of variable size here)
Definition: vbvector.hh:756
VariableBlockVector(const VariableBlockVector &a)
copy constructor, has copy semantics
Definition: vbvector.hh:152
VariableBlockVector(size_type _nblocks)
Definition: vbvector.hh:88
~VariableBlockVector()
free dynamic memory
Definition: vbvector.hh:195
@ blocklevel
The number of blocklevels this vector contains.
Definition: vbvector.hh:65
CreateIterator createend()
get create iterator pointing to one after the last block
Definition: vbvector.hh:492
B::field_type field_type
export the type representing the field
Definition: vbvector.hh:46
Iterator beforeBegin() const
Definition: vbvector.hh:622
CreateIterator createbegin()
get initial create iterator
Definition: vbvector.hh:483
VariableBlockVector & operator=(const VariableBlockVector &a)
assignment
Definition: vbvector.hh:302
ConstIterator rend() const
end ConstIterator
Definition: vbvector.hh:747
A::size_type size_type
The size type for the index access.
Definition: vbvector.hh:52
ConstIterator find(size_type i) const
random access returning iterator (end if not contained)
Definition: vbvector.hh:637
ConstIterator beforeEnd() const
Definition: vbvector.hh:741
Iterator find(size_type i)
random access returning iterator (end if not contained)
Definition: vbvector.hh:628
Iterator end()
end Iterator
Definition: vbvector.hh:608
ConstIterator begin() const
begin ConstIterator
Definition: vbvector.hh:728
window_type & operator[](size_type i)
random access to blocks
Definition: vbvector.hh:503
ConstIterator end() const
end ConstIterator
Definition: vbvector.hh:734
BlockVector< B, A > block_type
Definition: vbvector.hh:58
void resize(size_type _nblocks, size_type m)
same effect as constructor with same argument
Definition: vbvector.hh:250
void resize(size_type _nblocks)
same effect as constructor with same argument
Definition: vbvector.hh:214
Iterator beforeEnd()
Definition: vbvector.hh:615
Iterator begin()
begin Iterator
Definition: vbvector.hh:602
An unmanaged vector of blocks.
Definition: bvector.hh:42
base_array_unmanaged< B, std::allocator< B > >::iterator Iterator
make iterators available as types
Definition: bvector.hh:60
base_array_unmanaged< B, std::allocator< B > >::const_iterator ConstIterator
make iterators available as types
Definition: bvector.hh:63
#define DUNE_THROW(E, m)
Definition: exceptions.hh:243
Dune namespace.
Definition: alignment.hh:10
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 10, 22:30, 2024)