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