00001 #ifndef DUNE_GENERICGEOMETRY_TOPOLOGYTYPES_HH
00002 #define DUNE_GENERICGEOMETRY_TOPOLOGYTYPES_HH
00003
00004 #include <string>
00005
00006 #include <dune/common/static_assert.hh>
00007 #include <dune/grid/genericgeometry/misc.hh>
00008
00009 namespace Dune
00010 {
00011
00012 namespace GenericGeometry
00013 {
00014
00015 struct Point
00016 {
00017 static const unsigned int dimension = 0;
00018 static const unsigned int numCorners = 1;
00019
00020 static const unsigned int id = 0;
00021
00022 static std :: string name ()
00023 {
00024 return "p";
00025 }
00026 };
00027
00028
00029 template< class BaseTopology >
00030 struct Prism
00031 {
00032 static const unsigned int dimension = BaseTopology :: dimension + 1;
00033 static const unsigned int numCorners = 2 * BaseTopology :: numCorners;
00034
00035 static const unsigned int id = BaseTopology :: id + (1 << (dimension-1));
00036
00037 static std :: string name ()
00038 {
00039 return BaseTopology :: name() + "l";
00040
00041 }
00042 };
00043
00044
00045 template< class BaseTopology >
00046 struct Pyramid
00047 {
00048 static const unsigned int dimension = BaseTopology :: dimension + 1;
00049 static const unsigned int numCorners = BaseTopology :: numCorners + 1;
00050
00051 static const unsigned int id = BaseTopology :: id;
00052
00053 static std :: string name ()
00054 {
00055 return BaseTopology :: name() + "o";
00056
00057 }
00058 };
00059
00060
00061
00062 template< class Topology >
00063 struct BaseTopology;
00064
00065 template< class Base >
00066 struct BaseTopology< Prism< Base > >
00067 {
00068 typedef Base type;
00069 };
00070
00071 template< class Base >
00072 struct BaseTopology< Pyramid< Base > >
00073 {
00074 typedef Base type;
00075 };
00076
00077
00078
00079 template< class Topology >
00080 struct IsSimplex
00081 {
00082 static const bool value = ((Topology::id >> 1) == 0);
00083 };
00084
00085 template< class Topology >
00086 struct IsCube
00087 {
00088 static const bool value = ((Topology::id | 1) == (1 << Topology::dimension) - 1);
00089 };
00090
00091 template< class Topology >
00092 struct IsHybrid
00093 {
00094 static const bool value
00095 = !(IsSimplex< Topology >::value || IsCube< Topology >::value);
00096 };
00097
00098
00099
00100
00101
00102
00103 template< unsigned int dim >
00104 struct SimplexTopology
00105 {
00106 typedef Pyramid< typename SimplexTopology< dim-1 >::type > type;
00107 };
00108
00109 template<>
00110 struct SimplexTopology< 0 >
00111 {
00112 typedef Point type;
00113 };
00114
00115
00116
00117
00118
00119
00120 template< unsigned int dim >
00121 struct CubeTopology
00122 {
00123 typedef Prism< typename CubeTopology< dim-1 >::type > type;
00124 };
00125
00126 template<>
00127 struct CubeTopology< 0 >
00128 {
00129 typedef Point type;
00130 };
00131
00132
00133
00134
00135
00136
00137 template< unsigned int dim >
00138 struct PyramidTopology
00139 {
00140 typedef Pyramid< typename CubeTopology< dim-1 >::type > type;
00141 };
00142
00143
00144
00145
00146
00147
00148 template< unsigned int dim >
00149 struct PrismTopology
00150 {
00151 typedef Prism< typename SimplexTopology< dim-1 >::type > type;
00152 };
00153
00154
00155
00156
00157
00158
00159 template< unsigned int id, unsigned int dim >
00160 class Topology
00161 {
00162 static const unsigned int dimension = dim;
00163
00164 dune_static_assert( (id < (1 << dimension)), "id too large." );
00165
00166 static const bool isPrism = ((id >> (dimension-1)) != 0);
00167
00168 typedef typename Topology< (id & ~(1 << (dimension-1))), dimension-1 >::type
00169 BaseTopology;
00170
00171 template< bool >
00172 struct Prism
00173 {
00174 typedef GenericGeometry :: Prism< BaseTopology > type;
00175 };
00176
00177 template< bool >
00178 struct Pyramid
00179 {
00180 typedef GenericGeometry :: Pyramid< BaseTopology > type;
00181 };
00182
00183 public:
00184 typedef typename ProtectedIf< isPrism, Prism, Pyramid >::type type;
00185 };
00186
00187 template< unsigned int id >
00188 class Topology< id, 0 >
00189 {
00190 static const unsigned int dimension = 0;
00191
00192 dune_static_assert( (id < (1 << dimension)), "id too large." );
00193
00194 public:
00195 typedef Point type;
00196 };
00197
00198
00199
00200
00201
00202
00203 template< template< class > class Operation, int dim, class Topology = Point >
00204 class IfTopology
00205 {
00206 typedef IfTopology< Operation, dim-1, Prism< Topology > > IfPrism;
00207 typedef IfTopology< Operation, dim-1, Pyramid< Topology > > IfPyramid;
00208
00209 public:
00210 static void apply ( const unsigned int topologyId )
00211 {
00212 if( topologyId & 1 )
00213 IfPrism::apply( topologyId >> 1 );
00214 else
00215 IfPyramid::apply( topologyId >> 1 );
00216 }
00217
00218 template< class T1 >
00219 static void apply ( const unsigned int topologyId, T1 &p1 )
00220 {
00221 if( topologyId & 1 )
00222 IfPrism::apply( topologyId >> 1, p1 );
00223 else
00224 IfPyramid::apply( topologyId >> 1, p1 );
00225 }
00226
00227 template< class T1, class T2 >
00228 static void apply ( const unsigned int topologyId, T1 &p1, T2 &p2 )
00229 {
00230 if( topologyId & 1 )
00231 IfPrism::apply( topologyId >> 1, p1, p2 );
00232 else
00233 IfPyramid::apply( topologyId >> 1, p1, p2 );
00234 }
00235
00236 template< class T1, class T2, class T3 >
00237 static void apply ( const unsigned int topologyId, T1 &p1, T2 &p2, T3 &p3 )
00238 {
00239 if( topologyId & 1 )
00240 IfPrism::apply( topologyId >> 1, p1, p2, p3 );
00241 else
00242 IfPyramid::apply( topologyId >> 1, p1, p2, p3 );
00243 }
00244
00245 template< class T1, class T2, class T3, class T4 >
00246 static void apply ( const unsigned int topologyId, T1 &p1, T2 &p2, T3 &p3, T4 &p4 )
00247 {
00248 if( topologyId & 1 )
00249 IfPrism::apply( topologyId >> 1, p1, p2, p3, p4 );
00250 else
00251 IfPyramid::apply( topologyId >> 1, p1, p2, p3, p4 );
00252 }
00253 };
00254
00255 template< template< class > class Operation, class Topology >
00256 struct IfTopology< Operation, 0, Topology >
00257 {
00258 static void apply ( const unsigned int topologyId )
00259 {
00260 Operation< Topology >::apply();
00261 }
00262
00263 template< class T1 >
00264 static void apply ( const unsigned int topologyId, T1 &p1 )
00265 {
00266 Operation< Topology >::apply( p1 );
00267 }
00268
00269 template< class T1, class T2 >
00270 static void apply ( const unsigned int topologyId, T1 &p1, T2 &p2 )
00271 {
00272 Operation< Topology >::apply( p1, p2 );
00273 }
00274
00275 template< class T1, class T2, class T3 >
00276 static void apply ( const unsigned int topologyId, T1 &p1, T2 &p2, T3 &p3 )
00277 {
00278 Operation< Topology >::apply( p1, p2, p3 );
00279 }
00280
00281 template< class T1, class T2, class T3, class T4 >
00282 static void apply ( const unsigned int topologyId, T1 &p1, T2 &p2, T3 &p3, T4 &p4 )
00283 {
00284 Operation< Topology >::apply( p1, p2, p3, p4 );
00285 }
00286 };
00287
00288 }
00289
00290 }
00291
00292 #endif