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 
00023   template< class ctype, int dim >
00024   class GenericReferenceElement
00025   {
00026     typedef GenericReferenceElement< ctype, dim > This;
00027 
00028     class SubEntityInfo;
00029     template< class Topology > class CornerStorage;
00030     template< class Topology > struct Initialize;
00031 
00032     struct GeometryTraits
00033       : public GenericGeometry::DefaultGeometryTraits< ctype, dim, dim >
00034     {
00035       typedef GenericGeometry::DefaultGeometryTraits< ctype, dim, dim > Base;
00036 
00037       typedef typename Base::CoordTraits CoordTraits;
00038 
00039       template< class Topology >
00040       struct Mapping
00041       {
00042         typedef GenericGeometry::CornerMapping< CoordTraits, Topology, dim, CornerStorage< Topology >, true > type;
00043       };
00044 
00045       struct Caching
00046       {
00047         static const GenericGeometry::EvaluationType evaluateJacobianTransposed = GenericGeometry::PreCompute;
00048         static const GenericGeometry::EvaluationType evaluateJacobianInverseTransposed = GenericGeometry::PreCompute;
00049         static const GenericGeometry::EvaluationType evaluateIntegrationElement = GenericGeometry::PreCompute;
00050         static const GenericGeometry::EvaluationType evaluateNormal = GenericGeometry::PreCompute;
00051       };
00052     };
00053 
00054   public:
00056     template< int codim >
00057     struct Codim
00058     {
00060       typedef GenericGeometry::HybridMapping< dim-codim, GeometryTraits > Mapping;
00061     };
00062 
00063   private:
00064     template< int codim >
00065     class MappingArray
00066     : public std::vector< typename Codim< codim >::Mapping * >
00067     {};
00068 
00069     typedef GenericGeometry::CodimTable< MappingArray, dim > MappingsTable;
00070 
00071     std::vector< SubEntityInfo > info_[ dim+1 ];
00072     double volume_;
00073     MappingsTable mappings_;
00074 
00075   public:
00080     int size ( int c ) const
00081     {
00082       assert( (c >= 0) && (c <= dim) );
00083       return info_[ c ].size();
00084     }
00085 
00097     int size ( int i, int c, int cc ) const
00098     {
00099       assert( (c >= 0) && (c <= dim) );
00100       return info_[ c ][ i ].size( cc );
00101     }
00102 
00116     int subEntity ( int i, int c, int ii, int cc ) const
00117     {
00118       assert( (c >= 0) && (c <= dim) );
00119       return info_[ c ][ i ].number( ii, cc );
00120     }
00121 
00131     const FieldVector< ctype, dim > &position( int i, int c ) const
00132     {
00133       assert( (c >= 0) && (c <= dim) );
00134       return info_[ c ][ i ].position();
00135     }
00136     
00150     template< int codim >
00151     bool checkInside ( const FieldVector< ctype, dim-codim > &local, int i ) const
00152     {
00153       return mapping< codim >( i ).checkInside( local );
00154     }
00155 
00163     bool checkInside ( const FieldVector< ctype, dim > &local ) const
00164     {
00165       return checkInside< 0 >( local, 0 );
00166     }
00167 
00168 
00185     template< int codim >
00186     FieldVector< ctype, dim >
00187     global( const FieldVector< ctype, dim-codim > &local, int i, int c ) const
00188     {
00189       if( c != codim )
00190         DUNE_THROW( Exception, "Local Coordinate Type does not correspond to codimension c." );
00191       assert( c == codim );
00192       return mapping< codim >( i ).global( local );
00193     }
00194 
00208     template< int codim >
00209     FieldVector< ctype, dim >
00210     global( const FieldVector< ctype, dim-codim > &local, int i ) const
00211     {
00212       return mapping< codim >( i ).global( local );
00213     }
00214 
00230     template< int codim >
00231     typename Codim< codim >::Mapping &mapping( int i ) const
00232     {
00233       Int2Type< codim > codimVariable;
00234       return *(mappings_[ codimVariable ][ i ]);
00235     }
00236 
00245     GeometryType type ( int i, int c ) const
00246     {
00247       assert( (c >= 0) && (c <= dim) );
00248       return info_[ c ][ i ].type();
00249     }
00250 
00252     double volume () const
00253     {
00254       return volume_;
00255     }
00256 
00263     template< GeometryType::BasicType geoType >
00264     void initialize ()
00265     {
00266       typedef typename GenericGeometry::Convert< geoType, dim >::type Topology;
00267       typedef Initialize< Topology > Init;
00268       typedef GenericGeometry::VirtualMapping< Topology, GeometryTraits > VirtualMapping;
00269 
00270       Int2Type< 0 > codim0Variable;
00271       mappings_[ codim0Variable ].resize( 1 );
00272       mappings_[ codim0Variable ][ 0 ]  = new VirtualMapping( codim0Variable );
00273 
00274       GenericGeometry::ForLoop< Init::template Codim, 0, dim >::apply( info_, mappings_ );
00275       volume_ = GenericGeometry::ReferenceDomain< Topology >::template volume< double >();
00276     }
00277   };
00278 
00279 
00280   template< class ctype, int dim >
00281   class GenericReferenceElement< ctype, dim >::SubEntityInfo
00282   {
00283     template< class Topology, int codim > struct Initialize
00284     {
00285       template< int subcodim > struct SubCodim;
00286     };
00287 
00288     int codim_;
00289     std::vector< int > numbering_[ dim+1 ];
00290     FieldVector< ctype, dim > baryCenter_;
00291     GeometryType type_;
00292 
00293   public:
00294     int size ( int cc ) const
00295     {
00296       assert( (cc >= codim_) && (cc <= dim) );
00297       return numbering_[ cc ].size();
00298     }
00299 
00300     int number ( int ii, int cc ) const
00301     {
00302       assert( (cc >= codim_) && (cc <= dim) );
00303       return numbering_[ cc ][ ii ];
00304     }
00305 
00306     const FieldVector< ctype, dim > &position () const
00307     {
00308       return baryCenter_;
00309     }
00310 
00311     GeometryType type () const
00312     {
00313       return type_;
00314     }
00315 
00316     template< class Topology, unsigned int codim, unsigned int i >
00317     void initialize ()
00318     {
00319       typedef Initialize< Topology, codim > Init;
00320       typedef GenericGeometry::ReferenceElement< Topology, ctype > RefElement;
00321 
00322       codim_ = codim;
00323 
00324       const unsigned int iVariable = i;
00325       GenericGeometry::ForLoop< Init::template SubCodim, 0, dim-codim >::apply( iVariable, numbering_ );
00326 
00327       baryCenter_ = RefElement::template baryCenter< codim >( i );
00328 
00329       typedef typename GenericGeometry::SubTopology< Topology, codim, i >::type SubTopology;
00330       type_ = GenericGeometry::DuneGeometryType< SubTopology, GeometryType::simplex >::type();
00331     }
00332   };
00333 
00334 
00335   template< class ctype, int dim >
00336   template< class Topology >
00337   class GenericReferenceElement< ctype, dim >::CornerStorage
00338   {
00339     typedef GenericGeometry::ReferenceElement< Topology, ctype > RefElement;
00340 
00341   public:
00342     static const unsigned int size = Topology::numCorners;
00343 
00344     template< class SubTopology >
00345     struct SubStorage
00346     {
00347       typedef CornerStorage< SubTopology > type;
00348     };
00349 
00350     explicit CornerStorage ( const Int2Type< 0 > & )
00351     {
00352       for( unsigned int i = 0; i < size; ++i )
00353         coords_[ i ] = RefElement::corner( i );
00354     }
00355 
00356     template< class Mapping, unsigned int codim >
00357     explicit
00358     CornerStorage ( const GenericGeometry::SubMappingCoords< Mapping, codim > &coords )
00359     {
00360       for( unsigned int i = 0; i < size; ++i )
00361         coords_[ i ] = coords[ i ];
00362     }
00363 
00364     const FieldVector< ctype, dim > &operator[] ( unsigned int i ) const
00365     {
00366       return coords_[ i ];
00367     }
00368 
00369   private:
00370     FieldVector< ctype, dim > coords_[ size ];
00371   };
00372 
00373 
00374   template< class ctype, int dim >
00375   template< class Topology, int codim >
00376   template< int subcodim >
00377   struct GenericReferenceElement< ctype, dim >::SubEntityInfo::Initialize< Topology, codim >::SubCodim
00378   {
00379     typedef GenericGeometry::ReferenceElement< Topology, ctype > RefElement;
00380     
00381     static void apply ( unsigned int i, std::vector< int > (&numbering)[ dim+1 ] )
00382     {
00383       const unsigned int size = RefElement::template size< codim, subcodim >( i );
00384       numbering[ codim+subcodim ].resize( size );
00385       for( unsigned int j = 0; j < size; ++j )
00386         numbering[ codim+subcodim ][ j ] = RefElement::template subNumbering< codim, subcodim >( i, j );
00387     }
00388   };
00389 
00390 
00391   template< class ctype, int dim >
00392   template< class Topology >
00393   struct GenericReferenceElement< ctype, dim >::Initialize
00394   {
00395     typedef Dune::GenericReferenceElement< ctype, dim > GenericReferenceElement;
00396 
00397     typedef typename GenericReferenceElement::template Codim< 0 >::Mapping ReferenceMapping;
00398 
00399     template< int codim >
00400     struct Codim
00401     {
00402       template< int i >
00403       struct SubTopology
00404       {
00405         static void apply ( std::vector< SubEntityInfo > &info )
00406         {
00407           info[ i ].template initialize< Topology, codim, i >();
00408         }
00409       };
00410 
00411       static void apply ( std::vector< SubEntityInfo > (&info)[ dim+1 ],
00412                           MappingsTable &mappings )
00413       {
00414         const unsigned int size = GenericGeometry::Size< Topology, codim >::value;
00415         info[ codim ].resize( size );
00416         GenericGeometry::ForLoop< SubTopology, 0, size-1 >::apply( info[ codim ] );
00417         /*
00418         for( unsigned int i = 0; i < size; ++i )
00419           info[ codim ][ i ].template initialize< Topology, codim >( i );
00420         */
00421 
00422         if( codim > 0 )
00423         {
00424           Int2Type< 0 > codim0Variable;
00425           const ReferenceMapping &refMapping = *(mappings[ codim0Variable ][ 0 ]);
00426 
00427           Int2Type< codim > codimVariable;
00428           mappings[ codimVariable ].resize( size );
00429           for( unsigned int i = 0; i < size; ++i )
00430             mappings[ codimVariable ][ i ] = refMapping.template trace< codim >( i );
00431         }
00432       }
00433     };
00434   };
00435 
00436 
00437 
00438   // GenericReferenceElementContainer
00439   // --------------------------------
00440 
00441   template< class ctype, int dim >
00442   struct GenericReferenceElementContainer
00443   {
00444     typedef GenericReferenceElement< ctype, dim > value_type;
00445 
00446     const value_type &operator() ( const GeometryType &type ) const
00447     {
00448       assert( type.dim() == dim );
00449       switch( type.basicType() )
00450       {
00451       case GeometryType::simplex:
00452         return simplex_;
00453 
00454       case GeometryType::cube:
00455         return cube_;
00456         
00457       case GeometryType::pyramid:
00458         return pyramid_;
00459         
00460       case GeometryType::prism:
00461         return prism_;
00462         
00463       default:
00464         DUNE_THROW( RangeError, "Unknown geometry type: " << type );
00465       }
00466     }
00467 
00468     const value_type &simplex () const
00469     {
00470       return simplex_;
00471     }
00472 
00473     const value_type &cube () const
00474     {
00475       return cube_;
00476     }
00477 
00478     static const GenericReferenceElementContainer &instance ()
00479     {
00480       static GenericReferenceElementContainer inst;
00481       return inst;
00482     }
00483     
00484   private:
00485     GenericReferenceElementContainer ()
00486     {
00487       simplex_.template initialize< GeometryType::simplex >();
00488       cube_.template initialize< GeometryType::cube >();
00489       pyramid_.template initialize< GeometryType::pyramid >();
00490       prism_.template initialize< GeometryType::prism >();
00491     }
00492     
00493     value_type simplex_;
00494     value_type cube_;
00495     value_type pyramid_;
00496     value_type prism_;
00497   };
00498 
00499   template< class ctype >
00500   struct GenericReferenceElementContainer< ctype, 2 >
00501   {
00502     typedef GenericReferenceElement< ctype, 2 > value_type;
00503 
00504     const value_type &operator() ( const GeometryType &type ) const
00505     {
00506       assert( type.dim() == 2 );
00507       switch( type.basicType() )
00508       {
00509       case GeometryType::simplex:
00510         return simplex_;
00511 
00512       case GeometryType::cube:
00513         return cube_;
00514         
00515       case GeometryType::pyramid:
00516       case GeometryType::prism:
00517         DUNE_THROW( RangeError, "Invalid geometry type: " << type );
00518         
00519       default:
00520         DUNE_THROW( RangeError, "Unknown geometry type: " << type );
00521       }
00522     }
00523 
00524     const value_type &simplex () const
00525     {
00526       return simplex_;
00527     }
00528 
00529     const value_type &cube () const
00530     {
00531       return cube_;
00532     }
00533 
00534     static const GenericReferenceElementContainer &instance ()
00535     {
00536       static GenericReferenceElementContainer inst;
00537       return inst;
00538     }
00539     
00540   private:
00541     GenericReferenceElementContainer ()
00542     {
00543       simplex_.template initialize< GeometryType::simplex >();
00544       cube_.template initialize< GeometryType::cube >();
00545     }
00546     
00547     value_type simplex_;
00548     value_type cube_;
00549   };
00550   
00551   template< class ctype >
00552   struct GenericReferenceElementContainer< ctype, 1 >
00553   {
00554     typedef GenericReferenceElement< ctype, 1 > value_type;
00555     
00556     const value_type &operator() ( const GeometryType &type ) const
00557     {
00558       assert( type.dim() == 1 );
00559       return line_;
00560     }
00561 
00562     const value_type &simplex () const
00563     {
00564       return line_;
00565     }
00566 
00567     const value_type &cube () const
00568     {
00569       return line_;
00570     }
00571 
00572     static const GenericReferenceElementContainer &instance ()
00573     {
00574       static GenericReferenceElementContainer inst;
00575       return inst;
00576     }
00577     
00578   private:
00579     GenericReferenceElementContainer ()
00580     {
00581       line_.template initialize< GeometryType::simplex >();
00582     }
00583     
00584     value_type line_;
00585   };
00586   
00587   template< class ctype >
00588   struct GenericReferenceElementContainer< ctype, 0 >
00589   {
00590     typedef GenericReferenceElement< ctype, 0 > value_type;
00591 
00592     const value_type &operator() ( const GeometryType &type ) const
00593     {
00594       assert( type.dim() == 0 );
00595       return point_;
00596     }
00597 
00598     const value_type &simplex () const
00599     {
00600       return point_;
00601     }
00602 
00603     const value_type &cube () const
00604     {
00605       return point_;
00606     }
00607 
00608     static
00609     const GenericReferenceElementContainer & instance()
00610     {
00611       static GenericReferenceElementContainer inst;
00612       return inst;
00613     }
00614     
00615   private:
00616     GenericReferenceElementContainer ()
00617     {
00618       point_.template initialize< GeometryType::simplex >();
00619     }
00620     
00621     value_type point_;
00622   };
00623 
00624 
00625 
00626   // GenericReferenceElements
00627   // ------------------------
00628 
00629   template< class ctype, int dim >
00630   struct GenericReferenceElements
00631   {
00632     static const GenericReferenceElement< ctype, dim > &
00633     general ( const GeometryType &type )
00634     {
00635       return GenericReferenceElementContainer< ctype, dim >::instance()( type );
00636     }
00637 
00638     static const GenericReferenceElement< ctype, dim > &simplex ()
00639     {
00640       return GenericReferenceElementContainer< ctype, dim >::instance().simplex();
00641     }
00642 
00643     static const GenericReferenceElement< ctype, dim > &cube ()
00644     {
00645       return GenericReferenceElementContainer< ctype, dim >::instance().cube();
00646     }
00647   };
00648 
00649 }
00650 
00651 #endif

Generated on Sun Nov 15 22:28:40 2009 for dune-grid by  doxygen 1.5.6