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 
19 namespace 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:
407  CreateIterator (VariableBlockVector& _v, int _i) : v(_v)
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 
478  size_type index () const
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 
556  void increment()
557  {
558  ++i;
559  }
560 
562  void decrement()
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 
596  size_type index() const
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 
692  size_type size () const
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
CreateIterator & operator++()
prefix increment
Definition: vbvector.hh:415
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
Iterator class for sequential access.
Definition: vbvector.hh:541
RealIterator(window_type *_p, size_type _i)
constructor
Definition: vbvector.hh:551
window_type & dereference() const
dereferencing
Definition: vbvector.hh:574
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
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
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
window_type & operator[](size_type i)
random access to blocks
Definition: vbvector.hh:520
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.80.0 (May 1, 22:29, 2024)