conversion.hh

00001 #ifndef DUNE_GENERICGEOMETRY_CONVERSION_HH
00002 #define DUNE_GENERICGEOMETRY_CONVERSION_HH
00003 
00004 #include <dune/common/static_assert.hh>
00005 #include <dune/common/geometrytype.hh>
00006 
00007 #include <dune/grid/genericgeometry/misc.hh>
00008 #include <dune/grid/genericgeometry/topologytypes.hh>
00009 #include <dune/grid/genericgeometry/subtopologies.hh>
00010 
00011 namespace Dune
00012 {
00013 
00014   namespace GenericGeometry
00015   {
00016 
00017     // DuneGeometryType
00018     // ----------------
00019 
00020     template< class Topology, GeometryType :: BasicType defaultType >
00021     class DuneGeometryType;
00022 
00023     template< GeometryType :: BasicType defaultType >
00024     class DuneGeometryType< Point, defaultType >
00025     {
00026       dune_static_assert( (defaultType == GeometryType :: simplex)
00027                           || (defaultType == GeometryType :: cube),
00028                           "defaultType may only be a simplex or a cube." );
00029 
00030     public:
00031       enum { dimension = 0 };
00032       enum { basicType = defaultType };
00033 
00034       static GeometryType type ()
00035       {
00036         return GeometryType( (GeometryType :: BasicType)basicType, dimension );
00037       }
00038     };
00039 
00040     template< class BaseTopology, GeometryType :: BasicType defaultType >
00041     class DuneGeometryType< Prism< BaseTopology >, defaultType >
00042     {
00043       typedef DuneGeometryType< BaseTopology, defaultType > DuneBaseGeometryType;
00044       
00045       dune_static_assert( ((int)defaultType == (int)GeometryType :: simplex)
00046                           || ((int)defaultType == (int)GeometryType :: cube),
00047                           "defaultType may only be a simplex or a cube." );
00048 
00049       dune_static_assert( ((int)DuneBaseGeometryType :: basicType == (int)GeometryType :: simplex)
00050                           || ((int)DuneBaseGeometryType :: basicType == (int)GeometryType :: cube),
00051                           "Only prisms over simplices or cubes can be converted." );
00052 
00053     public:
00054       enum { dimension = DuneBaseGeometryType :: dimension + 1 };
00055       enum
00056       {
00057         basicType = (dimension == 1)
00058                     ? defaultType
00059                     : ((dimension == 2)
00060                       || ((int)DuneBaseGeometryType :: basicType == (int)GeometryType :: cube))
00061                       ? GeometryType :: cube
00062                       : GeometryType :: prism
00063       };
00064 
00065       static GeometryType type ()
00066       {
00067         return GeometryType( (GeometryType :: BasicType)basicType, dimension );
00068       }
00069     };
00070 
00071     template< class BaseTopology, GeometryType :: BasicType defaultType >
00072     class DuneGeometryType< Pyramid< BaseTopology >, defaultType >
00073     {
00074       typedef DuneGeometryType< BaseTopology, defaultType > DuneBaseGeometryType;
00075       
00076       dune_static_assert( ((int)defaultType == (int)GeometryType :: simplex)
00077                           || ((int)defaultType == (int)GeometryType :: cube),
00078                           "defaultType may only be a simplex or a cube." );
00079 
00080       dune_static_assert( ((int)DuneBaseGeometryType :: basicType == (int)GeometryType :: simplex)
00081                           || ((int)DuneBaseGeometryType :: basicType == (int)GeometryType :: cube),
00082                           "Only pyramids over simplices or cubes can be converted." );
00083 
00084     public:
00085       enum { dimension = DuneBaseGeometryType :: dimension + 1 };
00086       enum
00087       {
00088         basicType = (dimension == 1)
00089                     ? defaultType
00090                     : ((dimension == 2)
00091                       || ((int)DuneBaseGeometryType :: basicType == (int)GeometryType :: simplex))
00092                       ? GeometryType :: simplex
00093                       : GeometryType :: pyramid
00094       };
00095 
00096       static GeometryType type ()
00097       {
00098         return GeometryType( (GeometryType :: BasicType)basicType, dimension );
00099       }
00100     };
00101 
00102 
00103 
00104     // DuneGeometryTypeProvider
00105     // ------------------------
00106 
00107     template< unsigned int dim, GeometryType :: BasicType defaultType >
00108     struct DuneGeometryTypeProvider
00109     {
00110       enum { dimension = dim };
00111       enum { numTopologies = (1 << dimension) };
00112 
00113     private:
00114       template< int i >
00115       struct Builder;
00116       
00117       GeometryType types_[ numTopologies ];
00118       
00119       DuneGeometryTypeProvider ()
00120       {
00121         ForLoop< Builder, 0, (1 << dim)-1 > :: apply( types_ );
00122       }
00123       
00124       static const DuneGeometryTypeProvider &instance ()
00125       {
00126         static DuneGeometryTypeProvider inst;
00127         return inst;
00128       }
00129       
00130     public:
00131       static const GeometryType &type ( unsigned int topologyId )
00132       {
00133         assert( topologyId < numTopologies );
00134         return instance().types_[ topologyId ];
00135       }
00136     };
00137 
00138 
00139     template< unsigned int dim, GeometryType :: BasicType defaultType >
00140     template< int i >
00141     struct DuneGeometryTypeProvider< dim, defaultType > :: Builder
00142     {
00143       typedef typename GenericGeometry :: Topology< i, dimension > :: type Topology;
00144       typedef GenericGeometry :: DuneGeometryType< Topology, defaultType >
00145         DuneGeometryType;
00146       
00147       static void apply ( GeometryType (&types)[ numTopologies ] )
00148       {
00149         types[ i ] = DuneGeometryType :: type();
00150       }
00151     };
00152 
00153 
00154 
00155 
00156 
00157     // MapNumbering
00158     // ------------
00159     template< class Topology >
00160     struct MapNumbering;
00161 
00162     
00163     struct MapNumberingIdentical
00164     {
00165       template< unsigned int codim >
00166       static unsigned int dune2generic ( unsigned int i )
00167       {
00168         return i;
00169       }
00170 
00171       template< unsigned int codim >
00172       static unsigned int generic2dune ( unsigned int i )
00173       {
00174         return i;
00175       }
00176     };
00177 
00178     // MapNumbering for Point
00179     template<>
00180     struct MapNumbering< Point >
00181     : public MapNumberingIdentical
00182     {};
00183 
00184     // MapNumbering for Line
00185     template<>
00186     struct MapNumbering< Prism< Point > >
00187     : public MapNumberingIdentical
00188     {};
00189    
00190     template<>
00191     struct MapNumbering< Pyramid< Point > >
00192     : public MapNumberingIdentical
00193     {};
00194 
00195     // MapNumbering for Triangle
00196     struct MapNumberingTriangle
00197     {
00198       template< unsigned int codim >
00199       static unsigned int dune2generic ( unsigned int i )
00200       {
00201         return (codim == 1 ? 2 - i : i);
00202       }
00203 
00204       template< unsigned int codim >
00205       static unsigned int generic2dune ( unsigned int i )
00206       {
00207         return dune2generic< codim >( i );
00208       }
00209     };
00210     
00211     template<>
00212     struct MapNumbering< Pyramid< Pyramid< Point > > >
00213     : public MapNumberingTriangle
00214     {};
00215     
00216     template<>
00217     struct MapNumbering< Pyramid< Prism< Point > > >
00218     : public MapNumberingTriangle
00219     {};
00220 
00221 
00222     // MapNumbering for Quadrilateral
00223     template<>
00224     struct MapNumbering< Prism< Pyramid< Point > > >
00225     : public MapNumberingIdentical
00226     {};
00227 
00228     template<>
00229     struct MapNumbering< Prism< Prism< Point > > >
00230     : public MapNumberingIdentical
00231     {};
00232 
00233     // MapNumbering for Tetrahedron
00234     struct MapNumberingTetrahedron
00235     {
00236       template< unsigned int codim >
00237       static unsigned int dune2generic ( unsigned int i )
00238       {
00239         static unsigned int edge[ 6 ] = { 0, 2, 1, 3, 4, 5 };
00240         return (codim == 1 ? 3 - i : (codim == 2 ? edge[ i ] : i));
00241       }
00242 
00243       template< unsigned int codim >
00244       static unsigned int generic2dune ( unsigned int i )
00245       {
00246         return dune2generic< codim >( i );
00247       }
00248     };
00249 
00250     template<>
00251     struct MapNumbering< Pyramid< Pyramid< Pyramid< Point > > > >
00252     : public MapNumberingTetrahedron
00253     {};
00254     
00255     template<>
00256     struct MapNumbering< Pyramid< Pyramid< Prism< Point > > > >
00257     : public MapNumberingTetrahedron
00258     {};
00259 
00260     // MapNumbering for Cube
00261     struct MapNumberingCube
00262     {
00263       template< unsigned int codim >
00264       static unsigned int dune2generic ( unsigned int i )
00265       {
00266         static unsigned int edge[ 12 ] = { 0, 1, 2, 3, 4, 5, 8, 9, 6, 7, 10, 11 };
00267         return (codim == 2 ? edge[ i ] : i);
00268       }
00269 
00270       template< unsigned int codim >
00271       static unsigned int generic2dune ( unsigned int i )
00272       {
00273         return dune2generic< codim >( i );
00274       }
00275     };
00276     
00277     template<>
00278     struct MapNumbering< Prism< Prism< Pyramid< Point > > > >
00279     : public MapNumberingCube
00280     {};
00281     
00282     template<>
00283     struct MapNumbering< Prism< Prism< Prism< Point > > > >
00284     : public MapNumberingCube
00285     {};
00286 
00287     // MapNumbering for Pyramid
00288     struct MapNumberingPyramid
00289     {
00290       template< unsigned int codim >
00291       static unsigned int dune2generic ( unsigned int i )
00292       {
00293         static unsigned int vertex[ 5 ] = { 0, 1, 3, 2, 4 };
00294         static unsigned int edge[ 8 ] = { 2, 1, 3, 0, 4, 5, 7, 6 };
00295         static unsigned int face[ 5 ] = { 0, 3, 2, 4, 1 };
00296         
00297         if( codim == 3 )
00298           return vertex[ i ];
00299         else if( codim == 2 )
00300           return edge[ i ];
00301         else if( codim == 1 )
00302           return face[ i ];
00303         else
00304           return i;
00305       }
00306 
00307       template< unsigned int codim >
00308       static unsigned int generic2dune ( unsigned int i )
00309       {
00310         static unsigned int vertex[ 5 ] = { 0, 1, 3, 2, 4 };
00311         static unsigned int edge[ 8 ] = { 3, 1, 0, 2, 4, 5, 7, 6 };
00312         static unsigned int face[ 5 ] = { 0, 4, 2, 1, 3 };
00313         
00314         if( codim == 3 )
00315           return vertex[ i ];
00316         else if( codim == 2 )
00317           return edge[ i ];
00318         else if( codim == 1 )
00319           return face[ i ];
00320         else
00321           return i;
00322       }
00323     };
00324     
00325     template<>
00326     struct MapNumbering< Pyramid< Prism< Pyramid< Point > > > >
00327     : public MapNumberingPyramid
00328     {};
00329     
00330     template<>
00331     struct MapNumbering< Pyramid< Prism< Prism< Point > > > >
00332     : public MapNumberingPyramid
00333     {};
00334 
00335     // MapNumbering for Prism
00336     struct MapNumberingPrism
00337     {
00338       template< unsigned int codim >
00339       static unsigned int dune2generic ( unsigned int i )
00340       {
00341         static unsigned int edge[ 9 ] = { 3, 5, 4, 0, 1, 2, 6, 8, 7 };
00342         static unsigned int face[ 5 ] = { 3, 0, 2, 1, 4 };
00343 
00344         if( codim == 2 )
00345           return edge[ i ];
00346         else if( codim == 1 )
00347           return face[ i ];
00348         else
00349           return i;
00350       }
00351 
00352       template< unsigned int codim >
00353       static unsigned int generic2dune ( unsigned int i )
00354       {
00355         static unsigned int edge[ 9 ] = { 3, 4, 5, 0, 2, 1, 6, 8, 7 };
00356         static unsigned int face[ 5 ] = { 1, 3, 2, 0, 4 };
00357 
00358         if( codim == 2 )
00359           return edge[ i ];
00360         else if( codim == 1 )
00361           return face[ i ];
00362         else
00363           return i;
00364       }
00365     };
00366 
00367     template<>
00368     struct MapNumbering< Prism< Pyramid< Pyramid< Point > > > >
00369     : public MapNumberingPrism
00370     {};
00371     
00372     template<>
00373     struct MapNumbering< Prism< Pyramid< Prism< Point > > > >
00374     : public MapNumberingPrism
00375     {};
00376 
00377 
00378 
00379     // MapNumberingProvider
00380     // --------------------
00381 
00382     template< unsigned int dim >
00383     class MapNumberingProvider
00384     {
00385       enum { dimension = dim };
00386       enum { numTopologies = (1 << dimension) };
00387 
00388     private:
00389       template< int i >
00390       struct Builder;
00391 
00392       typedef std :: vector< unsigned int > Map;
00393       
00394       Map dune2generic_[ numTopologies ][ dimension+1 ];
00395       Map generic2dune_[ numTopologies ][ dimension+1 ];
00396       
00397       MapNumberingProvider ()
00398       {
00399         ForLoop< Builder, 0, (1 << dim)-1 > :: apply( dune2generic_, generic2dune_ );
00400       }
00401       
00402       static const MapNumberingProvider &instance ()
00403       {
00404         static MapNumberingProvider inst;
00405         return inst;
00406       }
00407       
00408     public:
00409       template< unsigned int codim >
00410       static unsigned int
00411       dune2generic ( unsigned int topologyId, unsigned int i )
00412       {
00413         assert( topologyId < numTopologies );
00414         return instance().dune2generic_[ topologyId ][ codim ][ i ];
00415       }
00416 
00417       template< unsigned int codim >
00418       static unsigned int
00419       generic2dune ( unsigned int topologyId, unsigned int i )
00420       {
00421         assert( topologyId < numTopologies );
00422         return instance().generic2dune_[ topologyId ][ codim ][ i ];
00423       }
00424     };
00425 
00426 
00427     template< unsigned int dim >
00428     template< int i >
00429     struct MapNumberingProvider< dim > :: Builder
00430     {
00431       typedef typename GenericGeometry :: Topology< i, dimension > :: type Topology;
00432       typedef GenericGeometry :: MapNumbering< Topology > MapNumbering;
00433 
00434       template< int codim >
00435       struct Codim;
00436       
00437       static void apply ( Map (&dune2generic)[ numTopologies ][ dimension+1 ],
00438                           Map (&generic2dune)[ numTopologies ][ dimension+1 ] )
00439       {
00440         ForLoop< Codim, 0, dimension > :: apply( dune2generic[ i ], generic2dune[ i ] );
00441       }
00442     };
00443 
00444     template< unsigned int dim >
00445     template< int i >
00446     template< int codim >
00447     struct MapNumberingProvider< dim > :: Builder< i > :: Codim
00448     {
00449       static void apply ( Map (&dune2generic)[ dimension+1 ],
00450                           Map (&generic2dune)[ dimension+1 ] )
00451       {
00452         const unsigned int size = Size< Topology, codim > :: value;
00453 
00454         Map &d2g = dune2generic[ codim ];
00455         d2g.resize( size );
00456         for( unsigned int j = 0; j < size; ++j )
00457           d2g[ j ] = MapNumbering::template dune2generic< codim >( j );
00458 
00459         Map &g2d = generic2dune[ codim ];
00460         g2d.resize( size );
00461         for( unsigned int j = 0; j < size; ++j )
00462           g2d[ j ] = MapNumbering::template generic2dune< codim >( j );
00463       }
00464     };
00465 
00466 
00467 
00468     // Convert
00469     // -------
00470 
00471     template< GeometryType :: BasicType type, unsigned int dim >
00472     struct Convert;
00473 
00474     template< unsigned int dim >
00475     struct Convert< GeometryType :: simplex, dim >
00476     {
00477       typedef Pyramid
00478         < typename Convert< GeometryType :: simplex, dim-1 > :: type >
00479         type;
00480 
00481       template< unsigned int codim >
00482       static unsigned int map ( unsigned int i )
00483       {
00484         return MapNumbering<type>::template dune2generic<codim>(i);
00485       }
00486     };
00487     
00488     template<>
00489     struct Convert< GeometryType :: simplex, 0 >
00490     {
00491       typedef Point type;
00492 
00493       template< unsigned int codim >
00494       static unsigned int map ( unsigned int i )
00495       {
00496         return MapNumbering<type>::template dune2generic<codim>(i);
00497       }
00498     };
00499     
00500     template< unsigned int dim >
00501     struct Convert< GeometryType :: cube, dim >
00502     {
00503       typedef Prism< typename Convert< GeometryType :: cube, dim-1 > :: type >
00504         type;
00505 
00506       template< unsigned int codim >
00507       static unsigned int map ( unsigned int i )
00508       {
00509         return MapNumbering<type>::template dune2generic<codim>(i);
00510       }
00511     };
00512     
00513     template<>
00514     struct Convert< GeometryType :: cube, 0 >
00515     {
00516       typedef Point type;
00517 
00518       template< unsigned int codim >
00519       static unsigned int map ( unsigned int i )
00520       {
00521         return MapNumbering<type>::template dune2generic<codim>(i);
00522       }
00523     };
00524     
00525     template< unsigned int dim >
00526     struct Convert< GeometryType :: prism, dim >
00527     {
00528       typedef Prism
00529         < typename Convert< GeometryType :: simplex, dim-1 > :: type >
00530         type;
00531 
00532       template< unsigned int codim >
00533       static unsigned int map ( unsigned int i )
00534       {
00535         return MapNumbering<type>::template dune2generic<codim>(i);
00536       }
00537 
00538     private:
00539       // dune_static_assert( dim >= 3, "Dune prisms must be at least 3-dimensional." );
00540     };
00541     
00542     template< unsigned int dim >
00543     struct Convert< GeometryType :: pyramid, dim >
00544     {
00545       typedef Pyramid
00546         < typename Convert< GeometryType :: cube, dim-1 > :: type >
00547         type;
00548 
00549       // Note that we map dune numbering into the generic one
00550       // this is only important for pyramids
00551       template< unsigned int codim >
00552       static unsigned int map ( unsigned int i )
00553       {
00554         return MapNumbering<type>::template dune2generic<codim>(i);
00555       }
00556 
00557     private:
00558       // dune_static_assert( dim >= 3, "Dune pyramids must be at least 3-dimensional." );
00559     };
00560 
00561 
00562 
00563 
00564     // topologyId
00565     // ----------
00566 
00567     inline unsigned int topologyId ( const GeometryType &type )
00568     {
00569       const unsigned int dim = type.dim();
00570 
00571       switch( type.basicType() )
00572       {
00573         case GeometryType::simplex:
00574           return 0;
00575 
00576         case GeometryType::cube:
00577           return (1 << dim) - 1;
00578 
00579         case GeometryType::pyramid:
00580           return (1 << (dim-1)) - 1;
00581 
00582         case GeometryType::prism:
00583           return 1 << (dim-1);
00584 
00585         default:
00586           DUNE_THROW( RangeError,
00587                       "Invalid basic geometry type: " << type.basicType() << "." );
00588       }
00589 
00590     }
00591 
00592   }
00593   
00594 }
00595 
00596 #endif

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