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