00001 #ifndef DUNE_GENERICGEOMETRY_GENERICREFERENCEELEMENT_HH
00002 #define DUNE_GENERICGEOMETRY_GENERICREFERENCEELEMENT_HH
00003
00004 #include <dune/grid/genericgeometry/conversion.hh>
00005 #include <dune/grid/genericgeometry/referenceelements.hh>
00006 #include <dune/grid/genericgeometry/geometry.hh>
00007
00008 namespace Dune
00009 {
00010
00011
00012
00013
00014 template< class ctype, int dim >
00015 class GenericReferenceElement
00016 {
00017 typedef GenericReferenceElement< ctype, dim > This;
00018
00019 class SubEntityInfo;
00020 template< class Topology > class CornerStorage;
00021 template< class Topology > struct Initialize;
00022
00023 struct GeometryTraits
00024 : public GenericGeometry :: DefaultGeometryTraits< ctype, dim, dim >
00025 {
00026 typedef GenericGeometry :: DefaultGeometryTraits< ctype, dim, dim > Base;
00027
00028 typedef typename Base :: CoordTraits CoordTraits;
00029
00030 template< class Topology >
00031 struct Mapping
00032 {
00033 typedef GenericGeometry :: CornerMapping
00034 < CoordTraits, Topology, dim, CornerStorage< Topology >, true >
00035 type;
00036 };
00037
00038 struct Caching
00039 {
00040 static const GenericGeometry :: EvaluationType evaluateJacobianTransposed
00041 = GenericGeometry :: PreCompute;
00042 static const GenericGeometry :: EvaluationType evaluateJacobianInverseTransposed
00043 = GenericGeometry :: PreCompute;
00044 static const GenericGeometry :: EvaluationType evaluateIntegrationElement
00045 = GenericGeometry :: PreCompute;
00046 static const GenericGeometry :: EvaluationType evaluateNormal
00047 = GenericGeometry :: PreCompute;
00048 };
00049 };
00050
00051 public:
00052 template< int codim >
00053 class Codim
00054 {
00055 typedef GenericGeometry :: HybridMapping< dim-codim, GeometryTraits > Mapping;
00056 };
00057
00058 private:
00059 template< int codim >
00060 class MappingArray
00061 : public std :: vector< typename Codim< codim > :: Mapping * >
00062 {};
00063
00064 typedef GenericGeometry :: CodimTable< MappingArray, dim > MappingsTable;
00065
00066 std :: vector< SubEntityInfo > info_[ dim+1 ];
00067 double volume_;
00068 MappingsTable mappings_;
00069
00070 public:
00071 int size ( int c ) const
00072 {
00073 assert( (c >= 0) && (c <= dim) );
00074 return info_[ c ].size();
00075 }
00076
00077 int size ( int i, int c, int cc )
00078 {
00079 assert( (c >= 0) && (c <= dim) );
00080 return info_[ c ][ i ].size( cc );
00081 }
00082
00083 int subEntity ( int i, int c, int ii, int cc ) const
00084 {
00085 assert( (c >= 0) && (c <= dim) );
00086 return info_[ c ][ i ].number( ii, cc );
00087 }
00088
00089 const FieldVector< ctype, dim > &position( int i, int c ) const
00090 {
00091 assert( (c >= 0) && (c <= dim) );
00092 return info_[ c ][ i ].position();
00093 }
00094
00095 template< int codim >
00096 FieldVector< ctype, dim >
00097 global( const FieldVector< ctype, dim-codim > &local, int i, int c ) const
00098 {
00099 if( c != codim )
00100 DUNE_THROW( Exception, "Local Coordinate Type does not correspond to codimension c." );
00101 assert( c == codim );
00102 return mapping< codim >( i ).global( local );
00103 }
00104
00105 template< int codim >
00106 FieldVector< ctype, dim >
00107 global( const FieldVector< ctype, dim-codim > &local, int i ) const
00108 {
00109 return mapping< codim >( i ).global( local );
00110 }
00111
00112 template< int codim >
00113 typename Codim< codim > :: Mapping &mapping( int i ) const
00114 {
00115 Int2Type< codim > codimVariable;
00116 return *(mappings_[ codimVariable ][ i ]);
00117 }
00118
00119 GeometryType type ( int i, int c ) const
00120 {
00121 assert( (c >= 0) && (c <= dim) );
00122 return info_[ c ][ i ].type();
00123 }
00124
00125 double volume () const
00126 {
00127 return volume_;
00128 }
00129
00130 template< GeometryType :: BasicType type >
00131 void initialize ()
00132 {
00133 typedef typename GenericGeometry :: Convert< type, dim > :: type Topology;
00134 typedef Initialize< Topology > Init;
00135 typedef GenericGeometry :: VirtualMapping< Topology, GeometryTraits > VirtualMapping;
00136
00137 Int2Type< 0 > codim0Variable;
00138 mappings_[ codim0Variable ].resize( 1 );
00139 mappings_[ codim0Variable ][ 0 ] = new VirtualMapping( codim0Variable );
00140
00141
00142 GenericGeometry :: ForLoop< Init :: template Codim, 0, dim > :: apply( info_, mappings_ );
00143 volume_ = GenericGeometry :: ReferenceDomain< Topology > :: template volume< double >();
00144 }
00145 };
00146
00147
00148 template< class ctype, int dim >
00149 class GenericReferenceElement< ctype, dim > :: SubEntityInfo
00150 {
00151 template< class Topology, int codim > struct Initialize
00152 {
00153 template< int subcodim > struct SubCodim;
00154 };
00155
00156 int codim_;
00157 std :: vector< int > numbering_[ dim+1 ];
00158 FieldVector< ctype, dim > baryCenter_;
00159 GeometryType type_;
00160
00161 public:
00162 int size ( int cc ) const
00163 {
00164 assert( (cc >= codim_) && (cc <= dim) );
00165 return numbering_[ cc ].size();
00166 }
00167
00168 int number ( int ii, int cc ) const
00169 {
00170 assert( (cc >= codim_) && (cc <= dim) );
00171 return numbering_[ cc ][ ii ];
00172 }
00173
00174 const FieldVector< ctype, dim > &position () const
00175 {
00176 return baryCenter_;
00177 }
00178
00179 GeometryType type () const
00180 {
00181 return type_;
00182 }
00183
00184 template< class Topology, int codim >
00185 void initialize ( unsigned int i )
00186 {
00187 typedef Initialize< Topology, codim > Init;
00188 typedef GenericGeometry :: ReferenceElement< Topology, ctype > RefElement;
00189
00190 GenericGeometry :: ForLoop< Init :: template SubCodim, 0, dim-codim > :: apply( i, numbering_ );
00191 baryCenter_ = RefElement :: template baryCenter< codim >( i );
00192 type_ = GenericGeometry :: DuneGeometryType< Topology, GeometryType :: simplex > :: type();
00193 }
00194 };
00195
00196
00197 template< class ctype, int dim >
00198 template< class Topology >
00199 class GenericReferenceElement< ctype, dim > :: CornerStorage
00200 {
00201 typedef GenericGeometry :: ReferenceElement< Topology, ctype > RefElement;
00202
00203 public:
00204 static const unsigned int size = Topology :: numCorners;
00205
00206 private:
00207 FieldVector< ctype, dim > coords_[ size ];
00208
00209 public:
00210 explicit CornerStorage ( const Int2Type< 0 > & )
00211 {
00212 for( unsigned int i = 0; i < size; ++i )
00213 coords_[ i ] = RefElement :: corner( i );
00214 }
00215
00216 template< class Mapping, unsigned int codim >
00217 explicit
00218 CornerStorage ( const GenericGeometry :: SubMappingCoords< Mapping, codim > &coords )
00219 {
00220 for( unsigned int i = 0; i < size; ++i )
00221 coords_[ i ] = coords[ i ];
00222 }
00223
00224 const FieldVector< ctype, dim > &operator[] ( unsigned int i ) const
00225 {
00226 return coords_[ i ];
00227 }
00228 };
00229
00230
00231 template< class ctype, int dim >
00232 template< class Topology, int codim >
00233 template< int subcodim >
00234 struct GenericReferenceElement< ctype, dim >
00235 :: SubEntityInfo :: Initialize< Topology, codim > :: SubCodim
00236 {
00237 typedef GenericGeometry :: ReferenceElement< Topology, ctype > RefElement;
00238
00239 static void apply ( unsigned int i, std :: vector< int > (&numbering)[ dim+1 ] )
00240 {
00241 const unsigned int size = RefElement :: template size< codim, subcodim >( i );
00242 numbering[ codim+subcodim ].resize( size );
00243 for( unsigned int j = 0; j < size; ++j )
00244 {
00245 numbering[ codim+subcodim ][ j ]
00246 = RefElement :: template subNumbering< codim, subcodim >[ i ][ j ];
00247 }
00248 }
00249 };
00250
00251
00252 template< class ctype, int dim >
00253 template< class Topology >
00254 struct GenericReferenceElement< ctype, dim > :: Initialize
00255 {
00256 typedef Dune :: GenericReferenceElement< ctype, dim > GenericReferenceElement;
00257
00258 typedef typename GenericReferenceElement :: template Codim< 0 > :: Mapping
00259 ReferenceMapping;
00260
00261 template< int codim >
00262 struct Codim
00263 {
00264 typedef typename GenericReferenceElement
00265 :: template Codim< codim > :: Mapping :: CachingType
00266 Caching;
00267
00268 static void apply ( std :: vector< SubEntityInfo > (&info)[ dim+1 ],
00269 MappingsTable &mappings )
00270 {
00271 const unsigned int size = GenericGeometry :: Size< Topology, codim > :: value;
00272 info[ codim ].resize( size );
00273 for( unsigned int i = 0; i < size; ++i )
00274 info[ codim ][ i ].template initialize< Topology, codim >( i );
00275
00276 if( codim > 0 )
00277 {
00278 const Int2Type< 0 > codim0Variable;
00279 const ReferenceMapping &refMapping = *(mappings[ codim0Variable ][ 0 ]);
00280
00281 const Int2Type< codim > codimVariable;
00282 mappings[ codimVariable ].resize( size );
00283 for( unsigned int i = 0; i < size; ++i )
00284 {
00285 mappings[ codimVariable ][ i ]
00286 = refMapping.template subMapping< codim >( i, Caching() );
00287 }
00288 }
00289 }
00290 };
00291 };
00292
00293
00294
00295
00296
00297
00298 template< class ctype, int dim >
00299 struct GenericReferenceElementContainer
00300 {
00301 typedef GenericReferenceElement< ctype, dim > value_type;
00302
00303 private:
00304 value_type simplex;
00305 value_type cube;
00306 value_type pyramid;
00307 value_type prism;
00308
00309 GenericReferenceElementContainer ()
00310 {
00311 simplex.template initialize< GeometryType :: simplex >();
00312 cube.template initialize< GeometryType :: cube >();
00313 pyramid.template initialize< GeometryType :: pyramid >();
00314 prism.template initialize< GeometryType :: prism >();
00315 }
00316
00317 public:
00318 const value_type &operator() ( const GeometryType &type ) const
00319 {
00320 assert( type.dim() == dim );
00321 switch( type.basicType() )
00322 {
00323 case GeometryType :: simplex:
00324 return simplex;
00325
00326 case GeometryType :: cube:
00327 return cube;
00328
00329 case GeometryType :: pyramid:
00330 return pyramid;
00331
00332 case GeometryType :: prism:
00333 return prism;
00334
00335 default:
00336 DUNE_THROW( RangeError, "Unknown geometry type: " << type );
00337 }
00338 }
00339 };
00340
00341 template< class ctype >
00342 struct GenericReferenceElementContainer< ctype, 2 >
00343 {
00344 typedef GenericReferenceElement< ctype, 2 > value_type;
00345
00346 private:
00347 value_type simplex;
00348 value_type cube;
00349
00350 GenericReferenceElementContainer ()
00351 {
00352 simplex.template initialize< GeometryType :: simplex >();
00353 cube.template initialize< GeometryType :: cube >();
00354 }
00355
00356 public:
00357 const value_type &operator() ( const GeometryType &type ) const
00358 {
00359 assert( type.dim() == 2 );
00360 switch( type.basicType() )
00361 {
00362 case GeometryType :: simplex:
00363 return simplex;
00364
00365 case GeometryType :: cube:
00366 return cube;
00367
00368 case GeometryType :: pyramid:
00369 case GeometryType :: prism:
00370 DUNE_THROW( RangeError, "Invalid geometry type: " << type );
00371
00372 default:
00373 DUNE_THROW( RangeError, "Unknown geometry type: " << type );
00374 }
00375 }
00376 };
00377
00378 template< class ctype >
00379 struct GenericReferenceElementContainer< ctype, 1 >
00380 {
00381 typedef GenericReferenceElement< ctype, 1 > value_type;
00382
00383 private:
00384 value_type line;
00385
00386 GenericReferenceElementContainer ()
00387 {
00388 line.template initialize< GeometryType :: simplex >();
00389 }
00390
00391 public:
00392 const value_type &operator() ( const GeometryType &type ) const
00393 {
00394 assert( type.dim() == 1 );
00395 return line;
00396 }
00397 };
00398
00399 template< class ctype >
00400 struct GenericReferenceElementContainer< ctype, 0 >
00401 {
00402 typedef GenericReferenceElement< ctype, 0 > value_type;
00403
00404 private:
00405 value_type point;
00406
00407 GenericReferenceElementContainer ()
00408 {
00409 point.template initialize< GeometryType :: simplex >();
00410 }
00411
00412 public:
00413 const value_type &operator() ( const GeometryType &type ) const
00414 {
00415 assert( type.dim() == 0 );
00416 return point;
00417 }
00418 };
00419
00420 }
00421
00422 #endif