subtopologies.hh

00001 #ifndef DUNE_GENERICGEOMETRY_SUBTOPOLOGIES_HH
00002 #define DUNE_GENERICGEOMETRY_SUBTOPOLOGIES_HH
00003 
00004 #include <cassert>
00005 #include <vector>
00006 
00007 #include <dune/common/static_assert.hh>
00008 
00009 #include <dune/grid/genericgeometry/misc.hh>
00010 #include <dune/grid/genericgeometry/topologytypes.hh>
00011 #include <dune/grid/genericgeometry/codimtable.hh>
00012 
00013 namespace Dune
00014 {
00015 
00016   namespace GenericGeometry
00017   {
00018 
00019     template< class Topology, unsigned int codim >
00020     struct Size;
00021 
00022     template< class Topology, unsigned int codim, unsigned int i >
00023     struct SubTopology;
00024 
00025     template< class Topology, unsigned int codim, unsigned int subcodim >
00026     class SubTopologySize;
00027 
00028     template< class Topology, unsigned int codim, unsigned int subcodim >
00029     class GenericSubTopologyNumbering;
00030 
00031     template< class Topology, unsigned int codim, unsigned int subcodim >
00032     class SubTopologyNumbering;
00033 
00034 
00035 
00036     // Size
00037     // ----
00038 
00039     template< class Topology, unsigned int dim, unsigned int codim >
00040     class SizeImpl;
00041     
00042     template< unsigned int dim, unsigned int codim >
00043     class SizeImpl< Point, dim, codim >
00044     {
00045       typedef Point Topology;
00046       dune_static_assert( (dim == Topology :: dimension), "Wrong dimension" );
00047       dune_static_assert( (codim <= dim), "Invalid codimension" );
00048                           
00049     public:
00050       enum { value = 1 };
00051     };
00052 
00053     template< class BaseTopology, unsigned int dim, unsigned int codim >
00054     class SizeImpl< Prism< BaseTopology >, dim, codim >
00055     {
00056       typedef Prism< BaseTopology > Topology;
00057       dune_static_assert( (dim == Topology :: dimension), "Wrong dimension" );
00058       dune_static_assert( (codim <= dim), "Invalid codimension" );
00059 
00060       enum { m = Size< BaseTopology, codim-1 > :: value };
00061       enum { n = Size< BaseTopology, codim > :: value };
00062 
00063     public:
00064       enum { value = n + 2*m };
00065     };
00066 
00067     template< class BaseTopology, unsigned int dim >
00068     class SizeImpl< Prism< BaseTopology >, dim, 0 >
00069     {
00070       typedef Prism< BaseTopology > Topology;
00071       dune_static_assert( (dim == Topology :: dimension), "Wrong dimension" );
00072 
00073     public:
00074       enum { value = 1 };
00075     };
00076     
00077     template< class BaseTopology, unsigned int dim >
00078     class SizeImpl< Prism< BaseTopology >, dim, dim >
00079     {
00080       typedef Prism< BaseTopology > Topology;
00081       dune_static_assert( (dim == Topology :: dimension), "Wrong dimension" );
00082 
00083       enum { m = Size< BaseTopology, dim-1 > :: value };
00084 
00085     public:
00086       enum { value = 2*m };
00087     };
00088 
00089     template< class BaseTopology, unsigned int dim, unsigned int codim >
00090     struct SizeImpl< Pyramid< BaseTopology >, dim, codim >
00091     {
00092       typedef Pyramid< BaseTopology > Topology;
00093       dune_static_assert( (dim == Topology :: dimension), "Wrong dimension" );
00094       dune_static_assert( (codim <= dim), "Invalid codimension" );
00095 
00096       enum { m = Size< BaseTopology, codim-1 > :: value };
00097       enum { n = Size< BaseTopology, codim > :: value };
00098 
00099     public:
00100       enum { value = m+n };
00101     };
00102     
00103     template< class BaseTopology, unsigned int dim >
00104     class SizeImpl< Pyramid< BaseTopology >, dim, 0 >
00105     {
00106       typedef Pyramid< BaseTopology > Topology;
00107       dune_static_assert( (dim == Topology :: dimension), "Wrong dimension" );
00108 
00109     public:
00110       enum { value = 1 };
00111     };
00112     
00113     template< class BaseTopology, unsigned int dim >
00114     class SizeImpl< Pyramid< BaseTopology >, dim, dim >
00115     {
00116       typedef Pyramid< BaseTopology > Topology;
00117       dune_static_assert( (dim == Topology :: dimension), "Wrong dimension" );
00118 
00119       enum { m = Size< BaseTopology, dim-1 > :: value };
00120 
00121     public:
00122       enum { value = m+1 };
00123     };
00124 
00125 
00126     template< class Topology, unsigned int codim >
00127     struct Size
00128     {
00129       enum { value = SizeImpl< Topology, Topology :: dimension, codim > :: value };
00130     };
00131 
00132 
00133 
00134     // SubTopology
00135     // -----------
00136 
00137     template< class Topology, unsigned int dim, unsigned int codim, unsigned int i >
00138     class SubTopologyImpl;
00139     
00140     template< unsigned int dim, unsigned int codim, unsigned int i >
00141     class SubTopologyImpl< Point, dim, codim, i >
00142     {
00143       typedef Point Topology;
00144       dune_static_assert( (dim == Topology :: dimension), "Wrong dimension" );
00145       dune_static_assert( (codim <= dim), "Invalid codimension" );
00146       dune_static_assert( (i < Size< Topology, codim > :: value),
00147                           "Invalid subentity index" );
00148       
00149     public:
00150       typedef Topology type;
00151     };
00152     
00153     template< class BaseTopology, unsigned int dim, unsigned int codim, unsigned int i >
00154     class SubTopologyImpl< Prism< BaseTopology >, dim, codim, i >
00155     {
00156       typedef Prism< BaseTopology > Topology;
00157       dune_static_assert( (dim == Topology :: dimension), "Wrong dimension" );
00158       dune_static_assert( (codim <= dim), "Invalid codimension" );
00159       dune_static_assert( (i < Size< Topology, codim > :: value),
00160                           "Invalid subentity index" );
00161       
00162       enum { m = Size< BaseTopology, codim-1 > :: value };
00163       enum { n = Size< BaseTopology, codim > :: value };
00164 
00165       enum { s = (i < n+m ? 0 : 1) };
00166       
00167       template< bool >
00168       struct PrismSub
00169       {
00170         typedef Prism< typename SubTopology< BaseTopology, codim, i > :: type > type;
00171       };
00172 
00173       template< bool >
00174       struct BaseSub
00175       {
00176         typedef typename SubTopology< BaseTopology, codim-1, i-(n+s*m) > :: type type;
00177       };
00178         
00179     public:
00180       typedef typename ProtectedIf< (i < n), PrismSub, BaseSub > :: type type;
00181     };
00182 
00183     template< class BaseTopology, unsigned int dim, unsigned int i >
00184     class SubTopologyImpl< Prism< BaseTopology >, dim, 0, i >
00185     {
00186       typedef Prism< BaseTopology > Topology;
00187       dune_static_assert( (dim == Topology :: dimension), "Wrong dimension" );
00188       dune_static_assert( (i < Size< Topology, 0 > :: value),
00189                           "Invalid subentity index" );
00190     public:
00191       typedef Topology type;
00192     };
00193     
00194     template< class BaseTopology, unsigned int dim, unsigned int i >
00195     class SubTopologyImpl< Prism< BaseTopology >, dim, dim, i >
00196     {
00197       typedef Prism< BaseTopology > Topology;
00198       dune_static_assert( (dim == Topology :: dimension), "Wrong dimension" );
00199       dune_static_assert( (i < Size< Topology, dim > :: value),
00200                           "Invalid subentity index" );
00201     public:
00202       typedef Point type;
00203     };
00204 
00205     template< class BaseTopology, unsigned int dim, unsigned int codim, unsigned int i >
00206     class SubTopologyImpl< Pyramid< BaseTopology >, dim, codim, i >
00207     {
00208       typedef Pyramid< BaseTopology > Topology;
00209       dune_static_assert( (dim == Topology :: dimension), "Wrong dimension" );
00210       dune_static_assert( (codim <= dim), "Invalid codimension" );
00211       dune_static_assert( (i < Size< Topology, codim > :: value),
00212                           "Invalid subentity index" );
00213 
00214       enum { m = Size< BaseTopology, codim-1 > :: value };
00215 
00216       template< bool >
00217       struct BaseSub
00218       {
00219         typedef typename SubTopology< BaseTopology, codim-1, i > :: type type;
00220       };
00221 
00222       template< bool >
00223       struct PyramidSub
00224       {
00225         typedef Pyramid< typename SubTopology< BaseTopology, codim, i-m > :: type > type;
00226       };
00227 
00228     public:
00229       typedef typename ProtectedIf< (i < m), BaseSub, PyramidSub > :: type type;
00230     };
00231 
00232     template< class BaseTopology, unsigned int dim, unsigned int i >
00233     class SubTopologyImpl< Pyramid< BaseTopology >, dim, 0, i >
00234     {
00235       typedef Pyramid< BaseTopology > Topology;
00236       dune_static_assert( (dim == Topology :: dimension), "Wrong dimension" );
00237       dune_static_assert( (i < Size< Topology, 0 > :: value),
00238                           "Invalid subentity index" );
00239 
00240     public:
00241       typedef Topology type;
00242     };
00243     
00244     template< class BaseTopology, unsigned int dim, unsigned int i >
00245     class SubTopologyImpl< Pyramid< BaseTopology >, dim, dim, i >
00246     {
00247       typedef Pyramid< BaseTopology > Topology;
00248       dune_static_assert( (dim == Topology :: dimension), "Wrong dimension" );
00249       dune_static_assert( (i < Size< Topology, dim > :: value),
00250                           "Invalid subentity index" );
00251 
00252     public:
00253       typedef Point type;
00254     };
00255     
00256     template< class Topology, unsigned int codim, unsigned int i >
00257     struct SubTopology
00258     {
00259       typedef typename SubTopologyImpl< Topology, Topology :: dimension, codim, i > :: type type;
00260     };
00261 
00262 
00263 
00264     // SubTopologySize
00265     // ---------------
00266 
00267     template< class Topology, unsigned int codim, unsigned int subcodim >
00268     class SubTopologySize
00269     {
00270       template< int i >
00271       struct Builder;
00272      
00273       unsigned int size_[ Size< Topology, codim > :: value ];
00274 
00275       SubTopologySize ()
00276       {
00277         ForLoop< Builder, 0, Size< Topology, codim > :: value-1 >
00278           :: apply( *this );
00279       }
00280 
00281       SubTopologySize ( const SubTopologySize & );
00282       
00283       static const SubTopologySize &instance ()
00284       {
00285         static SubTopologySize inst;
00286         return inst;
00287       }
00288 
00289     public:
00290       static unsigned int size ( unsigned int i )
00291       {
00292         assert( (i < Size< Topology, codim > :: value) );
00293         return instance().size_[ i ];
00294       }
00295     };
00296 
00297     template< class Topology, unsigned int codim, unsigned int subcodim >
00298     template< int i >
00299     struct SubTopologySize< Topology, codim, subcodim > :: Builder
00300     {
00301       typedef GenericGeometry :: SubTopologySize< Topology, codim, subcodim >
00302         SubTopologySize;
00303       typedef typename GenericGeometry :: SubTopology< Topology, codim, i > :: type
00304         SubTopology;
00305       
00306       static void apply ( SubTopologySize &subTopologySize )
00307       {
00308         subTopologySize.size_[ i ] = Size< SubTopology, subcodim > :: value;
00309       }
00310     };
00311 
00312 
00313 
00314     // GenericSubTopologyNumbering
00315     // ---------------------------
00316 
00317     template< class Topology, unsigned int codim,
00318               unsigned int subdim, unsigned int subcodim >
00319     struct GenericSubTopologyNumberingHelper;
00320 
00321     template< class BaseTopology, unsigned int codim,
00322               unsigned int subdim, unsigned int subcodim >
00323     struct GenericSubTopologyNumberingHelper
00324       < Prism< BaseTopology >, codim, subdim, subcodim >
00325     {
00326       typedef Prism< BaseTopology > Topology;
00327       
00328       enum { m = Size< BaseTopology, codim-1 > :: value };
00329       enum { n = Size< BaseTopology, codim > :: value };
00330 
00331       enum { mb = Size< BaseTopology, codim+subcodim-1 > :: value };
00332       enum { nb = Size< BaseTopology, codim+subcodim > :: value };
00333 
00334       static unsigned int number ( unsigned int i, unsigned int j )
00335       {
00336         const unsigned int s = (i < n+m ? 0 : 1);
00337         if( i < n )
00338         {
00339           const unsigned int ms = SubTopologySize< BaseTopology, codim, subcodim-1 > :: size( i );
00340           const unsigned int ns = SubTopologySize< BaseTopology, codim, subcodim > :: size( i );
00341           const unsigned int ss = (j < ns+ms ? 0 : 1);
00342           if( j < ns )
00343             return GenericSubTopologyNumbering< BaseTopology, codim, subcodim >
00344               :: number( i, j );
00345           else
00346             return GenericSubTopologyNumbering< BaseTopology, codim, subcodim-1 >
00347               :: number( i, j-(ns+ss*ms) ) + nb + ss*mb;
00348         }
00349         else
00350           return GenericSubTopologyNumbering< BaseTopology, codim-1, subcodim >
00351             :: number( i-(n+s*m), j ) + nb + s*mb;
00352       }
00353     };
00354 
00355     template< class BaseTopology, unsigned int codim, unsigned int subdim >
00356     struct GenericSubTopologyNumberingHelper
00357       < Prism< BaseTopology >, codim, subdim, 0 >
00358     {
00359       typedef Prism< BaseTopology > Topology;
00360 
00361       static unsigned int number ( unsigned int i, unsigned int j )
00362       {
00363         return i;
00364       }
00365     };
00366 
00367     template< class BaseTopology, unsigned int codim, unsigned int subdim >
00368     struct GenericSubTopologyNumberingHelper
00369       < Prism< BaseTopology >, codim, subdim, subdim >
00370     {
00371       typedef Prism< BaseTopology > Topology;
00372       
00373       enum { m = Size< BaseTopology, codim-1 > :: value };
00374       enum { n = Size< BaseTopology, codim > :: value };
00375 
00376       enum { mb = Size< BaseTopology, codim+subdim-1 > :: value };
00377 
00378       static unsigned int number ( unsigned int i, unsigned int j )
00379       {
00380         const unsigned int s = (i < n+m ? 0 : 1);
00381         if( i < n )
00382         {
00383           const unsigned int ms = SubTopologySize< BaseTopology, codim, subdim-1 > :: size( i );
00384           const unsigned int ss = (j < ms ? 0 : 1);
00385           return GenericSubTopologyNumbering< BaseTopology, codim, subdim-1 >
00386             :: number( i, j-ss*ms ) + ss*mb;
00387         }
00388         else
00389           return GenericSubTopologyNumbering< BaseTopology, codim-1, subdim >
00390             :: number( i-(n+s*m), j ) + s*mb;
00391       }
00392     };
00393 
00394     template< class BaseTopology, unsigned int codim,
00395               unsigned int subdim, unsigned int subcodim >
00396     struct GenericSubTopologyNumberingHelper
00397       < Pyramid< BaseTopology >, codim, subdim, subcodim >
00398     {
00399       typedef Pyramid< BaseTopology > Topology;
00400       
00401       enum { m = Size< BaseTopology, codim-1 > :: value };
00402 
00403       enum { mb = Size< BaseTopology, codim+subcodim-1 > :: value };
00404 
00405       static unsigned int number ( unsigned int i, unsigned int j )
00406       {
00407         if( i < m )
00408           return GenericSubTopologyNumbering< BaseTopology, codim-1, subcodim >
00409             :: number( i, j );
00410         else
00411         {
00412           const unsigned int ms = SubTopologySize< BaseTopology, codim, subcodim-1 > :: size( i-m );
00413           if( j < ms )
00414             return GenericSubTopologyNumbering< BaseTopology, codim, subcodim-1 >
00415               :: number( i-m, j );
00416           else
00417             return GenericSubTopologyNumbering< BaseTopology, codim, subcodim >
00418               :: number( i-m, j-ms ) + mb;
00419         }
00420       }
00421     };
00422 
00423     template< class BaseTopology, unsigned int codim, unsigned int subdim >
00424     struct GenericSubTopologyNumberingHelper
00425       < Pyramid< BaseTopology >, codim, subdim, 0 >
00426     {
00427       typedef Pyramid< BaseTopology > Topology;
00428       
00429       static unsigned int number ( unsigned int i, unsigned int j )
00430       {
00431         return i;
00432       }
00433     };
00434 
00435     template< class BaseTopology, unsigned int codim, unsigned int subdim >
00436     struct GenericSubTopologyNumberingHelper
00437       < Pyramid< BaseTopology >, codim, subdim, subdim >
00438     {
00439       typedef Pyramid< BaseTopology > Topology;
00440       
00441       enum { m = Size< BaseTopology, codim-1 > :: value };
00442 
00443       enum { mb = Size< BaseTopology, codim+subdim-1 > :: value };
00444 
00445       static unsigned int number ( unsigned int i, unsigned int j )
00446       {
00447         if( i < m )
00448           return GenericSubTopologyNumbering< BaseTopology, codim-1, subdim >
00449             :: number( i, j );
00450         else
00451         {
00452           const unsigned int ms = SubTopologySize< BaseTopology, codim, subdim-1 > :: size( i-m );
00453           if( j < ms )
00454             return GenericSubTopologyNumbering< BaseTopology, codim, subdim-1 >
00455               :: number( i-m, j );
00456           else
00457             return mb;
00458         }
00459       }
00460     };
00461 
00462     template< class Topology, unsigned int codim, unsigned int subcodim >
00463     class GenericSubTopologyNumbering
00464     {
00465       dune_static_assert( (codim <= Topology :: dimension), "Invalid codimension" );
00466       dune_static_assert( (codim + subcodim <= Topology :: dimension),
00467                           "Invalid subcodimension" );
00468 
00469       template< bool >
00470       struct BorderCodim
00471       {
00472         static unsigned int number ( unsigned int i, unsigned int j )
00473         {
00474           return (codim == 0 ? j : i );
00475         }
00476       };
00477 
00478       template< bool >
00479       struct InnerCodim
00480       {
00481         static unsigned int number ( unsigned int i, unsigned int j )
00482         {
00483           return GenericSubTopologyNumberingHelper
00484             < Topology, codim, Topology :: dimension - codim, subcodim >
00485             :: number( i, j );
00486         }
00487       };
00488       
00489     public:
00490       static unsigned int number ( unsigned int i, unsigned int j )
00491       {
00492         assert( (j <= SubTopologySize< Topology, codim, subcodim > :: size( i )) );
00493         return ProtectedIf
00494           < (codim == 0) || (codim == Topology :: dimension), BorderCodim, InnerCodim >
00495           :: number( i, j );
00496       }
00497     };
00498 
00499 
00500 
00501     // SubTopologyNumbering
00502     // --------------------
00503 
00504     template< class Topology, unsigned int codim, unsigned int subcodim >
00505     class SubTopologyNumbering
00506     {
00507       typedef GenericSubTopologyNumbering< Topology, codim, subcodim >
00508         GenericNumbering;
00509 
00510       std :: vector< unsigned int > numbering_[ Size< Topology, codim > :: value ];
00511 
00512     public:
00513       static unsigned int number ( unsigned int i, unsigned int j )
00514       {
00515         assert( (j <= SubTopologySize< Topology, codim, subcodim > :: size( i )) );
00516         return instance().numbering_[ i ][ j ];
00517       }
00518 
00519     private:
00520       SubTopologyNumbering ()
00521       {
00522         for( unsigned int i = 0; i < Size< Topology, codim > :: value; ++i )
00523         {
00524           const unsigned int size = SubTopologySize< Topology, codim, subcodim > :: size( i );
00525           numbering_[ i ].resize( size );
00526           for( unsigned int j = 0; j < size; ++j )
00527             numbering_[ i ][ j ] = GenericNumbering :: number( i, j );
00528         }
00529       }
00530       
00531       static const SubTopologyNumbering &instance ()
00532       {
00533         static SubTopologyNumbering inst;
00534         return inst;
00535       }
00536     };
00537 
00538 
00539 
00540     // IsCodimHybrid
00541     // -------------
00542 
00543     template< class Topology, unsigned int codim >
00544     struct IsCodimHybrid
00545     {
00546       enum { value = (codim != 0) && IsHybrid< Topology > :: value };
00547     };
00548     
00549   }
00550   
00551 }
00552 
00553 #endif

Generated on Thu Apr 2 10:40:43 2009 for dune-grid by  doxygen 1.5.6