dune-geometry  2.2.0
conversion.hh
Go to the documentation of this file.
00001 #ifndef DUNE_GEOMETRY_GENERICGEOMETRY_CONVERSION_HH
00002 #define DUNE_GEOMETRY_GENERICGEOMETRY_CONVERSION_HH
00003 
00004 #include <dune/common/static_assert.hh>
00005 
00006 #include <dune/geometry/type.hh>
00007 #include <dune/geometry/genericgeometry/topologytypes.hh>
00008 #include <dune/geometry/genericgeometry/subtopologies.hh>
00009 
00010 namespace Dune
00011 {
00012 
00019   class deprecated_int
00020   {
00021     unsigned int i;
00022   public:
00024     #ifndef DEPRECATEDINT
00025     operator unsigned int () { return i; }
00026     #endif
00027     unsigned int value() { return i; };
00028     #ifdef DEPRECATEDINT
00029     explicit
00030     #endif
00031     deprecated_int(unsigned int j) : i(j) {};
00032   };
00033 
00034   namespace GenericGeometry
00035   {
00036 
00037     // DuneGeometryType
00038     // ----------------
00039 
00047     template< class Topology, GeometryType::BasicType linetype >
00048     class DuneGeometryType;
00049 
00050     template< GeometryType::BasicType linetype >
00051     class DuneGeometryType< Point, linetype >
00052     {
00053       dune_static_assert( (linetype == GeometryType::simplex)
00054                           || (linetype == GeometryType::cube),
00055                           "Parameter linetype may only be a simplex or a cube." );
00056 
00057     public:
00058       static const unsigned int dimension = 0;
00059       static const GeometryType::BasicType basicType = linetype;
00060 
00061       // GeometryType can be initialized directly with the topologyId
00062       static GeometryType type () DUNE_DEPRECATED
00063       {
00064         return GeometryType( basicType, dimension );
00065       }
00066     };
00067 
00068     template< class BaseTopology, GeometryType::BasicType linetype >
00069     class DuneGeometryType< Prism< BaseTopology >, linetype >
00070     {
00071       typedef DuneGeometryType< BaseTopology, linetype > DuneBaseGeometryType;
00072       
00073       dune_static_assert( (linetype == GeometryType::simplex)
00074                           || (linetype == GeometryType::cube),
00075                           "Parameter linetype may only be a simplex or a cube." );
00076 
00077       dune_static_assert( (DuneBaseGeometryType::basicType == GeometryType::simplex)
00078                           || (DuneBaseGeometryType::basicType == GeometryType::cube),
00079                           "Only prisms over simplices or cubes can be converted." );
00080 
00081     public:
00082       static const unsigned int dimension = DuneBaseGeometryType::dimension + 1;
00083       static const GeometryType::BasicType basicType
00084         = ((dimension == 1)
00085            ? linetype
00086            : ((dimension == 2) || (DuneBaseGeometryType::basicType == GeometryType::cube))
00087              ? GeometryType::cube
00088              : GeometryType::prism);
00089 
00090       // GeometryType can be initialized directly with the topologyId
00091       static GeometryType type () DUNE_DEPRECATED
00092       {
00093         return GeometryType( basicType, dimension );
00094       }
00095     };
00096 
00097     template< class BaseTopology, GeometryType::BasicType linetype >
00098     class DuneGeometryType< Pyramid< BaseTopology >, linetype >
00099     {
00100       typedef DuneGeometryType< BaseTopology, linetype > DuneBaseGeometryType;
00101       
00102       dune_static_assert( (linetype == GeometryType::simplex)
00103                           || (linetype == GeometryType::cube),
00104                           "Parameter linetype may only be a simplex or a cube." );
00105 
00106       dune_static_assert( (DuneBaseGeometryType::basicType == GeometryType::simplex)
00107                           || (DuneBaseGeometryType::basicType == GeometryType::cube),
00108                           "Only pyramids over simplices or cubes can be converted." );
00109 
00110     public:
00111       static const unsigned int dimension = DuneBaseGeometryType::dimension + 1;
00112       static const GeometryType::BasicType basicType
00113         = ((dimension == 1)
00114            ? linetype
00115            : ((dimension == 2) || (DuneBaseGeometryType::basicType == GeometryType::simplex))
00116              ? GeometryType::simplex
00117              : GeometryType::pyramid);
00118 
00119       // GeometryType can be initialized directly with the topologyId
00120       static GeometryType type () DUNE_DEPRECATED
00121       {
00122         return GeometryType( basicType, dimension );
00123       }
00124     };
00125 
00126 
00127 
00128     // DuneGeometryTypeProvider
00129     // ------------------------
00130 
00142     template< unsigned int dim, GeometryType::BasicType linetype >
00143     struct DuneGeometryTypeProvider
00144     {
00146       static const unsigned int dimension = dim;
00147 
00149       static const unsigned int numTopologies = (1 << dimension);
00150 
00151     private:
00152       GeometryType types_[ (dimension>=1)? numTopologies / 2 : numTopologies ];
00153       
00154       // GeometryType can be initialized directly with the topologyId
00155       DuneGeometryTypeProvider () DUNE_DEPRECATED
00156       {
00157         if( dimension > 3 )
00158         {
00159           for( unsigned int i = 0; i < numTopologies / 2; ++i )
00160             types_[ i ].makeNone( dimension );
00161         }
00162 
00163         if( dimension >= 3 )
00164         {
00165           const unsigned int d = (dimension >= 2 ? dimension-2 : 0);
00166           types_[ 0 ].makeSimplex( dimension );
00167           types_[ (1 << d) ] = GeometryType( GeometryType::prism, dimension );
00168           types_[ (1 << d) - 1 ] = GeometryType( GeometryType::pyramid, dimension );
00169           types_[ (1 << (d+1)) - 1 ].makeCube( dimension );
00170         }
00171         else if( dimension == 2 )
00172         {
00173           types_[ 0 ].makeSimplex( dimension );
00174           types_[ 1 ].makeCube( dimension );
00175         }
00176         else
00177           types_[ 0 ] = GeometryType( linetype, dimension );
00178       }
00179 
00180       static const DuneGeometryTypeProvider &instance ()
00181       {
00182         static DuneGeometryTypeProvider inst;
00183         return inst;
00184       }
00185       
00186     public:
00193       static const GeometryType &type ( unsigned int topologyId )
00194       {
00195         assert( topologyId < numTopologies );
00196         return instance().types_[ topologyId / 2 ];
00197       }
00198     };
00199 
00200 
00201 
00202     // MapNumbering
00203     // ------------
00204 
00205     template< class Topology >
00206     struct MapNumbering;
00207 
00208     
00209     struct MapNumberingIdentical
00210     {
00211       template< unsigned int codim >
00212       static unsigned int dune2generic ( unsigned int i )
00213       {
00214         return i;
00215       }
00216 
00217       template< unsigned int codim >
00218       static unsigned int generic2dune ( unsigned int i )
00219       {
00220         return i;
00221       }
00222     };
00223 
00224     // MapNumbering for Point
00225     template<>
00226     struct MapNumbering< Point >
00227     : public MapNumberingIdentical
00228     {};
00229 
00230     // MapNumbering for Line
00231     template<>
00232     struct MapNumbering< Prism< Point > >
00233     : public MapNumberingIdentical
00234     {};
00235    
00236     template<>
00237     struct MapNumbering< Pyramid< Point > >
00238     : public MapNumberingIdentical
00239     {};
00240 
00241     // MapNumbering for Triangle
00242     struct MapNumberingTriangle
00243     {
00244       template< unsigned int codim >
00245       static unsigned int dune2generic ( unsigned int i )
00246       {
00247         return (codim == 1 ? 2 - i : i);
00248       }
00249 
00250       template< unsigned int codim >
00251       static unsigned int generic2dune ( unsigned int i )
00252       {
00253         return dune2generic< codim >( i );
00254       }
00255     };
00256     
00257     template<>
00258     struct MapNumbering< Pyramid< Pyramid< Point > > >
00259     : public MapNumberingTriangle
00260     {};
00261     
00262     template<>
00263     struct MapNumbering< Pyramid< Prism< Point > > >
00264     : public MapNumberingTriangle
00265     {};
00266 
00267 
00268     // MapNumbering for Quadrilateral
00269     template<>
00270     struct MapNumbering< Prism< Pyramid< Point > > >
00271     : public MapNumberingIdentical
00272     {};
00273 
00274     template<>
00275     struct MapNumbering< Prism< Prism< Point > > >
00276     : public MapNumberingIdentical
00277     {};
00278 
00279     // MapNumbering for Tetrahedron
00280     struct MapNumberingTetrahedron
00281     {
00282       template< unsigned int codim >
00283       static unsigned int dune2generic ( unsigned int i )
00284       {
00285         static unsigned int edge[ 6 ] = { 0, 2, 1, 3, 4, 5 };
00286         return (codim == 1 ? 3 - i : (codim == 2 ? edge[ i ] : i));
00287       }
00288 
00289       template< unsigned int codim >
00290       static unsigned int generic2dune ( unsigned int i )
00291       {
00292         return dune2generic< codim >( i );
00293       }
00294     };
00295 
00296     template<>
00297     struct MapNumbering< Pyramid< Pyramid< Pyramid< Point > > > >
00298     : public MapNumberingTetrahedron
00299     {};
00300     
00301     template<>
00302     struct MapNumbering< Pyramid< Pyramid< Prism< Point > > > >
00303     : public MapNumberingTetrahedron
00304     {};
00305 
00306     // MapNumbering for Cube
00307     struct MapNumberingCube
00308     {
00309       template< unsigned int codim >
00310       static unsigned int dune2generic ( unsigned int i )
00311       {
00312         static unsigned int edge[ 12 ] = { 0, 1, 2, 3, 4, 5, 8, 9, 6, 7, 10, 11 };
00313         return (codim == 2 ? edge[ i ] : i);
00314       }
00315 
00316       template< unsigned int codim >
00317       static unsigned int generic2dune ( unsigned int i )
00318       {
00319         return dune2generic< codim >( i );
00320       }
00321     };
00322     
00323     template<>
00324     struct MapNumbering< Prism< Prism< Pyramid< Point > > > >
00325     : public MapNumberingCube
00326     {};
00327     
00328     template<>
00329     struct MapNumbering< Prism< Prism< Prism< Point > > > >
00330     : public MapNumberingCube
00331     {};
00332 
00333     // MapNumbering for 4D-Cube
00334     struct MapNumbering4DCube
00335     {
00336       template< unsigned int codim >
00337       static unsigned int dune2generic ( unsigned int i )
00338       {
00339         static unsigned int codim2[ 24 ] =
00340           { 0, 1, 2, 3, 4, 5, 8, 9, 12, 13, 18, 19,
00341             6, 7, 10, 11, 14, 15, 20, 21, 16, 17, 22, 23 };
00342         static unsigned int codim3[ 32 ] =
00343           { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 20, 21, 22, 23,
00344             12, 13, 16, 17, 24, 25, 28, 29, 14, 15, 18, 19, 26, 27, 30, 31 };
00345         if (codim == 2)
00346           return codim2[i];
00347         else if (codim == 3)
00348           return codim3[i];
00349         else
00350           return i;
00351       }
00352 
00353       template< unsigned int codim >
00354       static unsigned int generic2dune ( unsigned int i )
00355       {
00356         static unsigned int codim2[ 24 ] =
00357           { 0, 1, 2, 3, 4, 5, 12, 13, 6, 7, 14, 15,
00358             8, 9, 16, 17, 20, 21, 10, 11, 18, 19, 22, 23 };
00359         static unsigned int codim3[ 32 ] =
00360           { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 16, 17, 24, 25,
00361             18, 19, 26, 27, 12, 13, 14, 15, 20, 21, 28, 29, 22, 23, 30, 31 };
00362         if (codim == 2)
00363           return codim2[i];
00364         else if (codim == 3)
00365           return codim3[i];
00366         else
00367           return i;
00368       }
00369     };
00370     
00371     template<>
00372     struct MapNumbering< Prism< Prism< Prism< Pyramid< Point > > > > >
00373     : public MapNumbering4DCube
00374     {};
00375     
00376     template<>
00377     struct MapNumbering< Prism< Prism< Prism< Prism< Point > > > > >
00378     : public MapNumbering4DCube
00379     {};
00380 
00381     // MapNumbering for Pyramid
00382     struct MapNumberingPyramid
00383     {
00384       template< unsigned int codim >
00385       static unsigned int dune2generic ( unsigned int i )
00386       {
00387         static unsigned int vertex[ 5 ] = { 0, 1, 3, 2, 4 };
00388         static unsigned int edge[ 8 ] = { 2, 1, 3, 0, 4, 5, 7, 6 };
00389         static unsigned int face[ 5 ] = { 0, 3, 2, 4, 1 };
00390         
00391         if( codim == 3 )
00392           return vertex[ i ];
00393         else if( codim == 2 )
00394           return edge[ i ];
00395         else if( codim == 1 )
00396           return face[ i ];
00397         else
00398           return i;
00399       }
00400 
00401       template< unsigned int codim >
00402       static unsigned int generic2dune ( unsigned int i )
00403       {
00404         static unsigned int vertex[ 5 ] = { 0, 1, 3, 2, 4 };
00405         static unsigned int edge[ 8 ] = { 3, 1, 0, 2, 4, 5, 7, 6 };
00406         static unsigned int face[ 5 ] = { 0, 4, 2, 1, 3 };
00407         
00408         if( codim == 3 )
00409           return vertex[ i ];
00410         else if( codim == 2 )
00411           return edge[ i ];
00412         else if( codim == 1 )
00413           return face[ i ];
00414         else
00415           return i;
00416       }
00417     };
00418     
00419     template<>
00420     struct MapNumbering< Pyramid< Prism< Pyramid< Point > > > >
00421     : public MapNumberingPyramid
00422     {};
00423     
00424     template<>
00425     struct MapNumbering< Pyramid< Prism< Prism< Point > > > >
00426     : public MapNumberingPyramid
00427     {};
00428 
00429     // MapNumbering for Prism
00430     struct MapNumberingPrism
00431     {
00432       template< unsigned int codim >
00433       static unsigned int dune2generic ( unsigned int i )
00434       {
00435         static unsigned int edge[ 9 ] = { 3, 5, 4, 0, 1, 2, 6, 8, 7 };
00436         static unsigned int face[ 5 ] = { 3, 0, 2, 1, 4 };
00437 
00438         if( codim == 2 )
00439           return edge[ i ];
00440         else if( codim == 1 )
00441           return face[ i ];
00442         else
00443           return i;
00444       }
00445 
00446       template< unsigned int codim >
00447       static unsigned int generic2dune ( unsigned int i )
00448       {
00449         static unsigned int edge[ 9 ] = { 3, 4, 5, 0, 2, 1, 6, 8, 7 };
00450         static unsigned int face[ 5 ] = { 1, 3, 2, 0, 4 };
00451 
00452         if( codim == 2 )
00453           return edge[ i ];
00454         else if( codim == 1 )
00455           return face[ i ];
00456         else
00457           return i;
00458       }
00459     };
00460 
00461     template<>
00462     struct MapNumbering< Prism< Pyramid< Pyramid< Point > > > >
00463     : public MapNumberingPrism
00464     {};
00465     
00466     template<>
00467     struct MapNumbering< Prism< Pyramid< Prism< Point > > > >
00468     : public MapNumberingPrism
00469     {};
00470 
00471 
00472 
00473     // MapNumberingProvider
00474     // --------------------
00475 
00476     template< unsigned int dim >
00477     struct MapNumberingProvider
00478     {
00479       static const unsigned int dimension = dim;
00480       static const unsigned int numTopologies = (1 << dimension);
00481 
00482     private:
00483       template< int i >
00484       struct Builder;
00485 
00486       typedef std :: vector< unsigned int > Map;
00487       
00488       Map dune2generic_[ numTopologies ][ dimension+1 ];
00489       Map generic2dune_[ numTopologies ][ dimension+1 ];
00490       
00491       MapNumberingProvider ()
00492       {
00493         ForLoop< Builder, 0, (1 << dim)-1 >::apply( dune2generic_, generic2dune_ );
00494       }
00495       
00496       static const MapNumberingProvider &instance ()
00497       {
00498         static MapNumberingProvider inst;
00499         return inst;
00500       }
00501       
00502     public:
00503       static unsigned int
00504       dune2generic ( unsigned int topologyId, unsigned int i, unsigned int codim )
00505       {
00506         assert( (topologyId < numTopologies) && (codim <= dimension) );
00507         assert( i < instance().dune2generic_[ topologyId ][ codim ].size() );
00508         return instance().dune2generic_[ topologyId ][ codim ][ i ];
00509       }
00510 
00511       template< unsigned int codim >
00512       static unsigned int
00513       dune2generic ( unsigned int topologyId, unsigned int i )
00514       {
00515         return dune2generic( topologyId, i, codim );
00516       }
00517 
00518       static unsigned int
00519       generic2dune ( unsigned int topologyId, unsigned int i, unsigned int codim )
00520       {
00521         assert( (topologyId < numTopologies) && (codim <= dimension) );
00522         assert( i < instance().dune2generic_[ topologyId ][ codim ].size() );
00523         return instance().generic2dune_[ topologyId ][ codim ][ i ];
00524       }
00525 
00526       template< unsigned int codim >
00527       static unsigned int
00528       generic2dune ( unsigned int topologyId, unsigned int i )
00529       {
00530         return generic2dune( topologyId, i, codim );
00531       }
00532     };
00533 
00534 
00535     template< unsigned int dim >
00536     template< int topologyId >
00537     struct MapNumberingProvider< dim >::Builder
00538     {
00539       typedef typename GenericGeometry::Topology< topologyId, dimension >::type Topology;
00540       typedef GenericGeometry::MapNumbering< Topology > MapNumbering;
00541 
00542       template< int codim >
00543       struct Codim;
00544       
00545       static void apply ( Map (&dune2generic)[ numTopologies ][ dimension+1 ],
00546                           Map (&generic2dune)[ numTopologies ][ dimension+1 ] )
00547       {
00548         ForLoop< Codim, 0, dimension >::apply( dune2generic[ topologyId ], generic2dune[ topologyId ] );
00549       }
00550     };
00551 
00552     template< unsigned int dim >
00553     template< int i >
00554     template< int codim >
00555     struct MapNumberingProvider< dim >::Builder< i >::Codim
00556     {
00557       static void apply ( Map (&dune2generic)[ dimension+1 ],
00558                           Map (&generic2dune)[ dimension+1 ] )
00559       {
00560         const unsigned int size = Size< Topology, codim >::value;
00561 
00562         Map &d2g = dune2generic[ codim ];
00563         d2g.resize( size );
00564         for( unsigned int j = 0; j < size; ++j )
00565           d2g[ j ] = MapNumbering::template dune2generic< codim >( j );
00566 
00567         Map &g2d = generic2dune[ codim ];
00568         g2d.resize( size );
00569         for( unsigned int j = 0; j < size; ++j )
00570           g2d[ j ] = MapNumbering::template generic2dune< codim >( j );
00571       }
00572     };
00573 
00574 
00575 
00576     // Convert
00577     // -------
00578 
00579     template< GeometryType :: BasicType type, unsigned int dim >
00580     struct Convert;
00581 
00582     template< unsigned int dim >
00583     struct Convert< GeometryType :: simplex, dim >
00584     {
00585       typedef Pyramid
00586         < typename Convert< GeometryType :: simplex, dim-1 > :: type >
00587         type;
00588 
00589       template< unsigned int codim >
00590       static unsigned int map ( unsigned int i )
00591       {
00592         return MapNumbering<type>::template dune2generic<codim>(i);
00593       }
00594     };
00595     
00596     template<>
00597     struct Convert< GeometryType :: simplex, 0 >
00598     {
00599       typedef Point type;
00600 
00601       template< unsigned int codim >
00602       static unsigned int map ( unsigned int i )
00603       {
00604         return MapNumbering<type>::template dune2generic<codim>(i);
00605       }
00606     };
00607     
00608     template< unsigned int dim >
00609     struct Convert< GeometryType :: cube, dim >
00610     {
00611       typedef Prism< typename Convert< GeometryType :: cube, dim-1 > :: type >
00612         type;
00613 
00614       template< unsigned int codim >
00615       static unsigned int map ( unsigned int i )
00616       {
00617         return MapNumbering<type>::template dune2generic<codim>(i);
00618       }
00619     };
00620     
00621     template<>
00622     struct Convert< GeometryType :: cube, 0 >
00623     {
00624       typedef Point type;
00625 
00626       template< unsigned int codim >
00627       static unsigned int map ( unsigned int i )
00628       {
00629         return MapNumbering<type>::template dune2generic<codim>(i);
00630       }
00631     };
00632     
00633     template< unsigned int dim >
00634     struct Convert< GeometryType :: prism, dim >
00635     {
00636       typedef Prism
00637         < typename Convert< GeometryType :: simplex, dim-1 > :: type >
00638         type;
00639 
00640       template< unsigned int codim >
00641       static unsigned int map ( unsigned int i )
00642       {
00643         return MapNumbering<type>::template dune2generic<codim>(i);
00644       }
00645 
00646     private:
00647       // dune_static_assert( dim >= 3, "Dune prisms must be at least 3-dimensional." );
00648     };
00649     
00650     template< unsigned int dim >
00651     struct Convert< GeometryType :: pyramid, dim >
00652     {
00653       typedef Pyramid
00654         < typename Convert< GeometryType :: cube, dim-1 > :: type >
00655         type;
00656 
00657       // Note that we map dune numbering into the generic one
00658       // this is only important for pyramids
00659       template< unsigned int codim >
00660       static unsigned int map ( unsigned int i )
00661       {
00662         return MapNumbering<type>::template dune2generic<codim>(i);
00663       }
00664 
00665     private:
00666       // dune_static_assert( dim >= 3, "Dune pyramids must be at least 3-dimensional." );
00667     };
00668 
00669 
00670 
00671 
00672     // topologyId
00673     // ----------
00674 
00676 
00683     inline unsigned int topologyId ( const GeometryType &type ) DUNE_DEPRECATED_MSG("use GeometryType::id() instead");
00684     inline unsigned int topologyId ( const GeometryType &type )
00685     {
00686       return type.id();
00687     }
00688 
00689 
00690 
00691     // hasGeometryType
00692     // ---------------
00693 
00694     inline bool
00695     hasGeometryType ( const unsigned int topologyId, const unsigned int dimension ) DUNE_DEPRECATED;
00696     inline bool
00697     hasGeometryType ( const unsigned int topologyId, const unsigned int dimension )
00698     {
00699       return true;
00700     }
00701 
00702 
00703     // geometryType
00704     // ------------
00708     inline GeometryType
00709     geometryType ( const unsigned int topologyId, const unsigned int dimension ) DUNE_DEPRECATED_MSG("Construct a GeometryTpye directly instead");
00710     inline GeometryType
00711     geometryType ( const unsigned int topologyId, const unsigned int dimension )
00712     {
00713       return GeometryType( topologyId, dimension );
00714     }
00715 
00716   }
00717   
00718 }
00719 
00720 #endif // #ifndef DUNE_GEOMETRY_GENERICGEOMETRY_CONVERSION_HH