dune-geometry
2.2.0
|
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