dune-grid  2.1.1
referencetopologies.hh
Go to the documentation of this file.
00001 #ifndef DUNE_GENERICGEOMETRY_REFERENCETOPOLOGIES_HH
00002 #define DUNE_GENERICGEOMETRY_REFERENCETOPOLOGIES_HH
00003 
00004 #include <dune/grid/genericgeometry/conversion.hh>
00005 #include <dune/grid/genericgeometry/subtopologies.hh>
00006 
00007 namespace Dune
00008 {
00009 
00010   namespace GenericGeometry
00011   {
00012 
00013     // ReferenceTopology
00014     // -----------------
00015 
00016     template< unsigned int dim >
00017     class ReferenceTopology
00018     {
00019       typedef ReferenceTopology< dim > This;
00020 
00021       class SubEntityInfo;
00022       template< class Topology > struct Initialize;
00023 
00024     public:
00025       static const unsigned int dimension = dim;
00026 
00027       unsigned int size ( unsigned int codim ) const
00028       {
00029         assert( codim <= dimension );
00030         return info_[ codim ].size();
00031       }
00032 
00033       unsigned int
00034       size ( unsigned int codim, unsigned int i, unsigned int subcodim ) const
00035       {
00036         assert( (codim <= dimension) && (i < info_[ codim ].size()) );
00037         return info_[ codim ][ i ].size( subcodim );
00038       }
00039 
00040       unsigned int subEntity ( unsigned int codim, unsigned int i,
00041                                unsigned int subcodim, unsigned int j ) const
00042       {
00043         assert( (codim <= dimension) && (i < info_[ codim ].size()) );
00044         return info_[ codim ][ i ].number( subcodim, j );
00045       }
00046 
00047       unsigned int topologyId ( unsigned int codim, unsigned int i ) const
00048       {
00049         assert( (codim <= dimension) && (i < info_[ codim ].size()) );
00050         return info_[ codim ][ i ].topologyId();
00051       }
00052 
00053       template< class Topology >
00054       void initialize ()
00055       {
00056         typedef Initialize< Topology > Init;
00057         ForLoop< Init::template Codim, 0, dimension >::apply( info_ );
00058       }
00059 
00060     private:
00061       std::vector< SubEntityInfo > info_[ dimension+1 ];
00062     };
00063 
00064 
00065 
00066     // ReferenceTopology::SubEntityInfo
00067     // --------------------------------
00068 
00069     template< unsigned int dim >
00070     class ReferenceTopology< dim >::SubEntityInfo
00071     {
00072       template< class Topology, unsigned int codim > struct Initialize
00073       {
00074         template< int subcodim > struct SubCodim;
00075       };
00076 
00077     public:
00078       unsigned int size ( unsigned int subcodim ) const
00079       {
00080         return numbering_[ subcodim ].size();
00081       }
00082 
00083       unsigned int number ( unsigned int subcodim, unsigned int j ) const
00084       {
00085         return numbering_[ subcodim ][ j ];
00086       }
00087 
00088       unsigned int topologyId () const
00089       {
00090         return topologyId_;
00091       }
00092 
00093       template< class Topology, unsigned int codim, unsigned int i >
00094       void initialize ()
00095       {
00096         typedef Initialize< Topology, codim > Init;
00097         typedef typename GenericGeometry::SubTopology< Topology, codim, i >::type SubTopology;
00098 
00099         codim_ = codim;
00100         topologyId_ = SubTopology::id;
00101         numbering_.resize( SubTopology::dimension+1 );
00102 
00103         const unsigned int iVariable = i;
00104         ForLoop< Init::template SubCodim, 0, SubTopology::dimension >::apply( iVariable, numbering_ );
00105       }
00106 
00107     private:
00108       int codim_;
00109       unsigned int topologyId_;
00110       std::vector< std::vector< unsigned int > > numbering_;
00111     };
00112 
00113 
00114     template< unsigned int dim >
00115     template< class Topology, unsigned int codim >
00116     template< int subcodim >
00117     struct ReferenceTopology< dim >::SubEntityInfo::Initialize< Topology, codim >::SubCodim
00118     {
00119       typedef SubTopologySize< Topology, codim, subcodim > Size;
00120       typedef SubTopologyNumbering< Topology, codim, subcodim > Numbering;
00121 
00122       static void
00123       apply ( unsigned int i, std::vector< std::vector< unsigned int > > &numbering )
00124       {
00125         const unsigned int size = Size::size( i );
00126         numbering[ subcodim ].resize( size );
00127         for( unsigned int j = 0; j < size; ++j )
00128           numbering[ subcodim ][ j ] = Numbering::number( i, j );
00129       }
00130     };
00131 
00132 
00133     // ReferenceTopology::Initialize
00134     // -----------------------------
00135 
00136     template< unsigned int dim >
00137     template< class Topology >
00138     struct ReferenceTopology< dim >::Initialize
00139     {
00140       template< int codim >
00141       struct Codim
00142       {
00143         template< int i >
00144         struct SubTopology
00145         {
00146           static void apply ( std::vector< SubEntityInfo > &info )
00147           {
00148             info[ i ].template initialize< Topology, codim, i >();
00149           }
00150         };
00151 
00152         static void apply ( std::vector< SubEntityInfo > (&info)[ dim+1 ] )
00153         {
00154           const unsigned int size = Size< Topology, codim >::value;
00155           info[ codim ].resize( size );
00156           ForLoop< SubTopology, 0, size-1 >::apply( info[ codim ] );
00157         }
00158       };
00159     };
00160 
00161 
00162     // ReferenceTopologyContainer
00163     // --------------------------
00164 
00165     template< unsigned int dim >
00166     class ReferenceTopologies
00167     {
00168       typedef ReferenceTopologies< dim > This;
00169 
00170       template< int topologyId >
00171       struct Init;
00172 
00173     public:
00174       static const unsigned int dimension = dim;
00175       static const unsigned int numTopologies = (1 << dimension);
00176 
00177       typedef GenericGeometry::ReferenceTopology< dimension > ReferenceTopology;
00178 
00179       static const ReferenceTopology &get ( const unsigned int topologyId )
00180       {
00181         assert( topologyId < numTopologies );
00182         return instance().refTopology_[ topologyId ];
00183       }
00184 
00185     private:
00186       ReferenceTopologies ()
00187       {
00188         ForLoop< Init, 0, numTopologies-1 >::apply( refTopology_ );
00189       }
00190 
00191       ReferenceTopologies ( const This & );
00192       This &operator= ( const This & );
00193 
00194       static const This &instance ()
00195       {
00196         static This instance;
00197         return instance;
00198       }
00199 
00200       ReferenceTopology refTopology_[ numTopologies ];
00201     };
00202 
00203 
00204     template< unsigned int dim >
00205     template< int topologyId >
00206     struct ReferenceTopologies< dim >::Init
00207     {
00208       static void apply ( ReferenceTopology (&refTopology)[ numTopologies ] )
00209       {
00210         typedef typename GenericGeometry::Topology< topologyId, dimension >::type Topology;
00211         refTopology[ topologyId ].template initialize< Topology >();
00212       }
00213     };
00214 
00215   }
00216 
00217 }
00218 
00219 #endif // #ifndef DUNE_GENERICGEOMETRY_REFERENCETOPOLOGIES_HH