dune-grid
2.1.1
|
00001 // -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 00002 // vi: set et ts=8 sw=2 sts=2: 00003 00004 #ifndef DUNE_GENERICGEOMETRY_REFERENCEELEMENTS_HH 00005 #define DUNE_GENERICGEOMETRY_REFERENCEELEMENTS_HH 00006 00007 #include <dune/common/array.hh> 00008 #include <dune/common/fvector.hh> 00009 #include <dune/common/typetraits.hh> 00010 00011 #include <dune/grid/genericgeometry/referencedomain.hh> 00012 00013 namespace Dune 00014 { 00015 00016 namespace GenericGeometry 00017 { 00018 00019 // ReferenceElement 00020 // ---------------- 00021 00022 template< class Topology, class ctype > 00023 struct ReferenceElement 00024 { 00025 static const unsigned int topologyId = Topology :: id; 00026 static const unsigned int dimension = Topology :: dimension; 00027 00028 static const unsigned int numCorners = Topology :: numCorners; 00029 static const unsigned int numNormals = ReferenceDomain< Topology > :: numNormals; 00030 00031 typedef FieldVector< ctype, dimension > CoordinateType; 00032 00033 template< unsigned int codim > 00034 struct Codim 00035 { 00036 enum { size = Size< Topology, codim > :: value }; 00037 }; 00038 00039 template< unsigned int codim, unsigned int subcodim > 00040 static unsigned int subNumbering ( unsigned int i, unsigned int j ) 00041 { 00042 return SubTopologyNumbering< Topology, codim, subcodim > :: number( i, j ); 00043 } 00044 00045 template< unsigned int codim, unsigned int subcodim > 00046 static unsigned int size ( unsigned int i ) 00047 { 00048 return SubTopologySize< Topology, codim, subcodim > :: size( i ); 00049 } 00050 00051 template< unsigned int codim > 00052 static const FieldVector< ctype, dimension > & 00053 baryCenter ( unsigned int i ) 00054 { 00055 integral_constant< int, codim > codimVariable; 00056 return instance().baryCenters_[ codimVariable ][ i ]; 00057 } 00058 00059 static const CoordinateType &corner ( unsigned int i ) 00060 { 00061 assert( i < numCorners ); 00062 return instance().corners_[ i ]; 00063 } 00064 00065 static bool checkInside ( const CoordinateType &x ) 00066 { 00067 return ReferenceDomain< Topology >::checkInside( x ); 00068 } 00069 00070 static const CoordinateType & 00071 integrationOuterNormal ( unsigned int i ) 00072 { 00073 assert( i < numNormals ); 00074 return instance().normals_[ i ]; 00075 } 00076 00077 static ctype volume () 00078 { 00079 return ReferenceDomain< Topology > :: template volume< ctype >(); 00080 } 00081 00082 static const ReferenceElement &instance () 00083 { 00084 static ReferenceElement inst; 00085 return inst; 00086 } 00087 00088 private: 00089 template< int codim > 00090 class BaryCenterArray; 00091 00092 ReferenceElement () 00093 { 00094 for( unsigned int i = 0; i < numCorners; ++i ) 00095 ReferenceDomain< Topology > :: corner( i, corners_[ i ] ); 00096 for( unsigned int i = 0; i < numNormals; ++i ) 00097 ReferenceDomain< Topology > :: integrationOuterNormal( i, normals_[ i ] ); 00098 } 00099 00100 Dune::array< CoordinateType, numCorners > corners_; 00101 CodimTable< BaryCenterArray, dimension > baryCenters_; 00102 Dune::array< CoordinateType, numNormals > normals_; 00103 }; 00104 00105 00106 00107 template< class Topology, class ctype > 00108 template< int codim > 00109 class ReferenceElement< Topology, ctype > :: BaryCenterArray 00110 { 00111 enum { Size = GenericGeometry :: Size< Topology, codim > :: value }; 00112 00113 typedef FieldVector< ctype, dimension > CoordinateType; 00114 00115 template< int i > 00116 struct Builder; 00117 00118 CoordinateType baryCenters_[ Size ]; 00119 00120 public: 00121 BaryCenterArray () 00122 { 00123 ForLoop< Builder, 0, Size-1 > :: apply( baryCenters_ ); 00124 } 00125 00126 const CoordinateType &operator[] ( unsigned int i ) const 00127 { 00128 assert( i < Size ); 00129 return baryCenters_[ i ]; 00130 } 00131 00132 static unsigned int size () 00133 { 00134 return Size; 00135 } 00136 }; 00137 00138 template< class Topology, class ctype > 00139 template< int codim > 00140 template< int i > 00141 struct ReferenceElement< Topology, ctype > :: BaryCenterArray< codim > :: Builder 00142 { 00143 static void apply ( CoordinateType (&baryCenters)[ Size ] ) 00144 { 00145 typedef SubTopologyNumbering< Topology, codim, dimension - codim > Numbering; 00146 typedef SubTopologySize< Topology, codim, dimension - codim > Size; 00147 00148 CoordinateType &x = baryCenters[ i ]; 00149 x = 0; 00150 const unsigned int numCorners = Size :: size( i ); 00151 for( unsigned int k = 0; k < numCorners; ++k ) 00152 { 00153 unsigned int j = Numbering :: number( i, k ); 00154 00155 CoordinateType y; 00156 ReferenceDomain< Topology > :: corner( j, y ); 00157 x += y; 00158 } 00159 x *= ctype( 1 ) / ctype( numCorners ); 00160 } 00161 }; 00162 00163 } 00164 00165 } 00166 00167 #endif