dune-geometry  2.2.0
conversion.hh
Go to the documentation of this file.
1 #ifndef DUNE_GEOMETRY_GENERICGEOMETRY_CONVERSION_HH
2 #define DUNE_GEOMETRY_GENERICGEOMETRY_CONVERSION_HH
3 
4 #include <dune/common/static_assert.hh>
5 
6 #include <dune/geometry/type.hh>
9 
10 namespace Dune
11 {
12 
20  {
21  unsigned int i;
22  public:
24  #ifndef DEPRECATEDINT
25  operator unsigned int () { return i; }
26  #endif
27  unsigned int value() { return i; };
28  #ifdef DEPRECATEDINT
29  explicit
30  #endif
31  deprecated_int(unsigned int j) : i(j) {};
32  };
33 
34  namespace GenericGeometry
35  {
36 
37  // DuneGeometryType
38  // ----------------
39 
47  template< class Topology, GeometryType::BasicType linetype >
48  class DuneGeometryType;
49 
50  template< GeometryType::BasicType linetype >
51  class DuneGeometryType< Point, linetype >
52  {
53  dune_static_assert( (linetype == GeometryType::simplex)
54  || (linetype == GeometryType::cube),
55  "Parameter linetype may only be a simplex or a cube." );
56 
57  public:
58  static const unsigned int dimension = 0;
59  static const GeometryType::BasicType basicType = linetype;
60 
61  // GeometryType can be initialized directly with the topologyId
62  static GeometryType type () DUNE_DEPRECATED
63  {
64  return GeometryType( basicType, dimension );
65  }
66  };
67 
68  template< class BaseTopology, GeometryType::BasicType linetype >
69  class DuneGeometryType< Prism< BaseTopology >, linetype >
70  {
72 
73  dune_static_assert( (linetype == GeometryType::simplex)
74  || (linetype == GeometryType::cube),
75  "Parameter linetype may only be a simplex or a cube." );
76 
77  dune_static_assert( (DuneBaseGeometryType::basicType == GeometryType::simplex)
78  || (DuneBaseGeometryType::basicType == GeometryType::cube),
79  "Only prisms over simplices or cubes can be converted." );
80 
81  public:
82  static const unsigned int dimension = DuneBaseGeometryType::dimension + 1;
83  static const GeometryType::BasicType basicType
84  = ((dimension == 1)
85  ? linetype
86  : ((dimension == 2) || (DuneBaseGeometryType::basicType == GeometryType::cube))
89 
90  // GeometryType can be initialized directly with the topologyId
91  static GeometryType type () DUNE_DEPRECATED
92  {
93  return GeometryType( basicType, dimension );
94  }
95  };
96 
97  template< class BaseTopology, GeometryType::BasicType linetype >
98  class DuneGeometryType< Pyramid< BaseTopology >, linetype >
99  {
101 
102  dune_static_assert( (linetype == GeometryType::simplex)
103  || (linetype == GeometryType::cube),
104  "Parameter linetype may only be a simplex or a cube." );
105 
106  dune_static_assert( (DuneBaseGeometryType::basicType == GeometryType::simplex)
107  || (DuneBaseGeometryType::basicType == GeometryType::cube),
108  "Only pyramids over simplices or cubes can be converted." );
109 
110  public:
111  static const unsigned int dimension = DuneBaseGeometryType::dimension + 1;
112  static const GeometryType::BasicType basicType
113  = ((dimension == 1)
114  ? linetype
115  : ((dimension == 2) || (DuneBaseGeometryType::basicType == GeometryType::simplex))
118 
119  // GeometryType can be initialized directly with the topologyId
120  static GeometryType type () DUNE_DEPRECATED
121  {
122  return GeometryType( basicType, dimension );
123  }
124  };
125 
126 
127 
128  // DuneGeometryTypeProvider
129  // ------------------------
130 
142  template< unsigned int dim, GeometryType::BasicType linetype >
144  {
146  static const unsigned int dimension = dim;
147 
149  static const unsigned int numTopologies = (1 << dimension);
150 
151  private:
152  GeometryType types_[ (dimension>=1)? numTopologies / 2 : numTopologies ];
153 
154  // GeometryType can be initialized directly with the topologyId
155  DuneGeometryTypeProvider () DUNE_DEPRECATED
156  {
157  if( dimension > 3 )
158  {
159  for( unsigned int i = 0; i < numTopologies / 2; ++i )
160  types_[ i ].makeNone( dimension );
161  }
162 
163  if( dimension >= 3 )
164  {
165  const unsigned int d = (dimension >= 2 ? dimension-2 : 0);
166  types_[ 0 ].makeSimplex( dimension );
167  types_[ (1 << d) ] = GeometryType( GeometryType::prism, dimension );
168  types_[ (1 << d) - 1 ] = GeometryType( GeometryType::pyramid, dimension );
169  types_[ (1 << (d+1)) - 1 ].makeCube( dimension );
170  }
171  else if( dimension == 2 )
172  {
173  types_[ 0 ].makeSimplex( dimension );
174  types_[ 1 ].makeCube( dimension );
175  }
176  else
177  types_[ 0 ] = GeometryType( linetype, dimension );
178  }
179 
180  static const DuneGeometryTypeProvider &instance ()
181  {
182  static DuneGeometryTypeProvider inst;
183  return inst;
184  }
185 
186  public:
193  static const GeometryType &type ( unsigned int topologyId )
194  {
195  assert( topologyId < numTopologies );
196  return instance().types_[ topologyId / 2 ];
197  }
198  };
199 
200 
201 
202  // MapNumbering
203  // ------------
204 
205  template< class Topology >
206  struct MapNumbering;
207 
208 
210  {
211  template< unsigned int codim >
212  static unsigned int dune2generic ( unsigned int i )
213  {
214  return i;
215  }
216 
217  template< unsigned int codim >
218  static unsigned int generic2dune ( unsigned int i )
219  {
220  return i;
221  }
222  };
223 
224  // MapNumbering for Point
225  template<>
226  struct MapNumbering< Point >
227  : public MapNumberingIdentical
228  {};
229 
230  // MapNumbering for Line
231  template<>
232  struct MapNumbering< Prism< Point > >
233  : public MapNumberingIdentical
234  {};
235 
236  template<>
237  struct MapNumbering< Pyramid< Point > >
238  : public MapNumberingIdentical
239  {};
240 
241  // MapNumbering for Triangle
243  {
244  template< unsigned int codim >
245  static unsigned int dune2generic ( unsigned int i )
246  {
247  return (codim == 1 ? 2 - i : i);
248  }
249 
250  template< unsigned int codim >
251  static unsigned int generic2dune ( unsigned int i )
252  {
253  return dune2generic< codim >( i );
254  }
255  };
256 
257  template<>
258  struct MapNumbering< Pyramid< Pyramid< Point > > >
259  : public MapNumberingTriangle
260  {};
261 
262  template<>
263  struct MapNumbering< Pyramid< Prism< Point > > >
264  : public MapNumberingTriangle
265  {};
266 
267 
268  // MapNumbering for Quadrilateral
269  template<>
270  struct MapNumbering< Prism< Pyramid< Point > > >
271  : public MapNumberingIdentical
272  {};
273 
274  template<>
275  struct MapNumbering< Prism< Prism< Point > > >
276  : public MapNumberingIdentical
277  {};
278 
279  // MapNumbering for Tetrahedron
281  {
282  template< unsigned int codim >
283  static unsigned int dune2generic ( unsigned int i )
284  {
285  static unsigned int edge[ 6 ] = { 0, 2, 1, 3, 4, 5 };
286  return (codim == 1 ? 3 - i : (codim == 2 ? edge[ i ] : i));
287  }
288 
289  template< unsigned int codim >
290  static unsigned int generic2dune ( unsigned int i )
291  {
292  return dune2generic< codim >( i );
293  }
294  };
295 
296  template<>
297  struct MapNumbering< Pyramid< Pyramid< Pyramid< Point > > > >
298  : public MapNumberingTetrahedron
299  {};
300 
301  template<>
302  struct MapNumbering< Pyramid< Pyramid< Prism< Point > > > >
303  : public MapNumberingTetrahedron
304  {};
305 
306  // MapNumbering for Cube
308  {
309  template< unsigned int codim >
310  static unsigned int dune2generic ( unsigned int i )
311  {
312  static unsigned int edge[ 12 ] = { 0, 1, 2, 3, 4, 5, 8, 9, 6, 7, 10, 11 };
313  return (codim == 2 ? edge[ i ] : i);
314  }
315 
316  template< unsigned int codim >
317  static unsigned int generic2dune ( unsigned int i )
318  {
319  return dune2generic< codim >( i );
320  }
321  };
322 
323  template<>
324  struct MapNumbering< Prism< Prism< Pyramid< Point > > > >
325  : public MapNumberingCube
326  {};
327 
328  template<>
329  struct MapNumbering< Prism< Prism< Prism< Point > > > >
330  : public MapNumberingCube
331  {};
332 
333  // MapNumbering for 4D-Cube
335  {
336  template< unsigned int codim >
337  static unsigned int dune2generic ( unsigned int i )
338  {
339  static unsigned int codim2[ 24 ] =
340  { 0, 1, 2, 3, 4, 5, 8, 9, 12, 13, 18, 19,
341  6, 7, 10, 11, 14, 15, 20, 21, 16, 17, 22, 23 };
342  static unsigned int codim3[ 32 ] =
343  { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 20, 21, 22, 23,
344  12, 13, 16, 17, 24, 25, 28, 29, 14, 15, 18, 19, 26, 27, 30, 31 };
345  if (codim == 2)
346  return codim2[i];
347  else if (codim == 3)
348  return codim3[i];
349  else
350  return i;
351  }
352 
353  template< unsigned int codim >
354  static unsigned int generic2dune ( unsigned int i )
355  {
356  static unsigned int codim2[ 24 ] =
357  { 0, 1, 2, 3, 4, 5, 12, 13, 6, 7, 14, 15,
358  8, 9, 16, 17, 20, 21, 10, 11, 18, 19, 22, 23 };
359  static unsigned int codim3[ 32 ] =
360  { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 16, 17, 24, 25,
361  18, 19, 26, 27, 12, 13, 14, 15, 20, 21, 28, 29, 22, 23, 30, 31 };
362  if (codim == 2)
363  return codim2[i];
364  else if (codim == 3)
365  return codim3[i];
366  else
367  return i;
368  }
369  };
370 
371  template<>
372  struct MapNumbering< Prism< Prism< Prism< Pyramid< Point > > > > >
373  : public MapNumbering4DCube
374  {};
375 
376  template<>
377  struct MapNumbering< Prism< Prism< Prism< Prism< Point > > > > >
378  : public MapNumbering4DCube
379  {};
380 
381  // MapNumbering for Pyramid
383  {
384  template< unsigned int codim >
385  static unsigned int dune2generic ( unsigned int i )
386  {
387  static unsigned int vertex[ 5 ] = { 0, 1, 3, 2, 4 };
388  static unsigned int edge[ 8 ] = { 2, 1, 3, 0, 4, 5, 7, 6 };
389  static unsigned int face[ 5 ] = { 0, 3, 2, 4, 1 };
390 
391  if( codim == 3 )
392  return vertex[ i ];
393  else if( codim == 2 )
394  return edge[ i ];
395  else if( codim == 1 )
396  return face[ i ];
397  else
398  return i;
399  }
400 
401  template< unsigned int codim >
402  static unsigned int generic2dune ( unsigned int i )
403  {
404  static unsigned int vertex[ 5 ] = { 0, 1, 3, 2, 4 };
405  static unsigned int edge[ 8 ] = { 3, 1, 0, 2, 4, 5, 7, 6 };
406  static unsigned int face[ 5 ] = { 0, 4, 2, 1, 3 };
407 
408  if( codim == 3 )
409  return vertex[ i ];
410  else if( codim == 2 )
411  return edge[ i ];
412  else if( codim == 1 )
413  return face[ i ];
414  else
415  return i;
416  }
417  };
418 
419  template<>
420  struct MapNumbering< Pyramid< Prism< Pyramid< Point > > > >
421  : public MapNumberingPyramid
422  {};
423 
424  template<>
425  struct MapNumbering< Pyramid< Prism< Prism< Point > > > >
426  : public MapNumberingPyramid
427  {};
428 
429  // MapNumbering for Prism
431  {
432  template< unsigned int codim >
433  static unsigned int dune2generic ( unsigned int i )
434  {
435  static unsigned int edge[ 9 ] = { 3, 5, 4, 0, 1, 2, 6, 8, 7 };
436  static unsigned int face[ 5 ] = { 3, 0, 2, 1, 4 };
437 
438  if( codim == 2 )
439  return edge[ i ];
440  else if( codim == 1 )
441  return face[ i ];
442  else
443  return i;
444  }
445 
446  template< unsigned int codim >
447  static unsigned int generic2dune ( unsigned int i )
448  {
449  static unsigned int edge[ 9 ] = { 3, 4, 5, 0, 2, 1, 6, 8, 7 };
450  static unsigned int face[ 5 ] = { 1, 3, 2, 0, 4 };
451 
452  if( codim == 2 )
453  return edge[ i ];
454  else if( codim == 1 )
455  return face[ i ];
456  else
457  return i;
458  }
459  };
460 
461  template<>
462  struct MapNumbering< Prism< Pyramid< Pyramid< Point > > > >
463  : public MapNumberingPrism
464  {};
465 
466  template<>
467  struct MapNumbering< Prism< Pyramid< Prism< Point > > > >
468  : public MapNumberingPrism
469  {};
470 
471 
472 
473  // MapNumberingProvider
474  // --------------------
475 
476  template< unsigned int dim >
478  {
479  static const unsigned int dimension = dim;
480  static const unsigned int numTopologies = (1 << dimension);
481 
482  private:
483  template< int i >
484  struct Builder;
485 
486  typedef std :: vector< unsigned int > Map;
487 
488  Map dune2generic_[ numTopologies ][ dimension+1 ];
489  Map generic2dune_[ numTopologies ][ dimension+1 ];
490 
492  {
493  ForLoop< Builder, 0, (1 << dim)-1 >::apply( dune2generic_, generic2dune_ );
494  }
495 
496  static const MapNumberingProvider &instance ()
497  {
498  static MapNumberingProvider inst;
499  return inst;
500  }
501 
502  public:
503  static unsigned int
504  dune2generic ( unsigned int topologyId, unsigned int i, unsigned int codim )
505  {
506  assert( (topologyId < numTopologies) && (codim <= dimension) );
507  assert( i < instance().dune2generic_[ topologyId ][ codim ].size() );
508  return instance().dune2generic_[ topologyId ][ codim ][ i ];
509  }
510 
511  template< unsigned int codim >
512  static unsigned int
513  dune2generic ( unsigned int topologyId, unsigned int i )
514  {
515  return dune2generic( topologyId, i, codim );
516  }
517 
518  static unsigned int
519  generic2dune ( unsigned int topologyId, unsigned int i, unsigned int codim )
520  {
521  assert( (topologyId < numTopologies) && (codim <= dimension) );
522  assert( i < instance().dune2generic_[ topologyId ][ codim ].size() );
523  return instance().generic2dune_[ topologyId ][ codim ][ i ];
524  }
525 
526  template< unsigned int codim >
527  static unsigned int
528  generic2dune ( unsigned int topologyId, unsigned int i )
529  {
530  return generic2dune( topologyId, i, codim );
531  }
532  };
533 
534 
535  template< unsigned int dim >
536  template< int topologyId >
538  {
540  typedef GenericGeometry::MapNumbering< Topology > MapNumbering;
541 
542  template< int codim >
543  struct Codim;
544 
545  static void apply ( Map (&dune2generic)[ numTopologies ][ dimension+1 ],
546  Map (&generic2dune)[ numTopologies ][ dimension+1 ] )
547  {
548  ForLoop< Codim, 0, dimension >::apply( dune2generic[ topologyId ], generic2dune[ topologyId ] );
549  }
550  };
551 
552  template< unsigned int dim >
553  template< int i >
554  template< int codim >
555  struct MapNumberingProvider< dim >::Builder< i >::Codim
556  {
557  static void apply ( Map (&dune2generic)[ dimension+1 ],
558  Map (&generic2dune)[ dimension+1 ] )
559  {
560  const unsigned int size = Size< Topology, codim >::value;
561 
562  Map &d2g = dune2generic[ codim ];
563  d2g.resize( size );
564  for( unsigned int j = 0; j < size; ++j )
565  d2g[ j ] = MapNumbering::template dune2generic< codim >( j );
566 
567  Map &g2d = generic2dune[ codim ];
568  g2d.resize( size );
569  for( unsigned int j = 0; j < size; ++j )
570  g2d[ j ] = MapNumbering::template generic2dune< codim >( j );
571  }
572  };
573 
574 
575 
576  // Convert
577  // -------
578 
579  template< GeometryType :: BasicType type, unsigned int dim >
580  struct Convert;
581 
582  template< unsigned int dim >
583  struct Convert< GeometryType :: simplex, dim >
584  {
585  typedef Pyramid
586  < typename Convert< GeometryType :: simplex, dim-1 > :: type >
588 
589  template< unsigned int codim >
590  static unsigned int map ( unsigned int i )
591  {
592  return MapNumbering<type>::template dune2generic<codim>(i);
593  }
594  };
595 
596  template<>
597  struct Convert< GeometryType :: simplex, 0 >
598  {
599  typedef Point type;
600 
601  template< unsigned int codim >
602  static unsigned int map ( unsigned int i )
603  {
604  return MapNumbering<type>::template dune2generic<codim>(i);
605  }
606  };
607 
608  template< unsigned int dim >
609  struct Convert< GeometryType :: cube, dim >
610  {
611  typedef Prism< typename Convert< GeometryType :: cube, dim-1 > :: type >
613 
614  template< unsigned int codim >
615  static unsigned int map ( unsigned int i )
616  {
617  return MapNumbering<type>::template dune2generic<codim>(i);
618  }
619  };
620 
621  template<>
622  struct Convert< GeometryType :: cube, 0 >
623  {
624  typedef Point type;
625 
626  template< unsigned int codim >
627  static unsigned int map ( unsigned int i )
628  {
629  return MapNumbering<type>::template dune2generic<codim>(i);
630  }
631  };
632 
633  template< unsigned int dim >
634  struct Convert< GeometryType :: prism, dim >
635  {
636  typedef Prism
637  < typename Convert< GeometryType :: simplex, dim-1 > :: type >
639 
640  template< unsigned int codim >
641  static unsigned int map ( unsigned int i )
642  {
643  return MapNumbering<type>::template dune2generic<codim>(i);
644  }
645 
646  private:
647  // dune_static_assert( dim >= 3, "Dune prisms must be at least 3-dimensional." );
648  };
649 
650  template< unsigned int dim >
651  struct Convert< GeometryType :: pyramid, dim >
652  {
653  typedef Pyramid
654  < typename Convert< GeometryType :: cube, dim-1 > :: type >
656 
657  // Note that we map dune numbering into the generic one
658  // this is only important for pyramids
659  template< unsigned int codim >
660  static unsigned int map ( unsigned int i )
661  {
662  return MapNumbering<type>::template dune2generic<codim>(i);
663  }
664 
665  private:
666  // dune_static_assert( dim >= 3, "Dune pyramids must be at least 3-dimensional." );
667  };
668 
669 
670 
671 
672  // topologyId
673  // ----------
674 
676 
683  inline unsigned int topologyId ( const GeometryType &type ) DUNE_DEPRECATED_MSG("use GeometryType::id() instead");
684  inline unsigned int topologyId ( const GeometryType &type )
685  {
686  return type.id();
687  }
688 
689 
690 
691  // hasGeometryType
692  // ---------------
693 
694  inline bool
695  hasGeometryType ( const unsigned int topologyId, const unsigned int dimension ) DUNE_DEPRECATED;
696  inline bool
697  hasGeometryType ( const unsigned int topologyId, const unsigned int dimension )
698  {
699  return true;
700  }
701 
702 
703  // geometryType
704  // ------------
708  inline GeometryType
709  geometryType ( const unsigned int topologyId, const unsigned int dimension ) DUNE_DEPRECATED_MSG("Construct a GeometryTpye directly instead");
710  inline GeometryType
711  geometryType ( const unsigned int topologyId, const unsigned int dimension )
712  {
713  return GeometryType( topologyId, dimension );
714  }
715 
716  }
717 
718 }
719 
720 #endif // #ifndef DUNE_GEOMETRY_GENERICGEOMETRY_CONVERSION_HH