dune-grid
2.1.1
|
00001 #ifndef DUNE_ALBERTA_GEOMETRYCACHE_HH 00002 #define DUNE_ALBERTA_GEOMETRYCACHE_HH 00003 00004 #include <dune/grid/albertagrid/misc.hh> 00005 #include <dune/grid/albertagrid/algebra.hh> 00006 00007 #if HAVE_ALBERTA 00008 00009 namespace Dune 00010 { 00011 00012 namespace Alberta 00013 { 00014 00015 // GeometryCache 00016 // ------------- 00017 00018 template< int dim > 00019 class GeometryCache 00020 { 00021 static const unsigned int flagIntegrationElement = (1 << 0); 00022 static const unsigned int flagJacobianTransposed = (1 << 1); 00023 static const unsigned int flagJacobianInverseTransposed = (1 << 2); 00024 00025 public: 00026 typedef FieldMatrix< Real, dimWorld, dim > Jacobian; 00027 typedef FieldMatrix< Real, dim, dimWorld > JacobianTransposed; 00028 00029 GeometryCache () 00030 : flags_( 0 ) 00031 {} 00032 00033 const Real &integrationElement ( const ALBERTA EL_INFO &elInfo ) 00034 { 00035 if( (flags_ & flagIntegrationElement) == 0 ) 00036 { 00037 integrationElement_ = std::abs( determinant( jacobianTransposed( elInfo ) ) ); 00038 assert( integrationElement_ > 1e-14 ); 00039 flags_ |= flagIntegrationElement; 00040 } 00041 return integrationElement_; 00042 } 00043 00044 const JacobianTransposed &jacobianTransposed ( const ALBERTA EL_INFO &elInfo ) 00045 { 00046 if( (flags_ & flagJacobianTransposed) == 0 ) 00047 { 00048 assert( (elInfo.fill_flag & FillFlags< dim >::coords) != 0 ); 00049 const GlobalVector &x = elInfo.coord[ 0 ]; 00050 for( int i = 0; i < dim; ++i ) 00051 { 00052 const GlobalVector &y = elInfo.coord[ i+1 ]; 00053 for( int j = 0; j < dimWorld; ++j ) 00054 jacobianTransposed_[ i ][ j ] = y[ j ] - x[ j ]; 00055 } 00056 flags_ |= flagJacobianTransposed; 00057 } 00058 return jacobianTransposed_; 00059 } 00060 00061 const Jacobian &jacobianInverseTransposed ( const ALBERTA EL_INFO &elInfo ) 00062 { 00063 if( (flags_ & flagJacobianInverseTransposed) == 0 ) 00064 { 00065 integrationElement_ = std::abs( invert( jacobianTransposed( elInfo ), jacobianInverseTransposed_ ) ); 00066 assert( integrationElement_ > 1e-14 ); 00067 flags_ |= flagIntegrationElement | flagJacobianInverseTransposed; 00068 } 00069 return jacobianInverseTransposed_; 00070 } 00071 00072 private: 00073 unsigned int flags_; 00074 Real integrationElement_; 00075 FieldMatrix< Real, dim, dimWorld > jacobianTransposed_; 00076 FieldMatrix< Real, dimWorld, dim > jacobianInverseTransposed_; 00077 }; 00078 00079 00080 00081 // GeometryCacheProxy 00082 // ------------------ 00083 00084 template< int dim > 00085 struct GeometryCacheProxy 00086 { 00087 typedef FieldMatrix< Real, dimWorld, dim > Jacobian; 00088 typedef FieldMatrix< Real, dim, dimWorld > JacobianTransposed; 00089 00090 GeometryCacheProxy ( GeometryCache< dim > &geometryCache, const ALBERTA EL_INFO &elInfo ) 00091 : geometryCache_( geometryCache ), 00092 elInfo_( elInfo ) 00093 {} 00094 00095 const Real &integrationElement () 00096 { 00097 return geometryCache_.integrationElement( elInfo_ ); 00098 } 00099 00100 const JacobianTransposed &jacobianTransposed () 00101 { 00102 return geometryCache_.jacobianTransposed( elInfo_ ); 00103 } 00104 00105 const Jacobian &jacobianInverseTransposed () 00106 { 00107 return geometryCache_.jacobianInverseTransposed( elInfo_ ); 00108 } 00109 00110 private: 00111 GeometryCache< dim > &geometryCache_; 00112 const ALBERTA EL_INFO &elInfo_; 00113 }; 00114 00115 } 00116 00117 } 00118 00119 #endif // #if HAVE_ALBERTA 00120 00121 #endif // #ifndef DUNE_ALBERTA_GEOMETRYCACHE_HH