00001
00002 #ifndef DUNE_FVECTOR_HH
00003 #define DUNE_FVECTOR_HH
00004
00005 #include<cmath>
00006 #include<cstddef>
00007 #include<complex>
00008
00009 #include "exceptions.hh"
00010 #include "genericiterator.hh"
00011
00012 namespace Dune {
00013
00024
00025 template<class K, int n> class FieldVector;
00026
00027 template<class K>
00028 inline double fvmeta_absreal (const K& k)
00029 {
00030 return std::abs(k);
00031 }
00032
00033 template<class K>
00034 inline double fvmeta_absreal (const std::complex<K>& c)
00035 {
00036 return fvmeta_abs(c.real()) + fvmeta_abs(c.imag());
00037 }
00038
00039 template<class K>
00040 inline double fvmeta_abs2 (const K& k)
00041 {
00042 return k*k;
00043 }
00044
00045 template<class K>
00046 inline double fvmeta_abs2 (const std::complex<K>& c)
00047 {
00048 return c.real()*c.real() + c.imag()*c.imag();
00049 }
00050
00052 template<class C, class T>
00053 class FieldIterator :
00054 public Dune::RandomAccessIteratorFacade<FieldIterator<C,T>,T, T&, int>
00055 {
00056 friend class FieldIterator<typename Dune::RemoveConst<C>::Type, typename Dune::RemoveConst<T>::Type >;
00057 friend class FieldIterator<const typename Dune::RemoveConst<C>::Type, const typename Dune::RemoveConst<T>::Type >;
00058
00059 public:
00060
00064 typedef std::ptrdiff_t DifferenceType;
00065
00066
00067 FieldIterator()
00068 : container_(0), position_(0)
00069 {}
00070
00071 FieldIterator(C& cont, DifferenceType pos)
00072 : container_(&cont), position_(pos)
00073 {}
00074
00075 FieldIterator(const FieldIterator<typename Dune::RemoveConst<C>::Type, typename Dune::RemoveConst<T>::Type >& other)
00076 : container_(other.container_), position_(other.position_)
00077 {}
00078
00079
00080 bool equals(const FieldIterator<typename Dune::RemoveConst<C>::Type,typename Dune::RemoveConst<T>::Type>& other) const
00081 {
00082 return position_ == other.position_ && container_ == other.container_;
00083 }
00084
00085
00086 bool equals(const FieldIterator<const typename Dune::RemoveConst<C>::Type,const typename Dune::RemoveConst<T>::Type>& other) const
00087 {
00088 return position_ == other.position_ && container_ == other.container_;
00089 }
00090
00091 T& dereference() const{
00092 return container_->operator[](position_);
00093 }
00094
00095 void increment(){
00096 ++position_;
00097 }
00098
00099
00100 void decrement(){
00101 --position_;
00102 }
00103
00104
00105 T& elementAt(DifferenceType i)const{
00106 return container_->operator[](position_+i);
00107 }
00108
00109 void advance(DifferenceType n){
00110 position_=position_+n;
00111 }
00112
00113 std::ptrdiff_t distanceTo(FieldIterator<const typename Dune::RemoveConst<C>::Type,const typename Dune::RemoveConst<T>::Type> other)const
00114 {
00115 assert(other.container_==container_);
00116 return other.position_ - position_;
00117 }
00118
00119 std::ptrdiff_t distanceTo(FieldIterator<typename Dune::RemoveConst<C>::Type, typename Dune::RemoveConst<T>::Type> other)const
00120 {
00121 assert(other.container_==container_);
00122 return other.position_ - position_;
00123 }
00124
00126 DifferenceType index () const
00127 {
00128 return this->position_;
00129 }
00130
00131 private:
00132 C *container_;
00133 DifferenceType position_;
00134 };
00135
00137 template<class T>
00138 struct IteratorType
00139 {
00140 typedef typename T::Iterator type;
00141 };
00142
00143 template<class T>
00144 struct IteratorType<const T>
00145 {
00146 typedef typename T::ConstIterator type;
00147 };
00148
00158 template<class K, int SIZE>
00159 class FieldVector
00160 {
00161 public:
00162
00163 enum { dimension = SIZE };
00164
00165
00166
00167
00168
00170 typedef K field_type;
00171
00173 typedef K block_type;
00174
00176 typedef std::size_t size_type;
00177
00179 enum {
00181 blocklevel = 1
00182 };
00183
00185 enum {
00187 size = SIZE
00188 };
00189
00191 FieldVector() {}
00192
00194 explicit FieldVector (const K& t)
00195 {
00196 for (size_type i=0; i<SIZE; i++) p[i] = t;
00197 }
00198
00199
00201 FieldVector& operator= (const K& k)
00202 {
00203
00204 for (size_type i=0; i<SIZE; i++)
00205 p[i] = k;
00206 return *this;
00207 }
00208
00209
00210
00212 K& operator[] (size_type i)
00213 {
00214 #ifdef DUNE_ISTL_WITH_CHECKING
00215 if (i<0 || i>=SIZE) DUNE_THROW(MathError,"index out of range");
00216 #endif
00217 return p[i];
00218 }
00219
00221 const K& operator[] (size_type i) const
00222 {
00223 #ifdef DUNE_ISTL_WITH_CHECKING
00224 if (i<0 || i>=SIZE) DUNE_THROW(MathError,"index out of range");
00225 #endif
00226 return p[i];
00227 }
00228
00230 typedef FieldIterator<FieldVector<K,SIZE>,K> Iterator;
00232 typedef Iterator iterator;
00233
00235 Iterator begin ()
00236 {
00237 return Iterator(*this,0);
00238 }
00239
00241 Iterator end ()
00242 {
00243 return Iterator(*this,SIZE);
00244 }
00245
00247 Iterator rbegin ()
00248 {
00249 return Iterator(*this,SIZE-1);
00250 }
00251
00253 Iterator rend ()
00254 {
00255 return Iterator(*this,-1);
00256 }
00257
00259 Iterator find (size_type i)
00260 {
00261 if (i<SIZE)
00262 return Iterator(*this,i);
00263 else
00264 return Iterator(*this,SIZE);
00265 }
00266
00268 typedef FieldIterator<const FieldVector<K,SIZE>,const K> ConstIterator;
00270 typedef ConstIterator const_iterator;
00271
00273 ConstIterator begin () const
00274 {
00275 return ConstIterator(*this,0);
00276 }
00277
00279 ConstIterator end () const
00280 {
00281 return ConstIterator(*this,SIZE);
00282 }
00283
00285 ConstIterator rbegin () const
00286 {
00287 return ConstIterator(*this,SIZE-1);
00288 }
00289
00291 ConstIterator rend () const
00292 {
00293 return ConstIterator(*this,-1);
00294 }
00295
00297 ConstIterator find (size_type i) const
00298 {
00299 if (i<SIZE)
00300 return ConstIterator(*this,i);
00301 else
00302 return ConstIterator(*this,SIZE);
00303 }
00304
00305
00306
00308 FieldVector& operator+= (const FieldVector& y)
00309 {
00310 for (size_type i=0; i<SIZE; i++)
00311 p[i] += y.p[i];
00312 return *this;
00313 }
00314
00316 FieldVector& operator-= (const FieldVector& y)
00317 {
00318 for (size_type i=0; i<SIZE; i++)
00319 p[i] -= y.p[i];
00320 return *this;
00321 }
00322
00324 FieldVector<K, size> operator+ (const FieldVector<K, size>& b) const
00325 {
00326 FieldVector<K, size> z = *this;
00327 return (z+=b);
00328 }
00329
00331 FieldVector<K, size> operator- (const FieldVector<K, size>& b) const
00332 {
00333 FieldVector<K, size> z = *this;
00334 return (z-=b);
00335 }
00336
00338 FieldVector& operator+= (const K& k)
00339 {
00340 for (size_type i=0; i<SIZE; i++)
00341 p[i] += k;
00342 return *this;
00343 }
00344
00346 FieldVector& operator-= (const K& k)
00347 {
00348 for (size_type i=0; i<SIZE; i++)
00349 p[i] -= k;
00350 return *this;
00351 }
00352
00354 FieldVector& operator*= (const K& k)
00355 {
00356 for (size_type i=0; i<SIZE; i++)
00357 p[i] *= k;
00358 return *this;
00359 }
00360
00362 FieldVector& operator/= (const K& k)
00363 {
00364 for (size_type i=0; i<SIZE; i++)
00365 p[i] /= k;
00366 return *this;
00367 }
00368
00370 bool operator== (const FieldVector& y) const
00371 {
00372 for (size_type i=0; i<SIZE; i++)
00373 if (p[i]!=y.p[i])
00374 return false;
00375
00376 return true;
00377 }
00378
00380 FieldVector& axpy (const K& a, const FieldVector& y)
00381 {
00382 for (size_type i=0; i<SIZE; i++)
00383 p[i] += a*y.p[i];
00384 return *this;
00385 }
00386
00387
00388
00390 K operator* (const FieldVector& y) const
00391 {
00392 K result = 0;
00393 for (int i=0; i<size; i++)
00394 result += p[i]*y[i];
00395 return result;
00396 }
00397
00398
00399
00400
00402 double one_norm() const {
00403 double result = 0;
00404 for (int i=0; i<size; i++)
00405 result += std::abs(p[i]);
00406 return result;
00407 }
00408
00409
00411 double one_norm_real () const
00412 {
00413 double result = 0;
00414 for (int i=0; i<size; i++)
00415 result += fvmeta_absreal(p[i]);
00416 return result;
00417 }
00418
00420 double two_norm () const
00421 {
00422 double result = 0;
00423 for (int i=0; i<size; i++)
00424 result += fvmeta_abs2(p[i]);
00425 return std::sqrt(result);
00426 }
00427
00429 double two_norm2 () const
00430 {
00431 double result = 0;
00432 for (int i=0; i<size; i++)
00433 result += fvmeta_abs2(p[i]);
00434 return result;
00435 }
00436
00438 double infinity_norm () const
00439 {
00440 double result = 0;
00441 for (int i=0; i<size; i++)
00442 result = std::max(result, std::abs(p[i]));
00443 return result;
00444 }
00445
00447 double infinity_norm_real () const
00448 {
00449 double result = 0;
00450 for (int i=0; i<size; i++)
00451 result = std::max(result, fvmeta_absreal(p[i]));
00452 return result;
00453 }
00454
00455
00456
00458 size_type N () const
00459 {
00460 return SIZE;
00461 }
00462
00464 size_type dim () const
00465 {
00466 return SIZE;
00467 }
00468
00469 private:
00470
00471 K p[(SIZE > 0) ? SIZE : 1];
00472 };
00473
00475 template<typename K, int n>
00476 std::ostream& operator<< (std::ostream& s, const FieldVector<K,n>& v)
00477 {
00478 for (typename FieldVector<K,n>::size_type i=0; i<n; i++)
00479 s << ((i>0) ? " " : "") << v[i];
00480 return s;
00481 }
00482
00483
00484
00485 template<class K, int n, int m> class FieldMatrix;
00486
00489 template<class K>
00490 class FieldVector<K,1>
00491 {
00492 enum { n = 1 };
00493 public:
00494 friend class FieldMatrix<K,1,1>;
00495
00496
00497
00499 typedef K field_type;
00500
00502 typedef K block_type;
00503
00505 typedef std::size_t size_type;
00506
00508 enum {blocklevel = 1};
00509
00511 enum {size = 1};
00512
00514 enum {dimension = 1};
00515
00516
00517
00519 FieldVector ()
00520 { }
00521
00523 FieldVector (const K& k)
00524 {
00525 p = k;
00526 }
00527
00529 FieldVector& operator= (const K& k)
00530 {
00531 p = k;
00532 return *this;
00533 }
00534
00535
00536
00538 K& operator[] (size_type i)
00539 {
00540 #ifdef DUNE_ISTL_WITH_CHECKING
00541 if (i != 0) DUNE_THROW(MathError,"index out of range");
00542 #endif
00543 return p;
00544 }
00545
00547 const K& operator[] (size_type i) const
00548 {
00549 #ifdef DUNE_ISTL_WITH_CHECKING
00550 if (i != 0) DUNE_THROW(MathError,"index out of range");
00551 #endif
00552 return p;
00553 }
00554
00556 typedef FieldIterator<FieldVector<K,n>,K> Iterator;
00558 typedef Iterator iterator;
00559
00561 Iterator begin ()
00562 {
00563 return Iterator(*this,0);
00564 }
00565
00567 Iterator end ()
00568 {
00569 return Iterator(*this,n);
00570 }
00571
00573 Iterator rbegin ()
00574 {
00575 return Iterator(*this,n-1);
00576 }
00577
00579 Iterator rend ()
00580 {
00581 return Iterator(*this,-1);
00582 }
00583
00585 Iterator find (size_type i)
00586 {
00587 if (i<n)
00588 return Iterator(*this,i);
00589 else
00590 return Iterator(*this,n);
00591 }
00592
00594 typedef FieldIterator<const FieldVector<K,n>,const K> ConstIterator;
00596 typedef ConstIterator const_iterator;
00597
00599 ConstIterator begin () const
00600 {
00601 return ConstIterator(*this,0);
00602 }
00603
00605 ConstIterator end () const
00606 {
00607 return ConstIterator(*this,n);
00608 }
00609
00611 ConstIterator rbegin () const
00612 {
00613 return ConstIterator(*this,n-1);
00614 }
00615
00617 ConstIterator rend () const
00618 {
00619 return ConstIterator(*this,-1);
00620 }
00621
00623 ConstIterator find (size_type i) const
00624 {
00625 if (i<n)
00626 return ConstIterator(*this,i);
00627 else
00628 return ConstIterator(*this,n);
00629 }
00630
00631
00633 FieldVector& operator+= (const FieldVector& y)
00634 {
00635 p += y.p;
00636 return *this;
00637 }
00638
00640 FieldVector& operator-= (const FieldVector& y)
00641 {
00642 p -= y.p;
00643 return *this;
00644 }
00645
00647 FieldVector& operator+= (const K& k)
00648 {
00649 p += k;
00650 return *this;
00651 }
00652
00654 FieldVector& operator-= (const K& k)
00655 {
00656 p -= k;
00657 return *this;
00658 }
00659
00661 FieldVector& operator*= (const K& k)
00662 {
00663 p *= k;
00664 return *this;
00665 }
00666
00668 FieldVector& operator/= (const K& k)
00669 {
00670 p /= k;
00671 return *this;
00672 }
00673
00675 FieldVector& axpy (const K& a, const FieldVector& y)
00676 {
00677 p += a*y.p;
00678 return *this;
00679 }
00680
00681
00682
00684 double one_norm () const
00685 {
00686 return std::abs(p);
00687 }
00688
00690 double one_norm_real () const
00691 {
00692 return fvmeta_abs_real(p);
00693 }
00694
00696 double two_norm () const
00697 {
00698 return sqrt(fvmeta_abs2(p));
00699 }
00700
00702 double two_norm2 () const
00703 {
00704 return fvmeta_abs2(p);
00705 }
00706
00708 double infinity_norm () const
00709 {
00710 return std::abs(p);
00711 }
00712
00714 double infinity_norm_real () const
00715 {
00716 return fvmeta_abs_real(p);
00717 }
00718
00719
00720
00721
00723 size_type N () const
00724 {
00725 return 1;
00726 }
00727
00729 size_type dim () const
00730 {
00731 return 1;
00732 }
00733
00734
00735
00737 operator K () {return p;}
00738
00740 operator K () const {return p;}
00741
00742 private:
00743
00744 K p;
00745 };
00746
00748 template<class K>
00749 inline FieldVector<K,1> operator+ (const FieldVector<K,1>& a, const FieldVector<K,1>& b)
00750 {
00751 FieldVector<K,1> z = a;
00752 return (z+=b);
00753 }
00754
00756 template<class K>
00757 inline FieldVector<K,1> operator- (const FieldVector<K,1>& a, const FieldVector<K,1>& b)
00758 {
00759 FieldVector<K,1> z = a;
00760 return (z-=b);
00761 }
00762
00764 template<class K>
00765 inline FieldVector<K,1> operator+ (const FieldVector<K,1>& a, const K b)
00766 {
00767 FieldVector<K,1> z = a;
00768 return (z[0]+=b);
00769 }
00770
00772 template<class K>
00773 inline FieldVector<K,1> operator- (const FieldVector<K,1>& a, const K b)
00774 {
00775 FieldVector<K,1> z = a;
00776 return (z[0]-=b);
00777 }
00778
00780 template<class K>
00781 inline FieldVector<K,1> operator+ (const K a, const FieldVector<K,1>& b)
00782 {
00783 FieldVector<K,1> z = a;
00784 return (z[0]+=b);
00785 }
00786
00788 template<class K>
00789 inline FieldVector<K,1> operator- (const K a, const FieldVector<K,1>& b)
00790 {
00791 FieldVector<K,1> z = a;
00792 return (z[0]-=b);
00793 }
00794
00797 }
00798
00799 #endif