vbvector.hh
Go to the documentation of this file.00001 #ifndef DUNE_VBVECTOR_HH
00002 #define DUNE_VBVECTOR_HH
00003
00004 #include<cmath>
00005 #include<complex>
00006 #include<iostream>
00007
00008 #include "istlexception.hh"
00009 #include "allocator.hh"
00010 #include "bvector.hh"
00011
00016 namespace Dune {
00017
00033 template<class B, class A=ISTLAllocator>
00034 class VariableBlockVector : public block_vector_unmanaged<B,A>
00035
00036
00037
00038 {
00039 public:
00040
00041
00042
00044 typedef typename B::field_type field_type;
00045
00047 typedef A allocator_type;
00048
00053 typedef BlockVector<B,A> block_type;
00054
00058 enum {
00060 blocklevel = B::blocklevel+2};
00061
00062
00063 typedef BlockVectorWindow<B,A> window_type;
00064
00065
00066
00067
00071 VariableBlockVector () : block_vector_unmanaged<B,A>()
00072 {
00073
00074 nblocks = 0;
00075 block = 0;
00076 initialized = false;
00077 }
00078
00082 explicit VariableBlockVector (int _nblocks) : block_vector_unmanaged<B,A>()
00083 {
00084
00085 nblocks = _nblocks;
00086 if (nblocks>0)
00087 {
00088 block = A::template malloc<window_type>(nblocks);
00089 }
00090 else
00091 {
00092 nblocks = 0;
00093 block = 0;;
00094 }
00095
00096
00097
00098 initialized = false;
00099 }
00100
00104 VariableBlockVector (int _nblocks, int m) : block_vector_unmanaged<B,A>()
00105 {
00106
00107 this->n = _nblocks*m;
00108 if (this->n>0)
00109 {
00110 this->p = A::template malloc<B>(this->n);
00111 }
00112 else
00113 {
00114 this->n = 0;
00115 this->p = 0;
00116 }
00117
00118
00119 nblocks = _nblocks;
00120 if (nblocks>0)
00121 {
00122
00123 block = A::template malloc<window_type>(nblocks);
00124
00125
00126 for (int i=0; i<nblocks; ++i)
00127 block[i].set(m,this->p+(i*m));
00128 }
00129 else
00130 {
00131 nblocks = 0;
00132 block = 0;;
00133 }
00134
00135
00136 initialized = true;
00137 }
00138
00140 VariableBlockVector (const VariableBlockVector& a)
00141 {
00142
00143 this->n = a.n;
00144 if (this->n>0)
00145 {
00146
00147 this->p = A::template malloc<B>(this->n);
00148
00149
00150 for (int i=0; i<this->n; i++) this->p[i]=a.p[i];
00151 }
00152 else
00153 {
00154 this->n = 0;
00155 this->p = 0;
00156 }
00157
00158
00159 nblocks = a.nblocks;
00160 if (nblocks>0)
00161 {
00162
00163 block = A::template malloc<window_type>(nblocks);
00164
00165
00166 block[0].set(a.block[0].getsize(),this->p);
00167 for (int i=1; i<nblocks; ++i)
00168 block[i].set(a.block[i].getsize(),block[i-1].getptr()+block[i-1].getsize());
00169 }
00170 else
00171 {
00172 nblocks = 0;
00173 block = 0;;
00174 }
00175
00176
00177 initialized = true;
00178 }
00179
00181 ~VariableBlockVector ()
00182 {
00183 if (this->n>0) A::template free<B>(this->p);
00184 if (nblocks>0) A::template free<window_type>(block);
00185 }
00186
00187
00189 void resize (int _nblocks)
00190 {
00191
00192 if (this->n>0) A::template free<B>(this->p);
00193 if (nblocks>0) A::template free<window_type>(block);
00194 this->n = 0;
00195 this->p = 0;
00196
00197
00198 nblocks = _nblocks;
00199 if (nblocks>0)
00200 {
00201 block = A::template malloc<window_type>(nblocks);
00202 }
00203 else
00204 {
00205 nblocks = 0;
00206 block = 0;;
00207 }
00208
00209
00210 initialized = false;
00211 }
00212
00214 void resize (int _nblocks, int m)
00215 {
00216
00217 if (this->n>0) A::template free<B>(this->p);
00218 if (nblocks>0) A::template free<window_type>(block);
00219
00220
00221 this->n = _nblocks*m;
00222 if (this->n>0)
00223 {
00224 this->p = A::template malloc<B>(this->n);
00225 }
00226 else
00227 {
00228 this->n = 0;
00229 this->p = 0;
00230 }
00231
00232
00233 nblocks = _nblocks;
00234 if (nblocks>0)
00235 {
00236
00237 block = A::template malloc<window_type>(nblocks);
00238
00239
00240 for (int i=0; i<nblocks; ++i)
00241 block[i].set(m,this->p+(i*m));
00242 }
00243 else
00244 {
00245 nblocks = 0;
00246 block = 0;;
00247 }
00248
00249
00250 initialized = true;
00251 }
00252
00254 VariableBlockVector& operator= (const VariableBlockVector& a)
00255 {
00256 if (&a!=this)
00257 {
00258
00259
00260 if (this->n!=a.n || nblocks!=a.nblocks)
00261 {
00262
00263 if (this->n>0) A::template free<B>(this->p);
00264 if (nblocks>0) A::template free<window_type>(block);
00265
00266
00267 this->n = a.n;
00268 if (this->n>0)
00269 {
00270
00271 this->p = A::template malloc<B>(this->n);
00272 }
00273 else
00274 {
00275 this->n = 0;
00276 this->p = 0;
00277 }
00278
00279
00280 nblocks = a.nblocks;
00281 if (nblocks>0)
00282 {
00283
00284 block = A::template malloc<window_type>(nblocks);
00285 }
00286 else
00287 {
00288 nblocks = 0;
00289 block = 0;;
00290 }
00291 }
00292
00293
00294
00295 if (nblocks>0)
00296 {
00297 block[0].set(a.block[0].getsize(),this->p);
00298 for (int i=1; i<nblocks; ++i)
00299 block[i].set(a.block[i].getsize(),block[i-1].getptr()+block[i-1].getsize());
00300 }
00301
00302
00303 for (int i=0; i<this->n; i++) this->p[i]=a.p[i];
00304 }
00305
00306
00307 initialized = true;
00308
00309 return *this;
00310 }
00311
00312
00313
00314
00316 VariableBlockVector& operator= (const field_type& k)
00317 {
00318 (static_cast<block_vector_unmanaged<B,A>&>(*this)) = k;
00319 return *this;
00320 }
00321
00322
00323
00324
00326 class CreateIterator
00327 {
00328 public:
00330 CreateIterator (VariableBlockVector& _v, int _i) : v(_v)
00331 {
00332 i = _i;
00333 k = 0;
00334 n = 0;
00335 }
00336
00338 CreateIterator& operator++()
00339 {
00340
00341
00342
00343 v.block[i].setsize(k);
00344
00345
00346 n += k;
00347
00348
00349 ++i;
00350
00351
00352 k = 0;
00353
00354
00355 if (i==v.nblocks)
00356 {
00357
00358 v.n = n;
00359 if (n>0)
00360 {
00361
00362 v.p = A::template malloc<B>(n);
00363 }
00364 else
00365 {
00366 v.n = 0;
00367 v.p = 0;
00368 }
00369
00370
00371 if (v.nblocks>0)
00372 {
00373 v.block[0].setptr(v.p);
00374 for (int j=1; j<v.nblocks; ++j)
00375 v.block[j].setptr(v.block[j-1].getptr()+v.block[j-1].getsize());
00376 }
00377
00378
00379 v.initialized = true;
00380
00381
00382 }
00383
00384 return *this;
00385 }
00386
00388 bool operator!= (const CreateIterator& it) const
00389 {
00390 return (i!=it.i) || (&v!=&it.v);
00391 }
00392
00394 bool operator== (const CreateIterator& it) const
00395 {
00396 return (i==it.i) && (&v==&it.v);
00397 }
00398
00400 int index () const
00401 {
00402 return i;
00403 }
00404
00406 void setblocksize (int _k)
00407 {
00408 k = _k;
00409 }
00410
00411 private:
00412 VariableBlockVector& v;
00413 int i;
00414 int k;
00415 int n;
00416 };
00417
00418
00419 friend class CreateIterator;
00420
00422 CreateIterator createbegin ()
00423 {
00424 #ifdef DUNE_ISTL_WITH_CHECKING
00425 if (initialized) DUNE_THROW(ISTLError,"no CreateIterator in initialized state");
00426 #endif
00427 return CreateIterator(*this,0);
00428 }
00429
00431 CreateIterator createend ()
00432 {
00433 return CreateIterator(*this,nblocks);
00434 }
00435
00436
00437
00438
00439
00440
00442 window_type& operator[] (int i)
00443 {
00444 #ifdef DUNE_ISTL_WITH_CHECKING
00445 if (i<0 || i>=nblocks) DUNE_THROW(ISTLError,"index out of range");
00446 #endif
00447 return block[i];
00448 }
00449
00451 const window_type& operator[] (int i) const
00452 {
00453 #ifdef DUNE_ISTL_WITH_CHECKING
00454 if (i<0 || i>=nblocks) DUNE_THROW(ISTLError,"index out of range");
00455 #endif
00456 return block[i];
00457 }
00458
00459
00460 class ConstIterator;
00461
00463 class Iterator
00464 {
00465 public:
00467 Iterator ()
00468 {
00469 p = 0;
00470 i = 0;
00471 }
00472
00474 Iterator (window_type* _p, int _i) : p(_p), i(_i)
00475 { }
00476
00478 Iterator& operator++()
00479 {
00480 ++i;
00481 return *this;
00482 }
00483
00485 Iterator& operator--()
00486 {
00487 --i;
00488 return *this;
00489 }
00490
00492 bool operator== (const Iterator& it) const
00493 {
00494 return (p+i)==(it.p+it.i);
00495 }
00496
00498 bool operator!= (const Iterator& it) const
00499 {
00500 return (p+i)!=(it.p+it.i);
00501 }
00502
00504 bool operator== (const ConstIterator& it) const
00505 {
00506 return (p+i)==(it.p+it.i);
00507 }
00508
00510 bool operator!= (const ConstIterator& it) const
00511 {
00512 return (p+i)!=(it.p+it.i);
00513 }
00514
00516 window_type& operator* () const
00517 {
00518 return p[i];
00519 }
00520
00522 window_type* operator-> () const
00523 {
00524 return p+i;
00525 }
00526
00527
00528 int index () const
00529 {
00530 return i;
00531 }
00532
00533 friend class ConstIterator;
00534
00535 private:
00536 window_type* p;
00537 int i;
00538 };
00539
00541 Iterator begin ()
00542 {
00543 return Iterator(block,0);
00544 }
00545
00547 Iterator end ()
00548 {
00549 return Iterator(block,nblocks);
00550 }
00551
00553 Iterator rbegin ()
00554 {
00555 return Iterator(block,nblocks-1);
00556 }
00557
00559 Iterator rend ()
00560 {
00561 return Iterator(block,-1);
00562 }
00563
00565 Iterator find (int i)
00566 {
00567 if (i>=0 && i<nblocks)
00568 return Iterator(block,i);
00569 else
00570 return Iterator(block,nblocks);
00571 }
00572
00574 ConstIterator find (int i) const
00575 {
00576 if (i>=0 && i<nblocks)
00577 return ConstIterator(block,i);
00578 else
00579 return ConstIterator(block,nblocks);
00580 }
00581
00583 class ConstIterator
00584 {
00585 public:
00587 ConstIterator ()
00588 {
00589 p = 0;
00590 i = 0;
00591 }
00592
00594 ConstIterator (const window_type* _p, int _i) : p(_p), i(_i)
00595 { }
00596
00598 ConstIterator (const Iterator& it) : p(it.p), i(it.i)
00599 { }
00600
00602 ConstIterator& operator++()
00603 {
00604 ++i;
00605 return *this;
00606 }
00607
00609 ConstIterator& operator--()
00610 {
00611 --i;
00612 return *this;
00613 }
00614
00616 bool operator== (const ConstIterator& it) const
00617 {
00618 return (p+i)==(it.p+it.i);
00619 }
00620
00622 bool operator!= (const ConstIterator& it) const
00623 {
00624 return (p+i)!=(it.p+it.i);
00625 }
00626
00628 bool operator== (const Iterator& it) const
00629 {
00630 return (p+i)==(it.p+it.i);
00631 }
00632
00634 bool operator!= (const Iterator& it) const
00635 {
00636 return (p+i)!=(it.p+it.i);
00637 }
00638
00640 const window_type& operator* () const
00641 {
00642 return p[i];
00643 }
00644
00646 const window_type* operator-> () const
00647 {
00648 return p+i;
00649 }
00650
00651
00652 int index () const
00653 {
00654 return i;
00655 }
00656
00657 friend class Iterator;
00658
00659 private:
00660 const window_type* p;
00661 int i;
00662 };
00663
00665 ConstIterator begin () const
00666 {
00667 return ConstIterator(block,0);
00668 }
00669
00671 ConstIterator end () const
00672 {
00673 return ConstIterator(block,nblocks);
00674 }
00675
00677 ConstIterator rbegin () const
00678 {
00679 return ConstIterator(block,nblocks-1);
00680 }
00681
00683 ConstIterator rend () const
00684 {
00685 return ConstIterator(block,-1);
00686 }
00687
00688
00689
00690
00692 int N () const
00693 {
00694 return nblocks;
00695 }
00696
00697
00698 private:
00699 int nblocks;
00700 window_type* block;
00701 bool initialized;
00702 };
00703
00704
00705
00708 }
00709
00710 #endif