genericreferenceelement.hh

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   // GenericReferenceElement
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   // GenericReferenceElementContainer
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

Generated on Thu Apr 2 10:40:39 2009 for dune-grid by  doxygen 1.5.6