genericreferenceelements.hh

00001 #ifndef DUNE_GENERICREFERENCEELEMENTS_HH
00002 #define DUNE_GENERICREFERENCEELEMENTS_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< CoordTraits, Topology, dim, CornerStorage< Topology >, true > type;
00034       };
00035 
00036       struct Caching
00037       {
00038         static const GenericGeometry::EvaluationType evaluateJacobianTransposed = GenericGeometry::PreCompute;
00039         static const GenericGeometry::EvaluationType evaluateJacobianInverseTransposed = GenericGeometry::PreCompute;
00040         static const GenericGeometry::EvaluationType evaluateIntegrationElement = GenericGeometry::PreCompute;
00041         static const GenericGeometry::EvaluationType evaluateNormal = GenericGeometry::PreCompute;
00042       };
00043     };
00044 
00045   public:
00046     template< int codim >
00047     struct Codim
00048     {
00049       typedef GenericGeometry::HybridMapping< dim-codim, GeometryTraits > Mapping;
00050     };
00051 
00052   private:
00053     template< int codim >
00054     class MappingArray
00055     : public std::vector< typename Codim< codim >::Mapping * >
00056     {};
00057 
00058     typedef GenericGeometry::CodimTable< MappingArray, dim > MappingsTable;
00059 
00060     std::vector< SubEntityInfo > info_[ dim+1 ];
00061     double volume_;
00062     MappingsTable mappings_;
00063 
00064   public:
00065     int size ( int c ) const
00066     {
00067       assert( (c >= 0) && (c <= dim) );
00068       return info_[ c ].size();
00069     }
00070 
00071     int size ( int i, int c, int cc ) const
00072     {
00073       assert( (c >= 0) && (c <= dim) );
00074       return info_[ c ][ i ].size( cc );
00075     }
00076 
00077     int subEntity ( int i, int c, int ii, int cc ) const
00078     {
00079       assert( (c >= 0) && (c <= dim) );
00080       return info_[ c ][ i ].number( ii, cc );
00081     }
00082 
00083     const FieldVector< ctype, dim > &position( int i, int c ) const
00084     {
00085       assert( (c >= 0) && (c <= dim) );
00086       return info_[ c ][ i ].position();
00087     }
00088     
00089     template< int codim >
00090     FieldVector< ctype, dim >
00091     global( const FieldVector< ctype, dim-codim > &local, int i, int c ) const
00092     {
00093       if( c != codim )
00094         DUNE_THROW( Exception, "Local Coordinate Type does not correspond to codimension c." );
00095       assert( c == codim );
00096       return mapping< codim >( i ).global( local );
00097     }
00098 
00099     template< int codim >
00100     FieldVector< ctype, dim >
00101     global( const FieldVector< ctype, dim-codim > &local, int i ) const
00102     {
00103       return mapping< codim >( i ).global( local );
00104     }
00105 
00106     template< int codim >
00107     typename Codim< codim >::Mapping &mapping( int i ) const
00108     {
00109       Int2Type< codim > codimVariable;
00110       return *(mappings_[ codimVariable ][ i ]);
00111     }
00112 
00113     GeometryType type ( int i, int c ) const
00114     {
00115       assert( (c >= 0) && (c <= dim) );
00116       return info_[ c ][ i ].type();
00117     }
00118 
00119     double volume () const
00120     {
00121       return volume_;
00122     }
00123 
00124     template< GeometryType::BasicType geoType >
00125     void initialize ()
00126     {
00127       typedef typename GenericGeometry::Convert< geoType, dim >::type Topology;
00128       typedef Initialize< Topology > Init;
00129       typedef GenericGeometry::VirtualMapping< Topology, GeometryTraits > VirtualMapping;
00130 
00131       Int2Type< 0 > codim0Variable;
00132       mappings_[ codim0Variable ].resize( 1 );
00133       mappings_[ codim0Variable ][ 0 ]  = new VirtualMapping( codim0Variable );
00134 
00135       GenericGeometry::ForLoop< Init::template Codim, 0, dim >::apply( info_, mappings_ );
00136       volume_ = GenericGeometry::ReferenceDomain< Topology >::template volume< double >();
00137     }
00138   };
00139 
00140 
00141   template< class ctype, int dim >
00142   class GenericReferenceElement< ctype, dim >::SubEntityInfo
00143   {
00144     template< class Topology, int codim > struct Initialize
00145     {
00146       template< int subcodim > struct SubCodim;
00147     };
00148 
00149     int codim_;
00150     std :: vector< int > numbering_[ dim+1 ];
00151     FieldVector< ctype, dim > baryCenter_;
00152     GeometryType type_;
00153 
00154   public:
00155     int size ( int cc ) const
00156     {
00157       assert( (cc >= codim_) && (cc <= dim) );
00158       return numbering_[ cc ].size();
00159     }
00160 
00161     int number ( int ii, int cc ) const
00162     {
00163       assert( (cc >= codim_) && (cc <= dim) );
00164       return numbering_[ cc ][ ii ];
00165     }
00166 
00167     const FieldVector< ctype, dim > &position () const
00168     {
00169       return baryCenter_;
00170     }
00171 
00172     GeometryType type () const
00173     {
00174       return type_;
00175     }
00176 
00177     template< class Topology, unsigned int codim, unsigned int i >
00178     void initialize ()
00179     {
00180       typedef Initialize< Topology, codim > Init;
00181       typedef GenericGeometry::ReferenceElement< Topology, ctype > RefElement;
00182 
00183       const unsigned int iVariable = i;
00184       GenericGeometry::ForLoop< Init::template SubCodim, 0, dim-codim >::apply( iVariable, numbering_ );
00185       baryCenter_ = RefElement::template baryCenter< codim >( i );
00186 
00187       typedef typename GenericGeometry::SubTopology< Topology, codim, i >::type SubTopology;
00188       type_ = GenericGeometry::DuneGeometryType< SubTopology, GeometryType::simplex >::type();
00189     }
00190   };
00191 
00192 
00193   template< class ctype, int dim >
00194   template< class Topology >
00195   class GenericReferenceElement< ctype, dim >::CornerStorage
00196   {
00197     typedef GenericGeometry::ReferenceElement< Topology, ctype > RefElement;
00198 
00199   public:
00200     static const unsigned int size = Topology::numCorners;
00201 
00202     template< class SubTopology >
00203     struct SubStorage
00204     {
00205       typedef CornerStorage< SubTopology > type;
00206     };
00207 
00208     explicit CornerStorage ( const Int2Type< 0 > & )
00209     {
00210       for( unsigned int i = 0; i < size; ++i )
00211         coords_[ i ] = RefElement::corner( i );
00212     }
00213 
00214     template< class Mapping, unsigned int codim >
00215     explicit
00216     CornerStorage ( const GenericGeometry::SubMappingCoords< Mapping, codim > &coords )
00217     {
00218       for( unsigned int i = 0; i < size; ++i )
00219         coords_[ i ] = coords[ i ];
00220     }
00221 
00222     const FieldVector< ctype, dim > &operator[] ( unsigned int i ) const
00223     {
00224       return coords_[ i ];
00225     }
00226 
00227   private:
00228     FieldVector< ctype, dim > coords_[ size ];
00229   };
00230 
00231 
00232   template< class ctype, int dim >
00233   template< class Topology, int codim >
00234   template< int subcodim >
00235   struct GenericReferenceElement< ctype, dim >::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         numbering[ codim+subcodim ][ j ] = RefElement::template subNumbering< codim, subcodim >( i, j );
00245     }
00246   };
00247 
00248 
00249   template< class ctype, int dim >
00250   template< class Topology >
00251   struct GenericReferenceElement< ctype, dim >::Initialize
00252   {
00253     typedef Dune::GenericReferenceElement< ctype, dim > GenericReferenceElement;
00254 
00255     typedef typename GenericReferenceElement::template Codim< 0 >::Mapping ReferenceMapping;
00256 
00257     template< int codim >
00258     struct Codim
00259     {
00260       template< int i >
00261       struct SubTopology
00262       {
00263         static void apply ( std::vector< SubEntityInfo > &info )
00264         {
00265           info[ i ].template initialize< Topology, codim, i >();
00266         }
00267       };
00268 
00269       static void apply ( std::vector< SubEntityInfo > (&info)[ dim+1 ],
00270                           MappingsTable &mappings )
00271       {
00272         const unsigned int size = GenericGeometry::Size< Topology, codim >::value;
00273         info[ codim ].resize( size );
00274         GenericGeometry::ForLoop< SubTopology, 0, size-1 >::apply( info[ codim ] );
00275         /*
00276         for( unsigned int i = 0; i < size; ++i )
00277           info[ codim ][ i ].template initialize< Topology, codim >( i );
00278         */
00279 
00280         if( codim > 0 )
00281         {
00282           Int2Type< 0 > codim0Variable;
00283           const ReferenceMapping &refMapping = *(mappings[ codim0Variable ][ 0 ]);
00284 
00285           Int2Type< codim > codimVariable;
00286           mappings[ codimVariable ].resize( size );
00287           for( unsigned int i = 0; i < size; ++i )
00288             mappings[ codimVariable ][ i ] = refMapping.template trace< codim >( i );
00289         }
00290       }
00291     };
00292   };
00293 
00294 
00295 
00296   // GenericReferenceElementContainer
00297   // --------------------------------
00298 
00299   template< class ctype, int dim >
00300   struct GenericReferenceElementContainer
00301   {
00302     typedef GenericReferenceElement< ctype, dim > value_type;
00303 
00304     const value_type &operator() ( const GeometryType &type ) const
00305     {
00306       assert( type.dim() == dim );
00307       switch( type.basicType() )
00308       {
00309       case GeometryType::simplex:
00310         return simplex_;
00311 
00312       case GeometryType::cube:
00313         return cube_;
00314         
00315       case GeometryType::pyramid:
00316         return pyramid_;
00317         
00318       case GeometryType::prism:
00319         return prism_;
00320         
00321       default:
00322         DUNE_THROW( RangeError, "Unknown geometry type: " << type );
00323       }
00324     }
00325 
00326     const value_type &simplex () const
00327     {
00328       return simplex_;
00329     }
00330 
00331     const value_type &cube () const
00332     {
00333       return cube_;
00334     }
00335 
00336     static const GenericReferenceElementContainer &instance ()
00337     {
00338       static GenericReferenceElementContainer inst;
00339       return inst;
00340     }
00341     
00342   private:
00343     GenericReferenceElementContainer ()
00344     {
00345       simplex_.template initialize< GeometryType::simplex >();
00346       cube_.template initialize< GeometryType::cube >();
00347       pyramid_.template initialize< GeometryType::pyramid >();
00348       prism_.template initialize< GeometryType::prism >();
00349     }
00350     
00351     value_type simplex_;
00352     value_type cube_;
00353     value_type pyramid_;
00354     value_type prism_;
00355   };
00356 
00357   template< class ctype >
00358   struct GenericReferenceElementContainer< ctype, 2 >
00359   {
00360     typedef GenericReferenceElement< ctype, 2 > value_type;
00361 
00362     const value_type &operator() ( const GeometryType &type ) const
00363     {
00364       assert( type.dim() == 2 );
00365       switch( type.basicType() )
00366       {
00367       case GeometryType::simplex:
00368         return simplex_;
00369 
00370       case GeometryType::cube:
00371         return cube_;
00372         
00373       case GeometryType::pyramid:
00374       case GeometryType::prism:
00375         DUNE_THROW( RangeError, "Invalid geometry type: " << type );
00376         
00377       default:
00378         DUNE_THROW( RangeError, "Unknown geometry type: " << type );
00379       }
00380     }
00381 
00382     const value_type &simplex () const
00383     {
00384       return simplex_;
00385     }
00386 
00387     const value_type &cube () const
00388     {
00389       return cube_;
00390     }
00391 
00392     static const GenericReferenceElementContainer &instance ()
00393     {
00394       static GenericReferenceElementContainer inst;
00395       return inst;
00396     }
00397     
00398   private:
00399     GenericReferenceElementContainer ()
00400     {
00401       simplex_.template initialize< GeometryType::simplex >();
00402       cube_.template initialize< GeometryType::cube >();
00403     }
00404     
00405     value_type simplex_;
00406     value_type cube_;
00407   };
00408   
00409   template< class ctype >
00410   struct GenericReferenceElementContainer< ctype, 1 >
00411   {
00412     typedef GenericReferenceElement< ctype, 1 > value_type;
00413     
00414     const value_type &operator() ( const GeometryType &type ) const
00415     {
00416       assert( type.dim() == 1 );
00417       return line_;
00418     }
00419 
00420     const value_type &simplex () const
00421     {
00422       return line_;
00423     }
00424 
00425     const value_type &cube () const
00426     {
00427       return line_;
00428     }
00429 
00430     static const GenericReferenceElementContainer &instance ()
00431     {
00432       static GenericReferenceElementContainer inst;
00433       return inst;
00434     }
00435     
00436   private:
00437     GenericReferenceElementContainer ()
00438     {
00439       line_.template initialize< GeometryType::simplex >();
00440     }
00441     
00442     value_type line_;
00443   };
00444   
00445   template< class ctype >
00446   struct GenericReferenceElementContainer< ctype, 0 >
00447   {
00448     typedef GenericReferenceElement< ctype, 0 > value_type;
00449 
00450     const value_type &operator() ( const GeometryType &type ) const
00451     {
00452       assert( type.dim() == 0 );
00453       return point_;
00454     }
00455 
00456     const value_type &simplex () const
00457     {
00458       return point_;
00459     }
00460 
00461     const value_type &cube () const
00462     {
00463       return point_;
00464     }
00465 
00466     static
00467     const GenericReferenceElementContainer & instance()
00468     {
00469       static GenericReferenceElementContainer inst;
00470       return inst;
00471     }
00472     
00473   private:
00474     GenericReferenceElementContainer ()
00475     {
00476       point_.template initialize< GeometryType::simplex >();
00477     }
00478     
00479     value_type point_;
00480   };
00481 
00482 
00483 
00484   // GenericReferenceElements
00485   // ------------------------
00486 
00487   template< class ctype, int dim >
00488   struct GenericReferenceElements
00489   {
00490     static const GenericReferenceElement< ctype, dim > &
00491     general ( const GeometryType &type )
00492     {
00493       return GenericReferenceElementContainer< ctype, dim >::instance()( type );
00494     }
00495 
00496     static const GenericReferenceElement< ctype, dim > &simplex ()
00497     {
00498       return GenericReferenceElementContainer< ctype, dim >::instance().simplex();
00499     }
00500 
00501     static const GenericReferenceElement< ctype, dim > &cube ()
00502     {
00503       return GenericReferenceElementContainer< ctype, dim >::instance().cube();
00504     }
00505   };
00506 
00507 }
00508 
00509 #endif

Generated on Tue Jul 28 22:28:16 2009 for dune-grid by  doxygen 1.5.6