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 #ifdef DUNE_EXPRESSIONTEMPLATES
00013 #include "exprtmpl.hh"
00014 #endif
00015
00016 namespace Dune {
00017
00018 #ifndef DUNE_EXPRESSIONTEMPLATES
00019
00030
00031 template<class K, int n> class FieldVector;
00032
00033 #endif
00034
00035 #ifndef DUNE_EXPRESSIONTEMPLATES
00036
00037 template<class K>
00038 inline double fvmeta_absreal (const K& k)
00039 {
00040 return std::abs(k);
00041 }
00042
00043 template<class K>
00044 inline double fvmeta_absreal (const std::complex<K>& c)
00045 {
00046 return fvmeta_abs(c.real()) + fvmeta_abs(c.imag());
00047 }
00048
00049 template<class K>
00050 inline double fvmeta_abs2 (const K& k)
00051 {
00052 return k*k;
00053 }
00054
00055 template<class K>
00056 inline double fvmeta_abs2 (const std::complex<K>& c)
00057 {
00058 return c.real()*c.real() + c.imag()*c.imag();
00059 }
00060
00061 #endif
00062
00064 template<class C, class T>
00065 class FieldIterator :
00066 public Dune::RandomAccessIteratorFacade<FieldIterator<C,T>,T, T&, int>
00067 {
00068 friend class FieldIterator<typename remove_const<C>::type, typename remove_const<T>::type >;
00069 friend class FieldIterator<const typename remove_const<C>::type, const typename remove_const<T>::type >;
00070
00071 public:
00072
00076 typedef std::ptrdiff_t DifferenceType;
00077
00078
00079 FieldIterator()
00080 : container_(0), position_(0)
00081 {}
00082
00083 FieldIterator(C& cont, DifferenceType pos)
00084 : container_(&cont), position_(pos)
00085 {}
00086
00087 FieldIterator(const FieldIterator<typename remove_const<C>::type, typename remove_const<T>::type >& other)
00088 : container_(other.container_), position_(other.position_)
00089 {}
00090
00091 #if 0
00092 FieldIterator(const FieldIterator<const typename remove_const<C>::type, const typename remove_const<T>::type >& other)
00093 : container_(other.container_), position_(other.position_)
00094 {}
00095 #endif
00096 #if 0
00097 FieldIterator(const FieldIterator<C,T>& other)
00098 : container_(other.container_), position_(other.position_)
00099 {}
00100 #endif
00101
00102 bool equals(const FieldIterator<typename remove_const<C>::type,typename remove_const<T>::type>& other) const
00103 {
00104 return position_ == other.position_ && container_ == other.container_;
00105 }
00106
00107
00108 bool equals(const FieldIterator<const typename remove_const<C>::type,const typename remove_const<T>::type>& other) const
00109 {
00110 return position_ == other.position_ && container_ == other.container_;
00111 }
00112
00113 T& dereference() const{
00114 return container_->operator[](position_);
00115 }
00116
00117 void increment(){
00118 ++position_;
00119 }
00120
00121
00122 void decrement(){
00123 --position_;
00124 }
00125
00126
00127 T& elementAt(DifferenceType i)const{
00128 return container_->operator[](position_+i);
00129 }
00130
00131 void advance(DifferenceType n){
00132 position_=position_+n;
00133 }
00134
00135 std::ptrdiff_t distanceTo(FieldIterator<const typename remove_const<C>::type,const typename remove_const<T>::type> other)const
00136 {
00137 assert(other.container_==container_);
00138 return other.position_ - position_;
00139 }
00140
00141 std::ptrdiff_t distanceTo(FieldIterator<typename remove_const<C>::type, typename remove_const<T>::type> other)const
00142 {
00143 assert(other.container_==container_);
00144 return other.position_ - position_;
00145 }
00146
00148 DifferenceType index () const
00149 {
00150 return this->position_;
00151 }
00152
00153 private:
00154 C *container_;
00155 DifferenceType position_;
00156 };
00157
00159 template<class T>
00160 struct IteratorType
00161 {
00162 typedef typename T::Iterator type;
00163 };
00164
00165 template<class T>
00166 struct IteratorType<const T>
00167 {
00168 typedef typename T::ConstIterator type;
00169 };
00170
00171 #ifdef DUNE_EXPRESSIONTEMPLATES
00173 template<class V>
00174 class FlatIterator :
00175 public ForwardIteratorFacade<FlatIterator<V>,
00176 typename Dune::FieldType<V>::type,
00177 typename Dune::FieldType<V>::type&,
00178 int>
00179 {
00180 public:
00181 typedef typename IteratorType<V>::type BlockIterator;
00182 typedef std::ptrdiff_t DifferenceType;
00183
00184 typedef typename BlockType<V>::type block_type;
00185 typedef typename FieldType<V>::type field_type;
00186 typedef FlatIterator<block_type> SubBlockIterator;
00187 FlatIterator(const BlockIterator & i) :
00188 it(i), bit(i->begin()), bend(i->end()) {};
00189 void increment ()
00190 {
00191 ++bit;
00192 if (bit == bend)
00193 {
00194 ++it;
00195 bit = it->begin();
00196 bend = it->end();
00197 }
00198 }
00199 bool equals (const FlatIterator & fit) const
00200 {
00201 return fit.it == it && fit.bit == bit;
00202 }
00203 field_type& dereference() const
00204 {
00205 return *bit;
00206 }
00208 DifferenceType index () const
00209 {
00210 return bit.index();
00211 }
00212 private:
00213 BlockIterator it;
00214 SubBlockIterator bit;
00215 SubBlockIterator bend;
00216 };
00217
00220 template<class K, int N>
00221 class FlatIterator< FieldVector<K,N> > :
00222 public ForwardIteratorFacade<FlatIterator< FieldVector<K,N> >,
00223 K, K&, int>
00224 {
00225 public:
00226 typedef typename FieldVector<K,N>::Iterator BlockIterator;
00227 typedef std::ptrdiff_t DifferenceType;
00228
00229 typedef typename FieldVector<K,N>::field_type field_type;
00230 FlatIterator(const BlockIterator & i) : it(i) {};
00231 void increment ()
00232 {
00233 ++it;
00234 }
00235 bool equals (const FlatIterator & fit) const
00236 {
00237 return fit.it == it;
00238 }
00239 field_type& dereference() const
00240 {
00241 return *it;
00242 }
00244 DifferenceType index () const
00245 {
00246 return it.index();
00247 }
00248 private:
00249 BlockIterator it;
00250 };
00251
00254 template<class K, int N>
00255 class FlatIterator< const FieldVector<K,N> > :
00256 public ForwardIteratorFacade<FlatIterator< const FieldVector<K,N> >,
00257 const K, const K&, int>
00258 {
00259 public:
00260 typedef typename FieldVector<K,N>::ConstIterator BlockIterator;
00261 typedef std::ptrdiff_t DifferenceType;
00262
00263 typedef typename FieldVector<K,N>::field_type field_type;
00264 FlatIterator(const BlockIterator & i) : it(i) {};
00265 void increment ()
00266 {
00267 ++it;
00268 }
00269 bool equals (const FlatIterator & fit) const
00270 {
00271 return fit.it == it;
00272 }
00273 const field_type& dereference() const
00274 {
00275 return *it;
00276 }
00278 DifferenceType index () const
00279 {
00280 return it.index();
00281 }
00282 private:
00283 BlockIterator it;
00284 };
00285 #endif
00286
00287 #ifdef DUNE_EXPRESSIONTEMPLATES
00288
00297 template<class K, int SIZE>
00298 class FieldVector
00299 : public Dune::ExprTmpl::Vector< FieldVector<K,SIZE> >
00300 #else
00310 template<class K, int SIZE>
00311 class FieldVector
00312 #endif
00313 {
00314 public:
00315
00316 enum { dimension = SIZE };
00317
00318
00319
00320
00321
00323 typedef K field_type;
00324
00326 typedef K block_type;
00327
00329 typedef std::size_t size_type;
00330
00332 enum {
00334 blocklevel = 1
00335 };
00336
00338 enum {
00340 size = SIZE
00341 };
00342
00344 FieldVector() {}
00345
00346 #ifndef DUNE_EXPRESSIONTEMPLATES
00348 explicit FieldVector (const K& t)
00349 {
00350 for (size_type i=0; i<SIZE; i++) p[i] = t;
00351 }
00352
00353
00355 FieldVector& operator= (const K& k)
00356 {
00357
00358 for (size_type i=0; i<SIZE; i++)
00359 p[i] = k;
00360 return *this;
00361 }
00362
00363 #else
00365 explicit FieldVector (const K& t)
00366 {
00367 #ifdef DUNE_VVERBOSE
00368 Dune::dvverb << INDENT << "FieldVector Copy Constructor Scalar\n";
00369 #endif
00370 assignFrom(t);
00371 }
00373 FieldVector& operator= (const K& k)
00374 {
00375 #ifdef DUNE_VVERBOSE
00376 Dune::dvverb << INDENT << "FieldVector Assignment Operator Scalar\n";
00377 #endif
00378 return assignFrom(k);
00379 }
00380 template <class E>
00381 FieldVector (Dune::ExprTmpl::Expression<E> op) {
00382 #ifdef DUNE_VVERBOSE
00383 Dune::dvverb << INDENT << "FieldVector Copy Constructor Expression\n";
00384 #endif
00385 assignFrom(op);
00386 }
00387 template <class V>
00388 FieldVector (const Dune::ExprTmpl::Vector<V> & op) {
00389 #ifdef DUNE_VVERBOSE
00390 Dune::dvverb << INDENT << "FieldVector Copy Operator Vector\n";
00391 #endif
00392 assignFrom(op);
00393 }
00394 template <class E>
00395 FieldVector& operator = (Dune::ExprTmpl::Expression<E> op) {
00396 #ifdef DUNE_VVERBOSE
00397 Dune::dvverb << INDENT << "FieldVector Assignment Operator Expression\n";
00398 #endif
00399 return assignFrom(op);
00400 }
00401 template <class V>
00402 FieldVector& operator = (const Dune::ExprTmpl::Vector<V> & op) {
00403 #ifdef DUNE_VVERBOSE
00404 Dune::dvverb << INDENT << "FieldVector Assignment Operator Vector\n";
00405 #endif
00406 return assignFrom(op);
00407 }
00408 #endif
00409
00410
00411
00413 K& operator[] (size_type i)
00414 {
00415 #ifdef DUNE_ISTL_WITH_CHECKING
00416 if (i<0 || i>=SIZE) DUNE_THROW(MathError,"index out of range");
00417 #endif
00418 return p[i];
00419 }
00420
00422 const K& operator[] (size_type i) const
00423 {
00424 #ifdef DUNE_ISTL_WITH_CHECKING
00425 if (i<0 || i>=SIZE) DUNE_THROW(MathError,"index out of range");
00426 #endif
00427 return p[i];
00428 }
00429
00431 typedef FieldIterator<FieldVector<K,SIZE>,K> Iterator;
00433 typedef Iterator iterator;
00434
00436 Iterator begin ()
00437 {
00438 return Iterator(*this,0);
00439 }
00440
00442 Iterator end ()
00443 {
00444 return Iterator(*this,SIZE);
00445 }
00446
00448 Iterator rbegin ()
00449 {
00450 return Iterator(*this,SIZE-1);
00451 }
00452
00454 Iterator rend ()
00455 {
00456 return Iterator(*this,-1);
00457 }
00458
00460 Iterator find (size_type i)
00461 {
00462 if (i<SIZE)
00463 return Iterator(*this,i);
00464 else
00465 return Iterator(*this,SIZE);
00466 }
00467
00469 typedef FieldIterator<const FieldVector<K,SIZE>,const K> ConstIterator;
00471 typedef ConstIterator const_iterator;
00472
00474 ConstIterator begin () const
00475 {
00476 return ConstIterator(*this,0);
00477 }
00478
00480 ConstIterator end () const
00481 {
00482 return ConstIterator(*this,SIZE);
00483 }
00484
00486 ConstIterator rbegin () const
00487 {
00488 return ConstIterator(*this,SIZE-1);
00489 }
00490
00492 ConstIterator rend () const
00493 {
00494 return ConstIterator(*this,-1);
00495 }
00496
00498 ConstIterator find (size_type i) const
00499 {
00500 if (i<SIZE)
00501 return ConstIterator(*this,i);
00502 else
00503 return ConstIterator(*this,SIZE);
00504 }
00505
00506 #ifndef DUNE_EXPRESSIONTEMPLATES
00507
00508
00510 FieldVector& operator+= (const FieldVector& y)
00511 {
00512 for (size_type i=0; i<SIZE; i++)
00513 p[i] += y.p[i];
00514 return *this;
00515 }
00516
00518 FieldVector& operator-= (const FieldVector& y)
00519 {
00520 for (size_type i=0; i<SIZE; i++)
00521 p[i] -= y.p[i];
00522 return *this;
00523 }
00524
00526 FieldVector<K, size> operator+ (const FieldVector<K, size>& b) const
00527 {
00528 FieldVector<K, size> z = *this;
00529 return (z+=b);
00530 }
00531
00533 FieldVector<K, size> operator- (const FieldVector<K, size>& b) const
00534 {
00535 FieldVector<K, size> z = *this;
00536 return (z-=b);
00537 }
00538
00540 FieldVector& operator+= (const K& k)
00541 {
00542 for (size_type i=0; i<SIZE; i++)
00543 p[i] += k;
00544 return *this;
00545 }
00546
00548 FieldVector& operator-= (const K& k)
00549 {
00550 for (size_type i=0; i<SIZE; i++)
00551 p[i] -= k;
00552 return *this;
00553 }
00554
00556 FieldVector& operator*= (const K& k)
00557 {
00558 for (size_type i=0; i<SIZE; i++)
00559 p[i] *= k;
00560 return *this;
00561 }
00562
00564 FieldVector& operator/= (const K& k)
00565 {
00566 for (size_type i=0; i<SIZE; i++)
00567 p[i] /= k;
00568 return *this;
00569 }
00570
00571 #endif
00572
00574 bool operator== (const FieldVector& y) const
00575 {
00576 for (size_type i=0; i<SIZE; i++)
00577 if (p[i]!=y.p[i])
00578 return false;
00579
00580 return true;
00581 }
00582
00584 FieldVector& axpy (const K& a, const FieldVector& y)
00585 {
00586 #ifndef DUNE_EXPRESSIONTEMPLATES
00587 for (size_type i=0; i<SIZE; i++)
00588 p[i] += a*y.p[i];
00589 #else
00590 *this += a*y;
00591 #endif
00592 return *this;
00593 }
00594
00595 #ifndef DUNE_EXPRESSIONTEMPLATES
00596
00597
00599 K operator* (const FieldVector& y) const
00600 {
00601 K result = 0;
00602 for (int i=0; i<size; i++)
00603 result += p[i]*y[i];
00604 return result;
00605 }
00606
00607
00608
00609
00611 double one_norm() const {
00612 double result = 0;
00613 for (int i=0; i<size; i++)
00614 result += std::abs(p[i]);
00615 return result;
00616 }
00617
00618
00620 double one_norm_real () const
00621 {
00622 double result = 0;
00623 for (int i=0; i<size; i++)
00624 result += fvmeta_absreal(p[i]);
00625 return result;
00626 }
00627
00629 double two_norm () const
00630 {
00631 double result = 0;
00632 for (int i=0; i<size; i++)
00633 result += fvmeta_abs2(p[i]);
00634 return std::sqrt(result);
00635 }
00636
00638 double two_norm2 () const
00639 {
00640 double result = 0;
00641 for (int i=0; i<size; i++)
00642 result += fvmeta_abs2(p[i]);
00643 return result;
00644 }
00645
00647 double infinity_norm () const
00648 {
00649 double result = 0;
00650 for (int i=0; i<size; i++)
00651 result = std::max(result, std::abs(p[i]));
00652 return result;
00653 }
00654
00656 double infinity_norm_real () const
00657 {
00658 double result = 0;
00659 for (int i=0; i<size; i++)
00660 result = std::max(result, fvmeta_absreal(p[i]));
00661 return result;
00662 }
00663 #endif
00664
00665
00666
00668 size_type N () const
00669 {
00670 return SIZE;
00671 }
00672
00674 size_type dim () const
00675 {
00676 return SIZE;
00677 }
00678
00679 private:
00680
00681 K p[(SIZE > 0) ? SIZE : 1];
00682 };
00683
00685 template<typename K, int n>
00686 std::ostream& operator<< (std::ostream& s, const FieldVector<K,n>& v)
00687 {
00688 for (typename FieldVector<K,n>::size_type i=0; i<n; i++)
00689 s << ((i>0) ? " " : "") << v[i];
00690 return s;
00691 }
00692
00693
00694
00695 template<class K, int n, int m> class FieldMatrix;
00696
00697 #ifdef DUNE_EXPRESSIONTEMPLATES
00698
00700 template<class K>
00701 class FieldVector<K,1>
00702 : public Dune::ExprTmpl::Vector< FieldVector<K,1> >
00703 #else
00706 template<class K>
00707 class FieldVector<K,1>
00708 #endif
00709 {
00710 enum { n = 1 };
00711 public:
00712 friend class FieldMatrix<K,1,1>;
00713
00714
00715
00717 typedef K field_type;
00718
00720 typedef K block_type;
00721
00723 typedef std::size_t size_type;
00724
00726 enum {blocklevel = 1};
00727
00729 enum {size = 1};
00730
00732 enum {dimension = 1};
00733
00734
00735
00737 FieldVector ()
00738 { }
00739
00741 FieldVector (const K& k)
00742 {
00743 p = k;
00744 }
00745
00747 FieldVector& operator= (const K& k)
00748 {
00749 p = k;
00750 return *this;
00751 }
00752
00753 #ifdef DUNE_EXPRESSIONTEMPLATES
00754 template <class E>
00755 FieldVector (Dune::ExprTmpl::Expression<E> op) {
00756 #ifdef DUNE_VVERBOSE
00757 Dune::dvverb << INDENT << "FieldVector<1> Copy Constructor Expression\n";
00758 #endif
00759 assignFrom(op);
00760 }
00761 template <class V>
00762 FieldVector (const Dune::ExprTmpl::Vector<V> & op) {
00763 #ifdef DUNE_VVERBOSE
00764 Dune::dvverb << INDENT << "FieldVector<1> Copy Operator Vector\n";
00765 #endif
00766 assignFrom(op);
00767 }
00768 template <class E>
00769 FieldVector& operator = (Dune::ExprTmpl::Expression<E> op) {
00770 #ifdef DUNE_VVERBOSE
00771 Dune::dvverb << INDENT << "FieldVector<1> Assignment Operator Expression\n";
00772 #endif
00773 return assignFrom(op);
00774 }
00775 template <class V>
00776 FieldVector& operator = (const Dune::ExprTmpl::Vector<V> & op) {
00777 #ifdef DUNE_VVERBOSE
00778 Dune::dvverb << INDENT << "FieldVector<1> Assignment Operator Vector\n";
00779 #endif
00780 return assignFrom(op);
00781 }
00782 #endif
00783
00784
00785
00787 K& operator[] (size_type i)
00788 {
00789 #ifdef DUNE_ISTL_WITH_CHECKING
00790 if (i != 0) DUNE_THROW(MathError,"index out of range");
00791 #endif
00792 return p;
00793 }
00794
00796 const K& operator[] (size_type i) const
00797 {
00798 #ifdef DUNE_ISTL_WITH_CHECKING
00799 if (i != 0) DUNE_THROW(MathError,"index out of range");
00800 #endif
00801 return p;
00802 }
00803
00805 typedef FieldIterator<FieldVector<K,n>,K> Iterator;
00807 typedef Iterator iterator;
00808
00810 Iterator begin ()
00811 {
00812 return Iterator(*this,0);
00813 }
00814
00816 Iterator end ()
00817 {
00818 return Iterator(*this,n);
00819 }
00820
00822 Iterator rbegin ()
00823 {
00824 return Iterator(*this,n-1);
00825 }
00826
00828 Iterator rend ()
00829 {
00830 return Iterator(*this,-1);
00831 }
00832
00834 Iterator find (size_type i)
00835 {
00836 if (i<n)
00837 return Iterator(*this,i);
00838 else
00839 return Iterator(*this,n);
00840 }
00841
00843 typedef FieldIterator<const FieldVector<K,n>,const K> ConstIterator;
00845 typedef ConstIterator const_iterator;
00846
00848 ConstIterator begin () const
00849 {
00850 return ConstIterator(*this,0);
00851 }
00852
00854 ConstIterator end () const
00855 {
00856 return ConstIterator(*this,n);
00857 }
00858
00860 ConstIterator rbegin () const
00861 {
00862 return ConstIterator(*this,n-1);
00863 }
00864
00866 ConstIterator rend () const
00867 {
00868 return ConstIterator(*this,-1);
00869 }
00870
00872 ConstIterator find (size_type i) const
00873 {
00874 if (i<n)
00875 return ConstIterator(*this,i);
00876 else
00877 return ConstIterator(*this,n);
00878 }
00879
00880
00882 FieldVector& operator+= (const FieldVector& y)
00883 {
00884 p += y.p;
00885 return *this;
00886 }
00887
00889 FieldVector& operator-= (const FieldVector& y)
00890 {
00891 p -= y.p;
00892 return *this;
00893 }
00894
00896 FieldVector& operator+= (const K& k)
00897 {
00898 p += k;
00899 return *this;
00900 }
00901
00903 FieldVector& operator-= (const K& k)
00904 {
00905 p -= k;
00906 return *this;
00907 }
00908
00910 FieldVector& operator*= (const K& k)
00911 {
00912 p *= k;
00913 return *this;
00914 }
00915
00917 FieldVector& operator/= (const K& k)
00918 {
00919 p /= k;
00920 return *this;
00921 }
00922
00924 FieldVector& axpy (const K& a, const FieldVector& y)
00925 {
00926 p += a*y.p;
00927 return *this;
00928 }
00929
00930
00931
00933 double one_norm () const
00934 {
00935 return std::abs(p);
00936 }
00937
00939 double one_norm_real () const
00940 {
00941 return fvmeta_abs_real(p);
00942 }
00943
00945 double two_norm () const
00946 {
00947 return sqrt(fvmeta_abs2(p));
00948 }
00949
00951 double two_norm2 () const
00952 {
00953 return fvmeta_abs2(p);
00954 }
00955
00957 double infinity_norm () const
00958 {
00959 return std::abs(p);
00960 }
00961
00963 double infinity_norm_real () const
00964 {
00965 return fvmeta_abs_real(p);
00966 }
00967
00968
00969
00970
00972 size_type N () const
00973 {
00974 return 1;
00975 }
00976
00978 size_type dim () const
00979 {
00980 return 1;
00981 }
00982
00983
00984
00986 operator K () {return p;}
00987
00989 operator K () const {return p;}
00990
00991 private:
00992
00993 K p;
00994 };
00995
00996 #ifndef DUNE_EXPRESSIONTEMPLATES
00998 template<class K>
00999 inline FieldVector<K,1> operator+ (const FieldVector<K,1>& a, const FieldVector<K,1>& b)
01000 {
01001 FieldVector<K,1> z = a;
01002 return (z+=b);
01003 }
01004
01006 template<class K>
01007 inline FieldVector<K,1> operator- (const FieldVector<K,1>& a, const FieldVector<K,1>& b)
01008 {
01009 FieldVector<K,1> z = a;
01010 return (z-=b);
01011 }
01012
01014 template<class K>
01015 inline FieldVector<K,1> operator+ (const FieldVector<K,1>& a, const K b)
01016 {
01017 FieldVector<K,1> z = a;
01018 return (z[0]+=b);
01019 }
01020
01022 template<class K>
01023 inline FieldVector<K,1> operator- (const FieldVector<K,1>& a, const K b)
01024 {
01025 FieldVector<K,1> z = a;
01026 return (z[0]-=b);
01027 }
01028
01030 template<class K>
01031 inline FieldVector<K,1> operator+ (const K a, const FieldVector<K,1>& b)
01032 {
01033 FieldVector<K,1> z = a;
01034 return (z[0]+=b);
01035 }
01036
01038 template<class K>
01039 inline FieldVector<K,1> operator- (const K a, const FieldVector<K,1>& b)
01040 {
01041 FieldVector<K,1> z = a;
01042 return (z[0]-=b);
01043 }
01044 #endif
01045
01046
01049 }
01050
01051 #endif