dune-geometry  2.2.0
topologytypes.hh
Go to the documentation of this file.
00001 #ifndef DUNE_GEOMETRY_GENERICGEOMETRY_TOPOLOGYTYPES_HH
00002 #define DUNE_GEOMETRY_GENERICGEOMETRY_TOPOLOGYTYPES_HH
00003 
00004 #include <string>
00005 
00006 #include <dune/common/static_assert.hh>
00007 #include <dune/common/typetraits.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         // return BaseTopology :: name() + "'";
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         // return BaseTopology :: name() + "°";
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     template< class Topology >
00099     struct IsGeneralizedPrism
00100     {
00101       static const bool value = false;
00102     };
00103 
00104     template< class BaseTopology >
00105     struct IsGeneralizedPrism< Prism< BaseTopology > >
00106     {
00107       static const bool value
00108         = (IsGeneralizedPrism< BaseTopology >::value || IsSimplex< BaseTopology >::value);
00109     };
00110 
00111 
00112 
00113     // SimplexTopology
00114     // ---------------
00115 
00116     template< unsigned int dim >
00117     struct SimplexTopology
00118     {
00119       typedef Pyramid< typename SimplexTopology< dim-1 >::type > type;
00120     };
00121 
00122     template<>
00123     struct SimplexTopology< 0 >
00124     {
00125       typedef Point type;
00126     };
00127 
00128 
00129 
00130     // CubeTopology
00131     // ------------
00132 
00133     template< unsigned int dim >
00134     struct CubeTopology
00135     {
00136       typedef Prism< typename CubeTopology< dim-1 >::type > type;
00137     };
00138 
00139     template<>
00140     struct CubeTopology< 0 >
00141     {
00142       typedef Point type;
00143     };
00144 
00145 
00146 
00147     // PyramidTopoogy
00148     // --------------
00149 
00150     template< unsigned int dim >
00151     struct PyramidTopology
00152     {
00153       typedef Pyramid< typename CubeTopology< dim-1 >::type > type;
00154     };
00155 
00156 
00157 
00158     // PrismTopoogy
00159     // --------------
00160 
00161     template< unsigned int dim >
00162     struct PrismTopology
00163     {
00164       typedef Prism< typename SimplexTopology< dim-1 >::type > type;
00165     };
00166 
00167 
00168 
00169     // Topology
00170     // --------
00171 
00172     template< unsigned int id, unsigned int dim >
00173     class Topology
00174     {
00175       static const unsigned int dimension = dim;
00176       
00177       dune_static_assert( (id < (1 << dimension)), "id too large." );
00178 
00179       static const bool isPrism = ((id >> (dimension-1)) != 0);
00180 
00181       typedef typename Topology< (id & ~(1 << (dimension-1))), dimension-1 >::type
00182         BaseTopology;
00183 
00184       template< bool >
00185       struct Prism
00186       {
00187         typedef GenericGeometry :: Prism< BaseTopology > type;
00188       };
00189 
00190       template< bool >
00191       struct Pyramid
00192       {
00193         typedef GenericGeometry :: Pyramid< BaseTopology > type;
00194       };
00195 
00196     public:
00197       typedef typename SelectType< isPrism, Prism<true>, Pyramid<false> >::Type::type type;
00198     };
00199 
00200     template< unsigned int id >
00201     class Topology< id, 0 >
00202     {
00203       static const unsigned int dimension = 0;
00204 
00205       dune_static_assert( (id < (1 << dimension)), "id too large." );
00206 
00207     public:
00208       typedef Point type;
00209     };
00210 
00211 
00212 
00213     // IfTopology
00214     // ----------
00215       
00216     template< template< class > class Operation, int dim, class Topology = Point >
00217     class IfTopology
00218     {
00219       typedef IfTopology< Operation, dim-1, Prism< Topology > > IfPrism;
00220       typedef IfTopology< Operation, dim-1, Pyramid< Topology > > IfPyramid;
00221 
00222     public:
00223       static void apply ( const unsigned int topologyId )
00224       {
00225         if( topologyId & 1 )
00226           IfPrism::apply( topologyId >> 1 );
00227         else
00228           IfPyramid::apply( topologyId >> 1 );
00229       }
00230 
00231       template< class T1 >
00232       static void apply ( const unsigned int topologyId, T1 &p1 )
00233       {
00234         if( topologyId & 1 )
00235           IfPrism::apply( topologyId >> 1, p1 );
00236         else
00237           IfPyramid::apply( topologyId >> 1, p1 );
00238       }
00239 
00240       template< class T1, class T2 >
00241       static void apply ( const unsigned int topologyId, T1 &p1, T2 &p2 )
00242       {
00243         if( topologyId & 1 )
00244           IfPrism::apply( topologyId >> 1, p1, p2 );
00245         else
00246           IfPyramid::apply( topologyId >> 1, p1, p2 );
00247       }
00248 
00249       template< class T1, class T2, class T3 >
00250       static void apply ( const unsigned int topologyId, T1 &p1, T2 &p2, T3 &p3 )
00251       {
00252         if( topologyId & 1 )
00253           IfPrism::apply( topologyId >> 1, p1, p2, p3 );
00254         else
00255           IfPyramid::apply( topologyId >> 1, p1, p2, p3 );
00256       }
00257 
00258       template< class T1, class T2, class T3, class T4 >
00259       static void apply ( const unsigned int topologyId, T1 &p1, T2 &p2, T3 &p3, T4 &p4 )
00260       {
00261         if( topologyId & 1 )
00262           IfPrism::apply( topologyId >> 1, p1, p2, p3, p4 );
00263         else
00264           IfPyramid::apply( topologyId >> 1, p1, p2, p3, p4 );
00265       }
00266     };
00267 
00268     template< template< class > class Operation, class Topology >
00269     class IfTopology< Operation, 0, Topology >
00270     {
00271     public:
00272       static void apply ( const unsigned int topologyId )
00273       {
00274         Operation< Topology >::apply();
00275       }
00276 
00277       template< class T1 >
00278       static void apply ( const unsigned int topologyId, T1 &p1 )
00279       {
00280         Operation< Topology >::apply( p1 );
00281       }
00282 
00283       template< class T1, class T2 >
00284       static void apply ( const unsigned int topologyId, T1 &p1, T2 &p2 )
00285       {
00286         Operation< Topology >::apply( p1, p2 );
00287       }
00288 
00289       template< class T1, class T2, class T3 >
00290       static void apply ( const unsigned int topologyId, T1 &p1, T2 &p2, T3 &p3 )
00291       {
00292         Operation< Topology >::apply( p1, p2, p3 );
00293       }
00294 
00295       template< class T1, class T2, class T3, class T4 >
00296       static void apply ( const unsigned int topologyId, T1 &p1, T2 &p2, T3 &p3, T4 &p4 )
00297       {
00298         Operation< Topology >::apply( p1, p2, p3, p4 );
00299       }
00300     };
00301 
00302   }
00303 
00304 }
00305 
00306 #endif // DUNE_GEOMETRY_GENERICGEOMETRY_TOPOLOGYTYPES_HH