dune-common  2.2.0
fvector.hh
Go to the documentation of this file.
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