dune-geometry  2.2.0
mappingprovider.hh
Go to the documentation of this file.
00001 #ifndef DUNE_GEOMETRY_GENERICGEOMETRY_MAPPINGPROVIDER_HH
00002 #define DUNE_GEOMETRY_GENERICGEOMETRY_MAPPINGPROVIDER_HH
00003 
00004 #include <dune/common/typetraits.hh>
00005 
00006 #include <dune/geometry/genericgeometry/maximum.hh>
00007 #include <dune/geometry/genericgeometry/conversion.hh>
00008 #include <dune/geometry/genericgeometry/cachedmapping.hh>
00009 #include <dune/geometry/genericgeometry/hybridmapping.hh>
00010 
00011 namespace Dune
00012 {
00013 
00014   namespace GenericGeometry
00015   {
00016 
00017     // NonHybridMappingFactory
00018     // -----------------------
00019 
00020     template< class Topology, class GeometryTraits >
00021     class NonHybridMappingFactory
00022     {
00023       typedef NonHybridMappingFactory< Topology, GeometryTraits > This;
00024 
00025     public:
00026       typedef NonHybridMapping< Topology, GeometryTraits > Mapping;
00027 
00028       static const unsigned int maxMappingSize = sizeof( Mapping );
00029 
00030       template< class CoordVector >
00031       static Mapping*
00032       construct ( const unsigned int topologyId, const CoordVector &coords, char *mappingStorage )
00033       {
00034         assert( (topologyId >> 1) == (Topology::id >> 1) );
00035         return new( mappingStorage ) Mapping( coords );
00036       }
00037 
00038       static std::size_t mappingSize ( const unsigned int topologyId )
00039       {
00040         return sizeof( Mapping );
00041       }
00042     };
00043 
00044 
00045 
00046     // VirtualMappingFactory
00047     // ---------------------
00048 
00049     template< unsigned int dim, class GeometryTraits >
00050     class VirtualMappingFactory
00051     {
00052       typedef VirtualMappingFactory< dim, GeometryTraits > This;
00053 
00054       static const unsigned int numTopologies = (1 << dim);
00055 
00056       template< int topologyId >
00057       struct MappingSize
00058       {
00059         typedef typename GenericGeometry::Topology< (unsigned int)topologyId, dim >::type Topology;
00060         static const int v = sizeof( VirtualMapping< Topology, GeometryTraits > );
00061 
00062         static void apply ( std::size_t (&mappingSize)[ numTopologies ] )
00063         {
00064           mappingSize[ topologyId ] = v;
00065         }
00066       };
00067 
00068       template< class CoordVector >
00069       class ConstructorTable;
00070 
00071       struct MappingSizeCache;
00072 
00073     public:
00074       typedef HybridMapping< dim, GeometryTraits > Mapping;
00075 
00076       static const unsigned int maxMappingSize = Maximum< MappingSize, 0, numTopologies-1 >::v;
00077 
00078       template< class CoordVector >
00079       static Mapping*
00080       construct ( const unsigned int topologyId, const CoordVector &coords, char *mappingStorage )
00081       {
00082         static ConstructorTable< CoordVector > construct;
00083         return construct[ topologyId ]( coords, mappingStorage );
00084       }
00085 
00086       static std::size_t mappingSize ( const unsigned int topologyId )
00087       {
00088         static MappingSizeCache mappingSize;
00089         return mappingSize[ topologyId ];
00090       }
00091     };
00092 
00093 
00094     // VirtualMappingFactory::ConstructorTable
00095     // ---------------------------------------
00096 
00097     template< unsigned int dim, class GeometryTraits >
00098     template< class CoordVector >
00099     class VirtualMappingFactory< dim, GeometryTraits >::ConstructorTable
00100     {
00101       typedef Mapping* (*Construct) ( const CoordVector &coords, char *mappingStorage );
00102 
00103       template< int i >
00104       struct Builder;
00105 
00106     public:
00107       ConstructorTable ()
00108       {
00109         ForLoop< Builder, 0, numTopologies-1 >::apply( construct_ );
00110       }
00111 
00112       Construct operator[] ( const unsigned int topologyId )
00113       {
00114         assert( topologyId < numTopologies );
00115         return construct_[ topologyId ];
00116       }
00117 
00118     private:
00119       template< class Topology >
00120       static Mapping*
00121       construct ( const CoordVector &coords, char *mappingStorage )
00122       {
00123         typedef VirtualMapping< Topology, GeometryTraits > VMapping;
00124         return new( mappingStorage ) VMapping( coords );
00125       }
00126 
00127       Construct construct_[ numTopologies ];
00128     };
00129 
00130 
00131     // VirtualMappingFactory::ConstructorTable::Builder
00132     // ------------------------------------------------
00133 
00134     template< unsigned int dim, class GeometryTraits >
00135     template< class CoordVector >
00136     template< int topologyId >
00137     struct VirtualMappingFactory< dim, GeometryTraits >::ConstructorTable< CoordVector >::Builder
00138     {
00139       static void apply ( Construct (&construct)[ numTopologies ] )
00140       {
00141         typedef typename GenericGeometry::Topology< (unsigned int)topologyId, dim >::type Topology;
00142         construct[ topologyId ] = ConstructorTable< CoordVector >::template construct< Topology >;
00143       }
00144     };
00145 
00146 
00147 
00148     // VirtualMappingFactory::MappingSizeCache
00149     // ---------------------------------------
00150 
00151     template< unsigned int dim, class GeometryTraits >
00152     struct VirtualMappingFactory< dim, GeometryTraits >::MappingSizeCache
00153     {
00154       MappingSizeCache ()
00155       {
00156         ForLoop< MappingSize, 0, numTopologies-1 >::apply( size_ );
00157       }
00158 
00159       std::size_t operator[] ( const unsigned int topologyId )
00160       {
00161         assert( topologyId < numTopologies );
00162         return size_[ topologyId ];
00163       }
00164 
00165     private:
00166       std::size_t size_[ numTopologies ];
00167     };
00168 
00169 
00170 
00171     // MappingProvider
00172     // ---------------
00173 
00174     template< class ElementMapping, unsigned int codim >
00175     class MappingProvider;
00176 
00177 
00178     template< unsigned int dim, class GeometryTraits, unsigned int codim >
00179     class MappingProvider< HybridMapping< dim, GeometryTraits >, codim >
00180     {
00181       typedef MappingProvider< HybridMapping< dim, GeometryTraits >, codim > This;
00182 
00183     public:
00184       static const unsigned int dimension = dim;
00185       static const unsigned int codimension = codim;
00186       static const unsigned int mydimension = dimension - codimension;
00187 
00188     private:
00189       typedef VirtualMappingFactory< mydimension, GeometryTraits > Factory;
00190 
00191     public:
00192       // Maximal amount of memory required to store a mapping
00193       static const unsigned int maxMappingSize = Factory::maxMappingSize;
00194 
00195       typedef typename Factory::Mapping Mapping;
00196 
00197       template< class CoordVector >
00198       static Mapping*
00199       construct ( const unsigned int topologyId, const CoordVector &coords, char *mappingStorage )
00200       {
00201         return Factory::construct( topologyId, coords, mappingStorage );
00202       }
00203 
00204       template< class CoordVector >
00205       static Mapping *create ( const unsigned int topologyId, const CoordVector &coords )
00206       {
00207         char *mapping = new char[ mappingSize( topologyId ) ];
00208         return construct( topologyId, coords, mapping );
00209       }
00210 
00211       static std::size_t mappingSize ( const unsigned int topologyId )
00212       {
00213         return Factory::mappingSize( topologyId );
00214       }
00215     };
00216 
00217 
00218     template< class Topology, class GeometryTraits, unsigned int codim >
00219     class MappingProvider< NonHybridMapping< Topology, GeometryTraits >, codim >
00220     {
00221       typedef MappingProvider< NonHybridMapping< Topology, GeometryTraits >, codim > This;
00222 
00223     public:
00224       static const unsigned int dimension = Topology::dimension;
00225       static const unsigned int codimension = codim;
00226       static const unsigned int mydimension = dimension - codimension;
00227 
00228       static const bool hybrid = IsCodimHybrid< Topology, codim >::value;
00229 
00230     private:
00231       template< bool >
00232       struct HybridFactory
00233       : public VirtualMappingFactory< mydimension, GeometryTraits >
00234       {};
00235 
00236       template< bool >
00237       struct NonHybridFactory
00238       : public NonHybridMappingFactory
00239         < typename SubTopology< Topology, codim, 0 >::type, GeometryTraits >
00240       {};
00241 
00242       typedef typename SelectType< hybrid, HybridFactory<true>, NonHybridFactory<false> >::Type Factory;
00243 
00244     public:
00245       // Maximal amount of memory required to store a mapping
00246       static const unsigned int maxMappingSize = Factory::maxMappingSize;
00247 
00248       typedef typename Factory::Mapping Mapping;
00249 
00250       template< class CoordVector >
00251       static Mapping*
00252       construct ( const unsigned int topologyId, const CoordVector &coords, char *mappingStorage )
00253       {
00254         return Factory::construct( topologyId, coords, mappingStorage );
00255       }
00256 
00257       template< class CoordVector >
00258       static Mapping *create ( const unsigned int topologyId, const CoordVector &coords )
00259       {
00260         Mapping *mapping = static_cast< Mapping * >( operator new( mappingSize( topologyId ) ) );
00261         construct( topologyId, coords, mapping );
00262         return mapping;
00263       }
00264 
00265       static std::size_t mappingSize ( const unsigned int topologyId )
00266       {
00267         return Factory::mappingSize( topologyId );
00268       }
00269     };
00270 
00271   } // namespace GenericGeometry
00272 
00273 } // namespace Dune
00274 
00275 #endif // #ifndef DUNE_GEOMETRY_GENERICGEOMETRY_MAPPINGPROVIDER_HH