referencetopologies.hh
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
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 const GeometryType &type ( unsigned int codim, unsigned int i ) const
00054 {
00055 assert( (codim <= dimension) && (i < info_[ codim ].size()) );
00056 return info_[ codim ][ i ].type();
00057 }
00058
00059 template< class Topology >
00060 void initialize ()
00061 {
00062 typedef Initialize< Topology > Init;
00063 ForLoop< Init::template Codim, 0, dimension >::apply( info_ );
00064 }
00065
00066 private:
00067 std::vector< SubEntityInfo > info_[ dimension+1 ];
00068 };
00069
00070
00071
00072
00073
00074
00075 template< unsigned int dim >
00076 class ReferenceTopology< dim >::SubEntityInfo
00077 {
00078 template< class Topology, unsigned int codim > struct Initialize
00079 {
00080 template< int subcodim > struct SubCodim;
00081 };
00082
00083 public:
00084 unsigned int size ( unsigned int subcodim ) const
00085 {
00086 return numbering_[ subcodim ].size();
00087 }
00088
00089 unsigned int number ( unsigned int subcodim, unsigned int j ) const
00090 {
00091 return numbering_[ subcodim ][ j ];
00092 }
00093
00094 unsigned int topologyId () const
00095 {
00096 return topologyId_;
00097 }
00098
00099 const GeometryType &type () const
00100 {
00101 return type_;
00102 }
00103
00104 template< class Topology, unsigned int codim, unsigned int i >
00105 void initialize ()
00106 {
00107 typedef Initialize< Topology, codim > Init;
00108 typedef typename GenericGeometry::SubTopology< Topology, codim, i >::type SubTopology;
00109
00110 codim_ = codim;
00111 topologyId_ = SubTopology::id;
00112 type_ = DuneGeometryType< SubTopology, GeometryType::simplex >::type();
00113 numbering_.resize( SubTopology::dimension+1 );
00114
00115 const unsigned int iVariable = i;
00116 ForLoop< Init::template SubCodim, 0, SubTopology::dimension >::apply( iVariable, numbering_ );
00117 }
00118
00119 private:
00120 int codim_;
00121 unsigned int topologyId_;
00122 GeometryType type_;
00123 std::vector< std::vector< unsigned int > > numbering_;
00124 };
00125
00126
00127 template< unsigned int dim >
00128 template< class Topology, unsigned int codim >
00129 template< int subcodim >
00130 struct ReferenceTopology< dim >::SubEntityInfo::Initialize< Topology, codim >::SubCodim
00131 {
00132 typedef SubTopologySize< Topology, codim, subcodim > Size;
00133 typedef SubTopologyNumbering< Topology, codim, subcodim > Numbering;
00134
00135 static void
00136 apply ( unsigned int i, std::vector< std::vector< unsigned int > > &numbering )
00137 {
00138 const unsigned int size = Size::size( i );
00139 numbering[ subcodim ].resize( size );
00140 for( unsigned int j = 0; j < size; ++j )
00141 numbering[ subcodim ][ j ] = Numbering::number( i, j );
00142 }
00143 };
00144
00145
00146
00147
00148
00149 template< unsigned int dim >
00150 template< class Topology >
00151 struct ReferenceTopology< dim >::Initialize
00152 {
00153 template< int codim >
00154 struct Codim
00155 {
00156 template< int i >
00157 struct SubTopology
00158 {
00159 static void apply ( std::vector< SubEntityInfo > &info )
00160 {
00161 info[ i ].template initialize< Topology, codim, i >();
00162 }
00163 };
00164
00165 static void apply ( std::vector< SubEntityInfo > (&info)[ dim+1 ] )
00166 {
00167 const unsigned int size = Size< Topology, codim >::value;
00168 info[ codim ].resize( size );
00169 ForLoop< SubTopology, 0, size-1 >::apply( info[ codim ] );
00170 }
00171 };
00172 };
00173
00174
00175
00176
00177
00178 template< unsigned int dim >
00179 class ReferenceTopologies
00180 {
00181 typedef ReferenceTopologies< dim > This;
00182
00183 template< int topologyId >
00184 struct Init;
00185
00186 public:
00187 static const unsigned int dimension = dim;
00188 static const unsigned int numTopologies = (1 << dimension);
00189
00190 typedef GenericGeometry::ReferenceTopology< dimension > ReferenceTopology;
00191
00192 static const ReferenceTopology &get ( const unsigned int topologyId )
00193 {
00194 assert( topologyId < numTopologies );
00195 return instance().refTopology_[ topologyId ];
00196 }
00197
00198 private:
00199 ReferenceTopologies ()
00200 {
00201 ForLoop< Init, 0, numTopologies-1 >::apply( refTopology_ );
00202 }
00203
00204 ReferenceTopologies ( const This & );
00205 This &operator= ( const This & );
00206
00207 static const This &instance ()
00208 {
00209 static This instance;
00210 return instance;
00211 }
00212
00213 ReferenceTopology refTopology_[ numTopologies ];
00214 };
00215
00216
00217 template< unsigned int dim >
00218 template< int topologyId >
00219 struct ReferenceTopologies< dim >::Init
00220 {
00221 static void apply ( ReferenceTopology (&refTopology)[ numTopologies ] )
00222 {
00223 typedef typename GenericGeometry::Topology< topologyId, dimension >::type Topology;
00224 refTopology[ topologyId ].template initialize< Topology >();
00225 }
00226 };
00227
00228 }
00229
00230 }
00231
00232 #endif // #ifndef DUNE_GENERICGEOMETRY_REFERENCETOPOLOGIES_HH