00001
00002
00003 #ifndef DUNE_FVECTOR_HH
00004 #define DUNE_FVECTOR_HH
00005
00006 #include <array>
00007 #include <cmath>
00008 #include <cstddef>
00009 #include <cstdlib>
00010 #include <complex>
00011 #include <cstring>
00012 #include <utility>
00013 #include <initializer_list>
00014 #include <algorithm>
00015
00016 #include "typetraits.hh"
00017 #include "exceptions.hh"
00018
00019 #include "ftraits.hh"
00020 #include "densevector.hh"
00021 #include "unused.hh"
00022 #include "boundschecking.hh"
00023
00024 namespace Dune {
00025
00035 template< class K, int SIZE > class FieldVector;
00036 template< class K, int SIZE >
00037 struct DenseMatVecTraits< FieldVector<K,SIZE> >
00038 {
00039 typedef FieldVector<K,SIZE> derived_type;
00040 typedef std::array<K,SIZE> container_type;
00041 typedef K value_type;
00042 typedef typename container_type::size_type size_type;
00043 };
00044
00045 template< class K, int SIZE >
00046 struct FieldTraits< FieldVector<K,SIZE> >
00047 {
00048 typedef typename FieldTraits<K>::field_type field_type;
00049 typedef typename FieldTraits<K>::real_type real_type;
00050 };
00051
00060 template<typename C, int SIZE>
00061 struct IsFieldVectorSizeCorrect
00062 {
00063 enum {
00068 value = true
00069 };
00070 };
00071
00072 template<typename T, int SIZE>
00073 struct IsFieldVectorSizeCorrect<FieldVector<T,SIZE>,SIZE>
00074 {
00075 enum {value = true};
00076 };
00077
00078 template<typename T, int SIZE, int SIZE1>
00079 struct IsFieldVectorSizeCorrect<FieldVector<T,SIZE1>,SIZE>
00080 {
00081 enum {value = false};
00082 };
00083
00084
00090 template< class K, int SIZE >
00091 class FieldVector :
00092 public DenseVector< FieldVector<K,SIZE> >
00093 {
00094 std::array<K,SIZE> _data;
00095 typedef DenseVector< FieldVector<K,SIZE> > Base;
00096 public:
00098 enum {
00100 dimension = SIZE
00101 };
00102
00103 typedef typename Base::size_type size_type;
00104 typedef typename Base::value_type value_type;
00105
00107 typedef value_type& reference;
00108
00110 typedef const value_type& const_reference;
00111
00113 constexpr FieldVector()
00114 : _data{{}}
00115 {}
00116
00118 explicit FieldVector (const K& t)
00119 {
00120 std::fill(_data.begin(),_data.end(),t);
00121 }
00122
00124 FieldVector (const FieldVector & x) : Base(), _data(x._data)
00125 {}
00126
00128 FieldVector (std::initializer_list<K> const &l)
00129 {
00130 assert(l.size() == dimension);
00131 std::copy_n(l.begin(), std::min(static_cast<std::size_t>(dimension),
00132 l.size()),
00133 _data.begin());
00134 }
00135
00147 template<class C>
00148 FieldVector (const DenseVector<C> & x, typename std::enable_if<IsFieldVectorSizeCorrect<C,SIZE>::value>::type* dummy=0 )
00149 {
00150 DUNE_UNUSED_PARAMETER(dummy);
00151
00152 assert(x.size() == SIZE);
00153 std::copy_n(x.begin(), std::min(static_cast<std::size_t>(SIZE),x.size()), _data.begin());
00154 }
00155
00157 template<class K1, int SIZE1>
00158 explicit FieldVector (const FieldVector<K1,SIZE1> & x)
00159 {
00160 static_assert(SIZE1 == SIZE, "FieldVector in constructor has wrong size");
00161 for (size_type i = 0; i<SIZE; i++)
00162 _data[i] = x[i];
00163 }
00164 using Base::operator=;
00165
00166
00167 static constexpr size_type size () { return SIZE; }
00168
00169 K & operator[](size_type i) {
00170 DUNE_ASSERT_BOUNDS(i < SIZE);
00171 return _data[i];
00172 }
00173 const K & operator[](size_type i) const {
00174 DUNE_ASSERT_BOUNDS(i < SIZE);
00175 return _data[i];
00176 }
00177 };
00178
00190 template<class K, int SIZE>
00191 inline std::istream &operator>> ( std::istream &in,
00192 FieldVector<K, SIZE> &v )
00193 {
00194 FieldVector<K, SIZE> w;
00195 for( typename FieldVector<K, SIZE>::size_type i = 0; i < SIZE; ++i )
00196 in >> w[ i ];
00197 if(in)
00198 v = w;
00199 return in;
00200 }
00201
00202 #ifndef DOXYGEN
00203 template< class K >
00204 struct DenseMatVecTraits< FieldVector<K,1> >
00205 {
00206 typedef FieldVector<K,1> derived_type;
00207 typedef K container_type;
00208 typedef K value_type;
00209 typedef size_t size_type;
00210 };
00211
00214 template<class K>
00215 class FieldVector<K, 1> :
00216 public DenseVector< FieldVector<K,1> >
00217 {
00218 K _data;
00219 typedef DenseVector< FieldVector<K,1> > Base;
00220 public:
00222 enum {
00224 dimension = 1
00225 };
00226
00227 typedef typename Base::size_type size_type;
00228
00230 typedef K& reference;
00231
00233 typedef const K& const_reference;
00234
00235
00236
00238 constexpr FieldVector ()
00239 : _data()
00240 {}
00241
00243 template<typename T,
00244 typename EnableIf = typename std::enable_if<
00245 std::is_convertible<T, K>::value &&
00246 ! std::is_same<K, DenseVector<typename FieldTraits<T>::field_type>
00247 >::value
00248 >::type
00249 >
00250 FieldVector (const T& k) : _data(k) {}
00251
00253 template<class C>
00254 FieldVector (const DenseVector<C> & x)
00255 {
00256 static_assert(((bool)IsFieldVectorSizeCorrect<C,1>::value), "FieldVectors do not match in dimension!");
00257 assert(x.size() == 1);
00258 _data = x[0];
00259 }
00260
00262 FieldVector ( const FieldVector &other )
00263 : Base(), _data( other._data )
00264 {}
00265
00267 FieldVector (std::initializer_list<K> const &l)
00268 {
00269 assert(l.size() == 1);
00270 _data = *l.begin();
00271 }
00272
00274 template<typename T,
00275 typename EnableIf = typename std::enable_if<
00276 std::is_convertible<T, K>::value &&
00277 ! std::is_same<K, DenseVector<typename FieldTraits<T>::field_type>
00278 >::value
00279 >::type
00280 >
00281 inline FieldVector& operator= (const T& k)
00282 {
00283 _data = k;
00284 return *this;
00285 }
00286
00287
00288 static constexpr size_type size () { return 1; }
00289
00290 K & operator[](size_type i)
00291 {
00292 DUNE_UNUSED_PARAMETER(i);
00293 DUNE_ASSERT_BOUNDS(i == 0);
00294 return _data;
00295 }
00296 const K & operator[](size_type i) const
00297 {
00298 DUNE_UNUSED_PARAMETER(i);
00299 DUNE_ASSERT_BOUNDS(i == 0);
00300 return _data;
00301 }
00302
00303
00304
00306 operator K& () { return _data; }
00307
00309 operator const K& () const { return _data; }
00310 };
00311
00312
00313
00314
00316 template<class K>
00317 inline bool operator> (const FieldVector<K,1>& a, const FieldVector<K,1>& b)
00318 {
00319 return a[0]>b[0];
00320 }
00321
00323 template<class K>
00324 inline bool operator>= (const FieldVector<K,1>& a, const FieldVector<K,1>& b)
00325 {
00326 return a[0]>=b[0];
00327 }
00328
00330 template<class K>
00331 inline bool operator< (const FieldVector<K,1>& a, const FieldVector<K,1>& b)
00332 {
00333 return a[0]<b[0];
00334 }
00335
00337 template<class K>
00338 inline bool operator<= (const FieldVector<K,1>& a, const FieldVector<K,1>& b)
00339 {
00340 return a[0]<=b[0];
00341 }
00342
00343
00344
00346 template<class K>
00347 inline FieldVector<K,1> operator+ (const FieldVector<K,1>& a, const K b)
00348 {
00349 return a[0]+b;
00350 }
00351
00353 template<class K>
00354 inline FieldVector<K,1> operator- (const FieldVector<K,1>& a, const K b)
00355 {
00356 return a[0]-b;
00357 }
00358
00360 template<class K>
00361 inline FieldVector<K,1> operator* (const FieldVector<K,1>& a, const K b)
00362 {
00363 return a[0]*b;
00364 }
00365
00367 template<class K>
00368 inline FieldVector<K,1> operator/ (const FieldVector<K,1>& a, const K b)
00369 {
00370 return a[0]/b;
00371 }
00372
00374 template<class K>
00375 inline bool operator> (const FieldVector<K,1>& a, const K b)
00376 {
00377 return a[0]>b;
00378 }
00379
00381 template<class K>
00382 inline bool operator>= (const FieldVector<K,1>& a, const K b)
00383 {
00384 return a[0]>=b;
00385 }
00386
00388 template<class K>
00389 inline bool operator< (const FieldVector<K,1>& a, const K b)
00390 {
00391 return a[0]<b;
00392 }
00393
00395 template<class K>
00396 inline bool operator<= (const FieldVector<K,1>& a, const K b)
00397 {
00398 return a[0]<=b;
00399 }
00400
00402 template<class K>
00403 inline bool operator== (const FieldVector<K,1>& a, const K b)
00404 {
00405 return a[0]==b;
00406 }
00407
00409 template<class K>
00410 inline bool operator!= (const FieldVector<K,1>& a, const K b)
00411 {
00412 return a[0]!=b;
00413 }
00414
00415
00416
00418 template<class K>
00419 inline FieldVector<K,1> operator+ (const K a, const FieldVector<K,1>& b)
00420 {
00421 return a+b[0];
00422 }
00423
00425 template<class K>
00426 inline FieldVector<K,1> operator- (const K a, const FieldVector<K,1>& b)
00427 {
00428 return a-b[0];
00429 }
00430
00432 template<class K>
00433 inline FieldVector<K,1> operator* (const K a, const FieldVector<K,1>& b)
00434 {
00435 return a*b[0];
00436 }
00437
00439 template<class K>
00440 inline FieldVector<K,1> operator/ (const K a, const FieldVector<K,1>& b)
00441 {
00442 return a/b[0];
00443 }
00444
00446 template<class K>
00447 inline bool operator> (const K a, const FieldVector<K,1>& b)
00448 {
00449 return a>b[0];
00450 }
00451
00453 template<class K>
00454 inline bool operator>= (const K a, const FieldVector<K,1>& b)
00455 {
00456 return a>=b[0];
00457 }
00458
00460 template<class K>
00461 inline bool operator< (const K a, const FieldVector<K,1>& b)
00462 {
00463 return a<b[0];
00464 }
00465
00467 template<class K>
00468 inline bool operator<= (const K a, const FieldVector<K,1>& b)
00469 {
00470 return a<=b[0];
00471 }
00472
00474 template<class K>
00475 inline bool operator== (const K a, const FieldVector<K,1>& b)
00476 {
00477 return a==b[0];
00478 }
00479
00481 template<class K>
00482 inline bool operator!= (const K a, const FieldVector<K,1>& b)
00483 {
00484 return a!=b[0];
00485 }
00486 #endif
00487
00490 }
00491
00492 #endif