00001 #ifndef DUNE_VBVECTOR_HH
00002 #define DUNE_VBVECTOR_HH
00003
00004 #include<math.h>
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 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 class ConstIterator
00575 {
00576 public:
00578 ConstIterator ()
00579 {
00580 p = 0;
00581 i = 0;
00582 }
00583
00585 ConstIterator (const window_type* _p, int _i) : p(_p), i(_i)
00586 { }
00587
00589 ConstIterator (const Iterator& it) : p(it.p), i(it.i)
00590 { }
00591
00593 ConstIterator& operator++()
00594 {
00595 ++i;
00596 return *this;
00597 }
00598
00600 ConstIterator& operator--()
00601 {
00602 --i;
00603 return *this;
00604 }
00605
00607 bool operator== (const ConstIterator& it) const
00608 {
00609 return (p+i)==(it.p+it.i);
00610 }
00611
00613 bool operator!= (const ConstIterator& it) const
00614 {
00615 return (p+i)!=(it.p+it.i);
00616 }
00617
00619 bool operator== (const Iterator& it) const
00620 {
00621 return (p+i)==(it.p+it.i);
00622 }
00623
00625 bool operator!= (const Iterator& it) const
00626 {
00627 return (p+i)!=(it.p+it.i);
00628 }
00629
00631 const window_type& operator* () const
00632 {
00633 return p[i];
00634 }
00635
00637 const window_type* operator-> () const
00638 {
00639 return p+i;
00640 }
00641
00642
00643 int index () const
00644 {
00645 return i;
00646 }
00647
00648 friend class Iterator;
00649
00650 private:
00651 const window_type* p;
00652 int i;
00653 };
00654
00656 ConstIterator begin () const
00657 {
00658 return ConstIterator(block,0);
00659 }
00660
00662 ConstIterator end () const
00663 {
00664 return ConstIterator(block,nblocks);
00665 }
00666
00668 ConstIterator rbegin () const
00669 {
00670 return ConstIterator(block,nblocks-1);
00671 }
00672
00674 ConstIterator rend () const
00675 {
00676 return ConstIterator(block,-1);
00677 }
00678
00679
00680
00681
00683 int N () const
00684 {
00685 return nblocks;
00686 }
00687
00688
00689 private:
00690 int nblocks;
00691 window_type* block;
00692 bool initialized;
00693 };
00694
00695
00696
00699 }
00700
00701 #endif