dune-common
2.2.0
|
00001 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- 00002 // vi: set et ts=4 sw=2 sts=2: 00003 // $Id: fvector.hh 6785 2012-05-31 22:07:47Z sander $ 00004 #ifndef DUNE_FVECTOR_HH 00005 #define DUNE_FVECTOR_HH 00006 00007 #include<cmath> 00008 #include<cstddef> 00009 #include<cstdlib> 00010 #include<complex> 00011 #include<cstring> 00012 00013 #include "typetraits.hh" 00014 #include "exceptions.hh" 00015 #include "array.hh" 00016 #include "densevector.hh" 00017 #include "static_assert.hh" 00018 00019 #if ! DUNE_COMMON_FIELDVECTOR_SIZE_IS_METHOD 00020 #warning The FieldVector class exports its size by the enum member 'size'. \ 00021 This behavior is deprecated. In the future, 'size' will be a method, \ 00022 which puts it in compliance with the stl conventions. To enable the new behavior \ 00023 (and get rid of this warning), build your Dune with --enable-fieldvector-size-is-method. \ 00024 If you do need the vector size as an enum, use 'dimension'. 00025 #endif 00026 00027 00028 namespace Dune { 00029 00039 template< class K, int SIZE > class FieldVector; 00040 template< class K, int SIZE > 00041 struct DenseMatVecTraits< FieldVector<K,SIZE> > 00042 { 00043 typedef FieldVector<K,SIZE> derived_type; 00044 typedef Dune::array<K,SIZE> container_type; 00045 typedef K value_type; 00046 typedef typename container_type::size_type size_type; 00047 }; 00048 00049 template< class K, int SIZE > 00050 struct FieldTraits< FieldVector<K,SIZE> > 00051 { 00052 typedef typename FieldTraits<K>::field_type field_type; 00053 typedef typename FieldTraits<K>::real_type real_type; 00054 }; 00055 00064 template<typename C, int SIZE> 00065 struct IsFieldVectorSizeCorrect 00066 { 00067 enum{ 00072 value = true}; 00073 }; 00074 00075 template<typename T, int SIZE> 00076 struct IsFieldVectorSizeCorrect<FieldVector<T,SIZE>,SIZE> 00077 { 00078 enum{value = true}; 00079 }; 00080 00081 template<typename T, int SIZE, int SIZE1> 00082 struct IsFieldVectorSizeCorrect<FieldVector<T,SIZE1>,SIZE> 00083 { 00084 enum{value = false}; 00085 }; 00086 00087 00093 template< class K, int SIZE > 00094 class FieldVector : 00095 public DenseVector< FieldVector<K,SIZE> > 00096 { 00097 Dune::array<K,SIZE> _data; 00098 typedef DenseVector< FieldVector<K,SIZE> > Base; 00099 public: 00101 enum { 00103 dimension = SIZE 00104 #if ! DUNE_COMMON_FIELDVECTOR_SIZE_IS_METHOD 00105 , 00107 size = SIZE 00108 #endif 00109 }; 00110 00111 typedef typename Base::size_type size_type; 00112 typedef typename Base::value_type value_type; 00113 00115 FieldVector() {} 00116 00118 explicit FieldVector (const K& t) 00119 { 00120 fill(t); 00121 } 00122 00124 FieldVector (const FieldVector & x) : _data(x._data) 00125 {} 00126 00138 template<class C> 00139 FieldVector (const DenseVector<C> & x, typename Dune::enable_if<IsFieldVectorSizeCorrect<C,SIZE>::value>::type* dummy=0 ) 00140 { 00141 // do a run-time size check, for the case that x is not a FieldVector 00142 assert(x.size() == SIZE); 00143 for (size_type i = 0; i<SIZE; i++) 00144 _data[i] = x[i]; 00145 } 00146 00148 template<class K1, int SIZE1> 00149 explicit FieldVector (const FieldVector<K1,SIZE1> & x) 00150 { 00151 dune_static_assert(SIZE1 == SIZE, "FieldVector in constructor has wrong size"); 00152 for (size_type i = 0; i<SIZE; i++) 00153 _data[i] = x[i]; 00154 } 00155 using Base::operator=; 00156 00157 // make this thing a vector 00158 size_type vec_size() const { return SIZE; } 00159 K & vec_access(size_type i) { return _data[i]; } 00160 const K & vec_access(size_type i) const { return _data[i]; } 00161 private: 00162 void fill(const K& t) 00163 { 00164 for (int i=0; i<SIZE; i++) _data[i]=t; 00165 } 00166 }; 00167 00179 template<class K, int SIZE> 00180 inline std::istream &operator>> ( std::istream &in, 00181 FieldVector<K, SIZE> &v ) 00182 { 00183 FieldVector<K, SIZE> w; 00184 for( typename FieldVector<K, SIZE>::size_type i = 0; i < SIZE; ++i ) 00185 in >> w[ i ]; 00186 if(in) 00187 v = w; 00188 return in; 00189 } 00190 00191 #ifndef DOXYGEN 00192 template< class K > 00193 struct DenseMatVecTraits< FieldVector<K,1> > 00194 { 00195 typedef FieldVector<K,1> derived_type; 00196 typedef K container_type; 00197 typedef K value_type; 00198 typedef size_t size_type; 00199 }; 00200 00203 template<class K> 00204 class FieldVector<K, 1> : 00205 public DenseVector< FieldVector<K,1> > 00206 { 00207 K _data; 00208 typedef DenseVector< FieldVector<K,1> > Base; 00209 public: 00211 enum { 00213 dimension = 1 00214 #if ! DUNE_COMMON_FIELDVECTOR_SIZE_IS_METHOD 00215 , 00217 size = 1 00218 #endif 00219 }; 00220 00221 typedef typename Base::size_type size_type; 00222 00223 //===== construction 00224 00226 FieldVector () {} 00227 00229 FieldVector (const K& k) : _data(k) {} 00230 00232 template<class C> 00233 FieldVector (const DenseVector<C> & x) 00234 { 00235 dune_static_assert(((bool)IsFieldVectorSizeCorrect<C,1>::value), "FieldVectors do not match in dimension!"); 00236 assert(x.size() == 1); 00237 _data = x[0]; 00238 } 00239 00241 inline FieldVector& operator= (const K& k) 00242 { 00243 _data = k; 00244 return *this; 00245 } 00246 00247 //===== forward methods to container 00248 size_type vec_size() const { return 1; } 00249 K & vec_access(size_type i) 00250 { 00251 assert(i == 0); 00252 return _data; 00253 } 00254 const K & vec_access(size_type i) const 00255 { 00256 assert(i == 0); 00257 return _data; 00258 } 00259 00260 //===== conversion operator 00261 00263 operator K () { return _data; } 00264 00266 operator K () const { return _data; } 00267 }; 00268 00269 /* ----- FV / FV ----- */ 00270 /* not necessary as these operations are already covered via the cast operator */ 00271 00272 /* ----- FV / scalar ----- */ 00273 00275 template<class K> 00276 inline FieldVector<K,1> operator+ (const FieldVector<K,1>& a, const K b) 00277 { 00278 return a[0]+b; 00279 } 00280 00282 template<class K> 00283 inline FieldVector<K,1> operator- (const FieldVector<K,1>& a, const K b) 00284 { 00285 return a[0]-b; 00286 } 00287 00289 template<class K> 00290 inline FieldVector<K,1> operator* (const FieldVector<K,1>& a, const K b) 00291 { 00292 return a[0]*b; 00293 } 00294 00296 template<class K> 00297 inline FieldVector<K,1> operator/ (const FieldVector<K,1>& a, const K b) 00298 { 00299 return a[0]/b; 00300 } 00301 00303 template<class K> 00304 inline bool operator> (const FieldVector<K,1>& a, const K b) 00305 { 00306 return a[0]>b; 00307 } 00308 00310 template<class K> 00311 inline bool operator>= (const FieldVector<K,1>& a, const K b) 00312 { 00313 return a[0]>=b; 00314 } 00315 00317 template<class K> 00318 inline bool operator< (const FieldVector<K,1>& a, const K b) 00319 { 00320 return a[0]<b; 00321 } 00322 00324 template<class K> 00325 inline bool operator<= (const FieldVector<K,1>& a, const K b) 00326 { 00327 return a[0]<=b; 00328 } 00329 00331 template<class K> 00332 inline bool operator== (const FieldVector<K,1>& a, const K b) 00333 { 00334 return a[0]==b; 00335 } 00336 00338 template<class K> 00339 inline bool operator!= (const FieldVector<K,1>& a, const K b) 00340 { 00341 return a[0]!=b; 00342 } 00343 00344 /* ----- scalar / FV ------ */ 00345 00347 template<class K> 00348 inline FieldVector<K,1> operator+ (const K a, const FieldVector<K,1>& b) 00349 { 00350 return a+b[0]; 00351 } 00352 00354 template<class K> 00355 inline FieldVector<K,1> operator- (const K a, const FieldVector<K,1>& b) 00356 { 00357 return a-b[0]; 00358 } 00359 00361 template<class K> 00362 inline FieldVector<K,1> operator* (const K a, const FieldVector<K,1>& b) 00363 { 00364 return a*b[0]; 00365 } 00366 00368 template<class K> 00369 inline FieldVector<K,1> operator/ (const K a, const FieldVector<K,1>& b) 00370 { 00371 return a/b[0]; 00372 } 00373 00375 template<class K> 00376 inline bool operator> (const K a, const FieldVector<K,1>& b) 00377 { 00378 return a>b[0]; 00379 } 00380 00382 template<class K> 00383 inline bool operator>= (const K a, const FieldVector<K,1>& b) 00384 { 00385 return a>=b[0]; 00386 } 00387 00389 template<class K> 00390 inline bool operator< (const K a, const FieldVector<K,1>& b) 00391 { 00392 return a<b[0]; 00393 } 00394 00396 template<class K> 00397 inline bool operator<= (const K a, const FieldVector<K,1>& b) 00398 { 00399 return a<=b[0]; 00400 } 00401 00403 template<class K> 00404 inline bool operator== (const K a, const FieldVector<K,1>& b) 00405 { 00406 return a==b[0]; 00407 } 00408 00410 template<class K> 00411 inline bool operator!= (const K a, const FieldVector<K,1>& b) 00412 { 00413 return a!=b[0]; 00414 } 00415 #endif 00416 00419 } // end namespace 00420 00421 #endif