00001
00002 #ifndef DUNE_FVECTOR_HH
00003 #define DUNE_FVECTOR_HH
00004
00005 #include<cmath>
00006 #include<cstdlib>
00007 #include<cstddef>
00008 #include<complex>
00009
00010 #include "exceptions.hh"
00011 #include "genericiterator.hh"
00012
00013 #ifdef DUNE_EXPRESSIONTEMPLATES
00014 #include "exprtmpl.hh"
00015 #endif
00016
00017 namespace Dune {
00018
00019 #ifndef DUNE_EXPRESSIONTEMPLATES
00020
00031
00032 template<class K, int n> class FieldVector;
00033
00034 #endif
00035
00036 #ifndef DUNE_EXPRESSIONTEMPLATES
00037
00038 template<class K>
00039 inline double fvmeta_absreal (const K& k)
00040 {
00041 return std::abs(k);
00042 }
00043
00044 template<class K>
00045 inline double fvmeta_absreal (const std::complex<K>& c)
00046 {
00047 return fvmeta_abs(c.real()) + fvmeta_abs(c.imag());
00048 }
00049
00050 template<class K>
00051 inline double fvmeta_abs2 (const K& k)
00052 {
00053 return k*k;
00054 }
00055
00056 template<class K>
00057 inline double fvmeta_abs2 (const std::complex<K>& c)
00058 {
00059 return c.real()*c.real() + c.imag()*c.imag();
00060 }
00061
00062 #endif
00063
00065 template<class C, class T>
00066 class FieldIterator :
00067 public Dune::RandomAccessIteratorFacade<FieldIterator<C,T>,T, T&, int>
00068 {
00069 friend class FieldIterator<typename remove_const<C>::type, typename remove_const<T>::type >;
00070 friend class FieldIterator<const typename remove_const<C>::type, const typename remove_const<T>::type >;
00071
00072 public:
00073
00077 typedef std::ptrdiff_t DifferenceType;
00078
00079
00080 FieldIterator()
00081 : container_(0), position_(0)
00082 {}
00083
00084 FieldIterator(C& cont, DifferenceType pos)
00085 : container_(&cont), position_(pos)
00086 {}
00087
00088 FieldIterator(const FieldIterator<typename remove_const<C>::type, typename remove_const<T>::type >& other)
00089 : container_(other.container_), position_(other.position_)
00090 {}
00091
00092 #if 0
00093 FieldIterator(const FieldIterator<const typename remove_const<C>::type, const typename remove_const<T>::type >& other)
00094 : container_(other.container_), position_(other.position_)
00095 {}
00096 #endif
00097 #if 0
00098 FieldIterator(const FieldIterator<C,T>& other)
00099 : container_(other.container_), position_(other.position_)
00100 {}
00101 #endif
00102
00103 bool equals(const FieldIterator<typename remove_const<C>::type,typename remove_const<T>::type>& other) const
00104 {
00105 return position_ == other.position_ && container_ == other.container_;
00106 }
00107
00108
00109 bool equals(const FieldIterator<const typename remove_const<C>::type,const typename remove_const<T>::type>& other) const
00110 {
00111 return position_ == other.position_ && container_ == other.container_;
00112 }
00113
00114 T& dereference() const{
00115 return container_->operator[](position_);
00116 }
00117
00118 void increment(){
00119 ++position_;
00120 }
00121
00122
00123 void decrement(){
00124 --position_;
00125 }
00126
00127
00128 T& elementAt(DifferenceType i)const{
00129 return container_->operator[](position_+i);
00130 }
00131
00132 void advance(DifferenceType n){
00133 position_=position_+n;
00134 }
00135
00136 std::ptrdiff_t distanceTo(FieldIterator<const typename remove_const<C>::type,const typename remove_const<T>::type> other)const
00137 {
00138 assert(other.container_==container_);
00139 return other.position_ - position_;
00140 }
00141
00142 std::ptrdiff_t distanceTo(FieldIterator<typename remove_const<C>::type, typename remove_const<T>::type> other)const
00143 {
00144 assert(other.container_==container_);
00145 return other.position_ - position_;
00146 }
00147
00149 DifferenceType index () const
00150 {
00151 return this->position_;
00152 }
00153
00154 private:
00155 C *container_;
00156 DifferenceType position_;
00157 };
00158
00160 template<class T>
00161 struct IteratorType
00162 {
00163 typedef typename T::Iterator type;
00164 };
00165
00166 template<class T>
00167 struct IteratorType<const T>
00168 {
00169 typedef typename T::ConstIterator type;
00170 };
00171
00172 #ifdef DUNE_EXPRESSIONTEMPLATES
00174 template<class V>
00175 class FlatIterator :
00176 public ForwardIteratorFacade<FlatIterator<V>,
00177 typename Dune::FieldType<V>::type,
00178 typename Dune::FieldType<V>::type&,
00179 int>
00180 {
00181 public:
00182 typedef typename IteratorType<V>::type BlockIterator;
00183 typedef std::ptrdiff_t DifferenceType;
00184
00185 typedef typename BlockType<V>::type block_type;
00186 typedef typename FieldType<V>::type field_type;
00187 typedef FlatIterator<block_type> SubBlockIterator;
00188 FlatIterator(const BlockIterator & i) :
00189 it(i), bit(i->begin()), bend(i->end()) {};
00190 void increment ()
00191 {
00192 ++bit;
00193 if (bit == bend)
00194 {
00195 ++it;
00196 bit = it->begin();
00197 bend = it->end();
00198 }
00199 }
00200 bool equals (const FlatIterator & fit) const
00201 {
00202 return fit.it == it && fit.bit == bit;
00203 }
00204 field_type& dereference() const
00205 {
00206 return *bit;
00207 }
00209 DifferenceType index () const
00210 {
00211 return bit.index();
00212 }
00213 private:
00214 BlockIterator it;
00215 SubBlockIterator bit;
00216 SubBlockIterator bend;
00217 };
00218
00221 template<class K, int N>
00222 class FlatIterator< FieldVector<K,N> > :
00223 public ForwardIteratorFacade<FlatIterator< FieldVector<K,N> >,
00224 K, K&, int>
00225 {
00226 public:
00227 typedef typename FieldVector<K,N>::Iterator BlockIterator;
00228 typedef std::ptrdiff_t DifferenceType;
00229
00230 typedef typename FieldVector<K,N>::field_type field_type;
00231 FlatIterator(const BlockIterator & i) : it(i) {};
00232 void increment ()
00233 {
00234 ++it;
00235 }
00236 bool equals (const FlatIterator & fit) const
00237 {
00238 return fit.it == it;
00239 }
00240 field_type& dereference() const
00241 {
00242 return *it;
00243 }
00245 DifferenceType index () const
00246 {
00247 return it.index();
00248 }
00249 private:
00250 BlockIterator it;
00251 };
00252
00255 template<class K, int N>
00256 class FlatIterator< const FieldVector<K,N> > :
00257 public ForwardIteratorFacade<FlatIterator< const FieldVector<K,N> >,
00258 const K, const K&, int>
00259 {
00260 public:
00261 typedef typename FieldVector<K,N>::ConstIterator BlockIterator;
00262 typedef std::ptrdiff_t DifferenceType;
00263
00264 typedef typename FieldVector<K,N>::field_type field_type;
00265 FlatIterator(const BlockIterator & i) : it(i) {};
00266 void increment ()
00267 {
00268 ++it;
00269 }
00270 bool equals (const FlatIterator & fit) const
00271 {
00272 return fit.it == it;
00273 }
00274 const field_type& dereference() const
00275 {
00276 return *it;
00277 }
00279 DifferenceType index () const
00280 {
00281 return it.index();
00282 }
00283 private:
00284 BlockIterator it;
00285 };
00286 #endif
00287
00288 #ifdef DUNE_EXPRESSIONTEMPLATES
00289
00298 template<class K, int SIZE>
00299 class FieldVector
00300 : public Dune::ExprTmpl::Vector< FieldVector<K,SIZE> >
00301 #else
00311 template<class K, int SIZE>
00312 class FieldVector
00313 #endif
00314 {
00315 public:
00316
00317 enum { dimension = SIZE };
00318
00319
00320
00321
00322
00324 typedef K field_type;
00325
00327 typedef K block_type;
00328
00330 typedef std::size_t size_type;
00331
00333 enum {
00335 blocklevel = 1
00336 };
00337
00339 enum {
00341 size = SIZE
00342 };
00343
00345 FieldVector() {}
00346
00347 #ifndef DUNE_EXPRESSIONTEMPLATES
00349 explicit FieldVector (const K& t)
00350 {
00351 for (size_type i=0; i<SIZE; i++) p[i] = t;
00352 }
00353
00354
00356 FieldVector& operator= (const K& k)
00357 {
00358
00359 for (size_type i=0; i<SIZE; i++)
00360 p[i] = k;
00361 return *this;
00362 }
00363
00364 #else
00366 explicit FieldVector (const K& t)
00367 {
00368 #ifdef DUNE_VVERBOSE
00369 Dune::dvverb << INDENT << "FieldVector Copy Constructor Scalar\n";
00370 #endif
00371 assignFrom(t);
00372 }
00374 FieldVector& operator= (const K& k)
00375 {
00376 #ifdef DUNE_VVERBOSE
00377 Dune::dvverb << INDENT << "FieldVector Assignment Operator Scalar\n";
00378 #endif
00379 return assignFrom(k);
00380 }
00381 template <class E>
00382 FieldVector (Dune::ExprTmpl::Expression<E> op) {
00383 #ifdef DUNE_VVERBOSE
00384 Dune::dvverb << INDENT << "FieldVector Copy Constructor Expression\n";
00385 #endif
00386 assignFrom(op);
00387 }
00388 template <class V>
00389 FieldVector (const Dune::ExprTmpl::Vector<V> & op) {
00390 #ifdef DUNE_VVERBOSE
00391 Dune::dvverb << INDENT << "FieldVector Copy Operator Vector\n";
00392 #endif
00393 assignFrom(op);
00394 }
00395 template <class E>
00396 FieldVector& operator = (Dune::ExprTmpl::Expression<E> op) {
00397 #ifdef DUNE_VVERBOSE
00398 Dune::dvverb << INDENT << "FieldVector Assignment Operator Expression\n";
00399 #endif
00400 return assignFrom(op);
00401 }
00402 template <class V>
00403 FieldVector& operator = (const Dune::ExprTmpl::Vector<V> & op) {
00404 #ifdef DUNE_VVERBOSE
00405 Dune::dvverb << INDENT << "FieldVector Assignment Operator Vector\n";
00406 #endif
00407 return assignFrom(op);
00408 }
00409 #endif
00410
00411
00412
00414 K& operator[] (size_type i)
00415 {
00416 #ifdef DUNE_ISTL_WITH_CHECKING
00417 if (i<0 || i>=SIZE) DUNE_THROW(MathError,"index out of range");
00418 #endif
00419 return p[i];
00420 }
00421
00423 const K& operator[] (size_type i) const
00424 {
00425 #ifdef DUNE_ISTL_WITH_CHECKING
00426 if (i<0 || i>=SIZE) DUNE_THROW(MathError,"index out of range");
00427 #endif
00428 return p[i];
00429 }
00430
00432 typedef FieldIterator<FieldVector<K,SIZE>,K> Iterator;
00434 typedef Iterator iterator;
00435
00437 Iterator begin ()
00438 {
00439 return Iterator(*this,0);
00440 }
00441
00443 Iterator end ()
00444 {
00445 return Iterator(*this,SIZE);
00446 }
00447
00449 Iterator rbegin ()
00450 {
00451 return Iterator(*this,SIZE-1);
00452 }
00453
00455 Iterator rend ()
00456 {
00457 return Iterator(*this,-1);
00458 }
00459
00461 Iterator find (size_type i)
00462 {
00463 if (i<SIZE)
00464 return Iterator(*this,i);
00465 else
00466 return Iterator(*this,SIZE);
00467 }
00468
00470 typedef FieldIterator<const FieldVector<K,SIZE>,const K> ConstIterator;
00472 typedef ConstIterator const_iterator;
00473
00475 ConstIterator begin () const
00476 {
00477 return ConstIterator(*this,0);
00478 }
00479
00481 ConstIterator end () const
00482 {
00483 return ConstIterator(*this,SIZE);
00484 }
00485
00487 ConstIterator rbegin () const
00488 {
00489 return ConstIterator(*this,SIZE-1);
00490 }
00491
00493 ConstIterator rend () const
00494 {
00495 return ConstIterator(*this,-1);
00496 }
00497
00499 ConstIterator find (size_type i) const
00500 {
00501 if (i<SIZE)
00502 return ConstIterator(*this,i);
00503 else
00504 return ConstIterator(*this,SIZE);
00505 }
00506
00507 #ifndef DUNE_EXPRESSIONTEMPLATES
00508
00509
00511 FieldVector& operator+= (const FieldVector& y)
00512 {
00513 for (size_type i=0; i<SIZE; i++)
00514 p[i] += y.p[i];
00515 return *this;
00516 }
00517
00519 FieldVector& operator-= (const FieldVector& y)
00520 {
00521 for (size_type i=0; i<SIZE; i++)
00522 p[i] -= y.p[i];
00523 return *this;
00524 }
00525
00527 FieldVector<K, size> operator+ (const FieldVector<K, size>& b) const
00528 {
00529 FieldVector<K, size> z = *this;
00530 return (z+=b);
00531 }
00532
00534 FieldVector<K, size> operator- (const FieldVector<K, size>& b) const
00535 {
00536 FieldVector<K, size> z = *this;
00537 return (z-=b);
00538 }
00539
00541 FieldVector& operator+= (const K& k)
00542 {
00543 for (size_type i=0; i<SIZE; i++)
00544 p[i] += k;
00545 return *this;
00546 }
00547
00549 FieldVector& operator-= (const K& k)
00550 {
00551 for (size_type i=0; i<SIZE; i++)
00552 p[i] -= k;
00553 return *this;
00554 }
00555
00557 FieldVector& operator*= (const K& k)
00558 {
00559 for (size_type i=0; i<SIZE; i++)
00560 p[i] *= k;
00561 return *this;
00562 }
00563
00565 FieldVector& operator/= (const K& k)
00566 {
00567 for (size_type i=0; i<SIZE; i++)
00568 p[i] /= k;
00569 return *this;
00570 }
00571
00572 #endif
00573
00575 bool operator== (const FieldVector& y) const
00576 {
00577 for (size_type i=0; i<SIZE; i++)
00578 if (p[i]!=y.p[i])
00579 return false;
00580
00581 return true;
00582 }
00583
00585 FieldVector& axpy (const K& a, const FieldVector& y)
00586 {
00587 #ifndef DUNE_EXPRESSIONTEMPLATES
00588 for (size_type i=0; i<SIZE; i++)
00589 p[i] += a*y.p[i];
00590 #else
00591 *this += a*y;
00592 #endif
00593 return *this;
00594 }
00595
00596 #ifndef DUNE_EXPRESSIONTEMPLATES
00597
00598
00600 K operator* (const FieldVector& y) const
00601 {
00602 K result = 0;
00603 for (int i=0; i<size; i++)
00604 result += p[i]*y[i];
00605 return result;
00606 }
00607
00608
00609
00610
00612 double one_norm() const {
00613 double result = 0;
00614 for (int i=0; i<size; i++)
00615 result += std::abs(p[i]);
00616 return result;
00617 }
00618
00619
00621 double one_norm_real () const
00622 {
00623 double result = 0;
00624 for (int i=0; i<size; i++)
00625 result += fvmeta_absreal(p[i]);
00626 return result;
00627 }
00628
00630 double two_norm () const
00631 {
00632 double result = 0;
00633 for (int i=0; i<size; i++)
00634 result += fvmeta_abs2(p[i]);
00635 return std::sqrt(result);
00636 }
00637
00639 double two_norm2 () const
00640 {
00641 double result = 0;
00642 for (int i=0; i<size; i++)
00643 result += fvmeta_abs2(p[i]);
00644 return result;
00645 }
00646
00648 double infinity_norm () const
00649 {
00650 double result = 0;
00651 for (int i=0; i<size; i++)
00652 result = std::max(result, std::abs(p[i]));
00653 return result;
00654 }
00655
00657 double infinity_norm_real () const
00658 {
00659 double result = 0;
00660 for (int i=0; i<size; i++)
00661 result = std::max(result, fvmeta_absreal(p[i]));
00662 return result;
00663 }
00664 #endif
00665
00666
00667
00669 size_type N () const
00670 {
00671 return SIZE;
00672 }
00673
00675 size_type dim () const
00676 {
00677 return SIZE;
00678 }
00679
00680 private:
00681
00682 K p[(SIZE > 0) ? SIZE : 1];
00683 };
00684
00686 template<typename K, int n>
00687 std::ostream& operator<< (std::ostream& s, const FieldVector<K,n>& v)
00688 {
00689 for (typename FieldVector<K,n>::size_type i=0; i<n; i++)
00690 s << ((i>0) ? " " : "") << v[i];
00691 return s;
00692 }
00693
00694
00695
00696 template<class K, int n, int m> class FieldMatrix;
00697
00698 #ifdef DUNE_EXPRESSIONTEMPLATES
00699
00701 template<class K>
00702 class FieldVector<K,1>
00703 : public Dune::ExprTmpl::Vector< FieldVector<K,1> >
00704 #else
00707 template<class K>
00708 class FieldVector<K,1>
00709 #endif
00710 {
00711 enum { n = 1 };
00712 public:
00713 friend class FieldMatrix<K,1,1>;
00714
00715
00716
00718 typedef K field_type;
00719
00721 typedef K block_type;
00722
00724 typedef std::size_t size_type;
00725
00727 enum {blocklevel = 1};
00728
00730 enum {size = 1};
00731
00733 enum {dimension = 1};
00734
00735
00736
00738 FieldVector ()
00739 { }
00740
00742 FieldVector (const K& k)
00743 {
00744 p = k;
00745 }
00746
00748 FieldVector& operator= (const K& k)
00749 {
00750 p = k;
00751 return *this;
00752 }
00753
00754 #ifdef DUNE_EXPRESSIONTEMPLATES
00755 template <class E>
00756 FieldVector (Dune::ExprTmpl::Expression<E> op) {
00757 #ifdef DUNE_VVERBOSE
00758 Dune::dvverb << INDENT << "FieldVector<1> Copy Constructor Expression\n";
00759 #endif
00760 assignFrom(op);
00761 }
00762 template <class V>
00763 FieldVector (const Dune::ExprTmpl::Vector<V> & op) {
00764 #ifdef DUNE_VVERBOSE
00765 Dune::dvverb << INDENT << "FieldVector<1> Copy Operator Vector\n";
00766 #endif
00767 assignFrom(op);
00768 }
00769 template <class E>
00770 FieldVector& operator = (Dune::ExprTmpl::Expression<E> op) {
00771 #ifdef DUNE_VVERBOSE
00772 Dune::dvverb << INDENT << "FieldVector<1> Assignment Operator Expression\n";
00773 #endif
00774 return assignFrom(op);
00775 }
00776 template <class V>
00777 FieldVector& operator = (const Dune::ExprTmpl::Vector<V> & op) {
00778 #ifdef DUNE_VVERBOSE
00779 Dune::dvverb << INDENT << "FieldVector<1> Assignment Operator Vector\n";
00780 #endif
00781 return assignFrom(op);
00782 }
00783 #endif
00784
00785
00786
00788 K& operator[] (size_type i)
00789 {
00790 #ifdef DUNE_ISTL_WITH_CHECKING
00791 if (i != 0) DUNE_THROW(MathError,"index out of range");
00792 #endif
00793 return p;
00794 }
00795
00797 const K& operator[] (size_type i) const
00798 {
00799 #ifdef DUNE_ISTL_WITH_CHECKING
00800 if (i != 0) DUNE_THROW(MathError,"index out of range");
00801 #endif
00802 return p;
00803 }
00804
00806 typedef FieldIterator<FieldVector<K,n>,K> Iterator;
00808 typedef Iterator iterator;
00809
00811 Iterator begin ()
00812 {
00813 return Iterator(*this,0);
00814 }
00815
00817 Iterator end ()
00818 {
00819 return Iterator(*this,n);
00820 }
00821
00823 Iterator rbegin ()
00824 {
00825 return Iterator(*this,n-1);
00826 }
00827
00829 Iterator rend ()
00830 {
00831 return Iterator(*this,-1);
00832 }
00833
00835 Iterator find (size_type i)
00836 {
00837 if (i<n)
00838 return Iterator(*this,i);
00839 else
00840 return Iterator(*this,n);
00841 }
00842
00844 typedef FieldIterator<const FieldVector<K,n>,const K> ConstIterator;
00846 typedef ConstIterator const_iterator;
00847
00849 ConstIterator begin () const
00850 {
00851 return ConstIterator(*this,0);
00852 }
00853
00855 ConstIterator end () const
00856 {
00857 return ConstIterator(*this,n);
00858 }
00859
00861 ConstIterator rbegin () const
00862 {
00863 return ConstIterator(*this,n-1);
00864 }
00865
00867 ConstIterator rend () const
00868 {
00869 return ConstIterator(*this,-1);
00870 }
00871
00873 ConstIterator find (size_type i) const
00874 {
00875 if (i<n)
00876 return ConstIterator(*this,i);
00877 else
00878 return ConstIterator(*this,n);
00879 }
00880
00881
00883 FieldVector& operator+= (const FieldVector& y)
00884 {
00885 p += y.p;
00886 return *this;
00887 }
00888
00890 FieldVector& operator-= (const FieldVector& y)
00891 {
00892 p -= y.p;
00893 return *this;
00894 }
00895
00897 FieldVector& operator+= (const K& k)
00898 {
00899 p += k;
00900 return *this;
00901 }
00902
00904 FieldVector& operator-= (const K& k)
00905 {
00906 p -= k;
00907 return *this;
00908 }
00909
00911 FieldVector& operator*= (const K& k)
00912 {
00913 p *= k;
00914 return *this;
00915 }
00916
00918 FieldVector& operator/= (const K& k)
00919 {
00920 p /= k;
00921 return *this;
00922 }
00923
00925 FieldVector& axpy (const K& a, const FieldVector& y)
00926 {
00927 p += a*y.p;
00928 return *this;
00929 }
00930
00931
00932
00934 double one_norm () const
00935 {
00936 return std::abs(p);
00937 }
00938
00940 double one_norm_real () const
00941 {
00942 return fvmeta_abs_real(p);
00943 }
00944
00946 double two_norm () const
00947 {
00948 return sqrt(fvmeta_abs2(p));
00949 }
00950
00952 double two_norm2 () const
00953 {
00954 return fvmeta_abs2(p);
00955 }
00956
00958 double infinity_norm () const
00959 {
00960 return std::abs(p);
00961 }
00962
00964 double infinity_norm_real () const
00965 {
00966 return fvmeta_abs_real(p);
00967 }
00968
00969
00970
00971
00973 size_type N () const
00974 {
00975 return 1;
00976 }
00977
00979 size_type dim () const
00980 {
00981 return 1;
00982 }
00983
00984
00985
00987 operator K () {return p;}
00988
00990 operator K () const {return p;}
00991
00992 private:
00993
00994 K p;
00995 };
00996
00997 #ifndef DUNE_EXPRESSIONTEMPLATES
00999 template<class K>
01000 inline FieldVector<K,1> operator+ (const FieldVector<K,1>& a, const FieldVector<K,1>& b)
01001 {
01002 FieldVector<K,1> z = a;
01003 return (z+=b);
01004 }
01005
01007 template<class K>
01008 inline FieldVector<K,1> operator- (const FieldVector<K,1>& a, const FieldVector<K,1>& b)
01009 {
01010 FieldVector<K,1> z = a;
01011 return (z-=b);
01012 }
01013
01015 template<class K>
01016 inline FieldVector<K,1> operator+ (const FieldVector<K,1>& a, const K b)
01017 {
01018 FieldVector<K,1> z = a;
01019 return (z[0]+=b);
01020 }
01021
01023 template<class K>
01024 inline FieldVector<K,1> operator- (const FieldVector<K,1>& a, const K b)
01025 {
01026 FieldVector<K,1> z = a;
01027 return (z[0]-=b);
01028 }
01029
01031 template<class K>
01032 inline FieldVector<K,1> operator+ (const K a, const FieldVector<K,1>& b)
01033 {
01034 FieldVector<K,1> z = a;
01035 return (z[0]+=b);
01036 }
01037
01039 template<class K>
01040 inline FieldVector<K,1> operator- (const K a, const FieldVector<K,1>& b)
01041 {
01042 FieldVector<K,1> z = a;
01043 return (z[0]-=b);
01044 }
01045 #endif
01046
01047
01050 }
01051
01052 #endif