- Home
- About DUNE
- Download
- Documentation
- Community
- Development
00001 #ifndef DUNE_FIELD_HH 00002 #define DUNE_FIELD_HH 00003 00004 #if HAVE_ALGLIB 00005 #include <alglib/amp.h> 00006 #endif 00007 00008 #include <dune/common/gmpfield.hh> 00009 #include <dune/common/fvector.hh> 00010 #include <dune/common/fmatrix.hh> 00011 00012 namespace Dune 00013 { 00014 00015 // Unity 00016 // ----- 00017 00028 template< class Field > 00029 struct Unity 00030 { 00031 operator Field () const 00032 { 00033 return Field( 1 ); 00034 } 00035 }; 00036 00037 template< class Field > 00038 Field operator+ ( const Unity< Field > &u, const Field &f ) 00039 { 00040 return (Field)u + f; 00041 } 00042 00043 template< class Field > 00044 Field operator- ( const Unity< Field > &u, const Field &f ) 00045 { 00046 return (Field)u - f; 00047 } 00048 00049 template< class Field > 00050 Field operator* ( const Unity< Field > &u, const Field &f ) 00051 { 00052 return f; 00053 } 00054 00055 template< class Field > 00056 Field operator/ ( const Unity< Field > &u, const Field &f ) 00057 { 00058 return (Field)u / f; 00059 } 00060 00061 00062 00063 // Zero 00064 // ---- 00065 00077 template< class Field > 00078 struct Zero 00079 { 00080 operator Field () const 00081 { 00082 return Field( 0 ); 00083 } 00084 static const Field epsilon() 00085 { 00086 return Field(1e-12); 00087 } 00088 }; 00089 #if HAVE_ALGLIB 00090 template< unsigned int precision > 00091 struct Zero< amp::ampf< precision > > 00092 { 00093 typedef amp::ampf< precision > Field; 00094 operator Field () const 00095 { 00096 return Field( 0 ); 00097 } 00098 static const Field epsilon() 00099 { 00100 return Field(1e-20); 00101 } 00102 }; 00103 #endif 00104 #if HAVE_GMP 00105 template< unsigned int precision > 00106 struct Zero< GMPField< precision > > 00107 { 00108 typedef GMPField< precision > Field; 00109 operator Field () const 00110 { 00111 return Field( 0 ); 00112 } 00113 static const Field epsilon() 00114 { 00115 return Field(1e-20); 00116 } 00117 }; 00118 #endif 00119 00120 template< class Field > 00121 inline bool operator == ( const Zero< Field > &, const Field &f ) 00122 { 00123 return ( f < Zero<Field>::epsilon() && f > -Zero<Field>::epsilon() ); 00124 } 00125 00126 template< class Field > 00127 inline bool operator == ( const Field &f, const Zero< Field > &z) 00128 { 00129 return ( z == f ); 00130 } 00131 00132 template< class Field > 00133 inline bool operator< ( const Zero< Field > &, const Field &f ) 00134 { 00135 return f > Zero<Field>::epsilon(); 00136 } 00137 00138 template< class Field > 00139 inline bool operator< ( const Field &f, const Zero< Field > & ) 00140 { 00141 return f < -Zero<Field>::epsilon(); 00142 } 00143 00144 template< class Field > 00145 inline bool operator> ( const Zero< Field > &z, const Field &f ) 00146 { 00147 return f < z; 00148 } 00149 00150 template< class Field > 00151 inline bool operator> ( const Field &f, const Zero< Field > &z ) 00152 { 00153 return z < f; 00154 } 00155 00156 00157 // field_cast 00158 // ---------- 00159 00172 template< class F2, class F1 > 00173 inline void field_cast ( const F1 &f1, F2 &f2 ) 00174 { 00175 f2 = f1; 00176 } 00177 00178 #if HAVE_ALGLIB 00179 template< unsigned int precision > 00180 inline void field_cast ( const amp::ampf< precision > &f1, double &f2 ) 00181 { 00182 f2 = f1.toDouble(); 00183 } 00184 00185 template< unsigned int precision > 00186 inline void field_cast ( const amp::ampf< precision > &f1, long double &f2 ) 00187 { 00188 f2 = f1.toDouble(); 00189 } 00190 #endif 00191 00192 #if HAVE_GMP 00193 template< unsigned int precision > 00194 inline void field_cast ( const Dune::GMPField< precision > &f1, double &f2 ) 00195 { 00196 f2 = f1.get_d(); 00197 } 00198 00199 template< unsigned int precision > 00200 inline void field_cast ( const Dune::GMPField< precision > &f1, long double &f2 ) 00201 { 00202 f2 = f1.get_d(); 00203 } 00204 #endif 00205 00206 template< class F2, class F1, int dim > 00207 inline void field_cast ( const Dune::FieldVector< F1, dim > &f1, Dune::FieldVector< F2, dim > &f2 ) 00208 { 00209 for( int d = 0; d < dim; ++d ) 00210 field_cast( f1[ d ], f2[ d ] ); 00211 } 00212 template< class F2, class F1 > 00213 inline void field_cast ( const Dune::FieldVector< F1, 1 > &f1, F2 &f2 ) 00214 { 00215 field_cast( f1[ 0 ], f2 ); 00216 } 00217 template< class F2, class F1 > 00218 inline void field_cast ( const F1 &f1, Dune::FieldVector< F2, 1 > &f2 ) 00219 { 00220 field_cast( f1, f2[ 0 ] ); 00221 } 00222 00223 template< class F2, class F1, int rdim, int cdim > 00224 inline void field_cast ( const Dune::FieldMatrix< F1, rdim, cdim > &f1, Dune::FieldMatrix< F2, rdim, cdim > &f2 ) 00225 { 00226 for( int r = 0; r < rdim; ++r ) 00227 field_cast( f1[ r ], f2[ r ] ); 00228 } 00229 template< class F2, class F1 > 00230 inline void field_cast ( const Dune::FieldMatrix<F1,1,1> &f1, Dune::FieldMatrix< F2, 1,1 > &f2 ) 00231 { 00232 field_cast( f1[ 0 ][ 0 ], f2[ 0 ][ 0 ] ); 00233 } 00234 template< class F2, class F1 > 00235 inline void field_cast ( const Dune::FieldMatrix< F1, 1,1 > &f1, F2 &f2 ) 00236 { 00237 field_cast( f1[ 0 ][ 0 ], f2 ); 00238 } 00239 template< class F2, class F1 > 00240 inline void field_cast ( const F1 &f1, Dune::FieldMatrix< F2, 1,1 > &f2 ) 00241 { 00242 field_cast( f1, f2[ 0 ][ 0 ] ); 00243 } 00244 template< class F2, class F1 > 00245 inline void field_cast ( const Dune::FieldVector<F1,1> &f1, Dune::FieldMatrix< F2, 1,1 > &f2 ) 00246 { 00247 field_cast( f1[ 0 ], f2[ 0 ][ 0 ] ); 00248 } 00249 template< class F2, class F1 > 00250 inline void field_cast ( const Dune::FieldMatrix<F1,1,1> &f1, Dune::FieldVector< F2, 1 > &f2 ) 00251 { 00252 field_cast( f1[ 0 ][ 0 ], f2[ 0 ] ); 00253 } 00254 00255 template< class F2, class F1 > 00256 inline void field_cast ( const Dune::FieldVector< F1, 1 > &f1, Dune::FieldVector<F2, 1> &f2 ) 00257 { 00258 field_cast( f1[ 0 ], f2[ 0 ] ); 00259 } 00260 00261 template< class F2,class V > 00262 struct FieldCast 00263 { 00264 typedef F2 type; 00265 }; 00266 template< class F2,class F1,int dim > 00267 struct FieldCast< F2, Dune::FieldVector<F1,dim> > 00268 { 00269 typedef Dune::FieldVector<F2,dim> type; 00270 }; 00271 template< class F2,class F1,int dim1, int dim2> 00272 struct FieldCast< F2, Dune::FieldMatrix<F1,dim1,dim2> > 00273 { 00274 typedef Dune::FieldMatrix<F2,dim1,dim2> type; 00275 }; 00276 template< class F2,class V > 00277 inline typename FieldCast<F2,V>::type field_cast ( const V &f1 ) 00278 { 00279 typename FieldCast<F2,V>::type f2; 00280 field_cast( f1, f2 ); 00281 return f2; 00282 } 00283 00284 00285 // Precision 00286 // this is not a perfect solution to obtain the 00287 // precision of a field - definition is not clear 00288 // to be removed 00289 // --------- 00290 00291 template <class Field> 00292 struct Precision; 00293 00294 template<> 00295 struct Precision< double > 00296 { 00297 static const unsigned int value = 64; 00298 }; 00299 00300 template<> 00301 struct Precision< long double > 00302 { 00303 static const unsigned int value = 80; 00304 }; 00305 00306 template<> 00307 struct Precision< float > 00308 { 00309 static const unsigned int value = 32; 00310 }; 00311 00312 #if HAVE_ALGLIB 00313 template< unsigned int precision > 00314 struct Precision< amp::ampf< precision > > 00315 { 00316 static const unsigned int value = precision; 00317 }; 00318 #endif 00319 #if HAVE_GMP 00320 template< unsigned int precision > 00321 struct Precision< GMPField< precision > > 00322 { 00323 static const unsigned int value = precision; 00324 }; 00325 #endif 00326 00327 // ComputeField 00328 // ------------ 00329 00330 template <class Field,unsigned int sum> 00331 struct ComputeField 00332 { 00333 typedef Field Type; 00334 }; 00335 00336 #if HAVE_ALGLIB 00337 template< unsigned int precision, unsigned int sum > 00338 struct ComputeField< amp::ampf< precision >, sum > 00339 { 00340 typedef amp::ampf<precision+sum> Type; 00341 }; 00342 #endif 00343 #if HAVE_GMP 00344 template< unsigned int precision, unsigned int sum > 00345 struct ComputeField< GMPField< precision >, sum > 00346 { 00347 typedef GMPField<precision+sum> Type; 00348 }; 00349 #endif 00350 } 00351 00352 // to be moved to different location... 00353 namespace std 00354 { 00355 00356 #if HAVE_ALGLIB 00357 template< unsigned int precision > 00358 inline ostream & 00359 operator<< ( ostream &out, 00360 const amp::ampf< precision > &value ) 00361 { 00362 return out << value.toDec(); 00363 } 00364 00365 template< unsigned int precision > 00366 inline amp::ampf< precision > sqrt ( const amp::ampf< precision > &a ) 00367 { 00368 return amp::sqrt( a ); 00369 } 00370 00371 template< unsigned int precision > 00372 inline amp::ampf< precision > abs ( const amp::ampf< precision > &a ) 00373 { 00374 return amp::abs( a ); 00375 } 00376 #endif // #if HAVE_ALGLIB 00377 00378 } 00379 00380 #endif // #ifndef DUNE_FIELD_HH
Generated on Fri Apr 29 2011 with Doxygen (ver 1.7.1) [doxygen-log,error-log].