3 #ifndef DUNE_GEOMETRY_GENERICGEOMETRY_SUBTOPOLOGIES_HH
4 #define DUNE_GEOMETRY_GENERICGEOMETRY_SUBTOPOLOGIES_HH
9 #include <dune/common/forloop.hh>
10 #include <dune/common/static_assert.hh>
11 #include <dune/common/typetraits.hh>
12 #include <dune/common/visibility.hh>
13 #include <dune/common/unused.hh>
20 namespace GenericGeometry
23 template<
class Topology,
unsigned int codim >
26 template<
class Topology,
unsigned int codim,
unsigned int i >
29 template<
class Topology,
unsigned int codim,
unsigned int subcodim >
30 class SubTopologySize;
32 template<
class Topology,
unsigned int codim,
unsigned int subcodim >
33 class GenericSubTopologyNumbering;
35 template<
class Topology,
unsigned int codim,
unsigned int subcodim >
36 class SubTopologyNumbering;
43 template<
class Topology,
unsigned int dim,
unsigned int codim >
46 template<
unsigned int dim,
unsigned int codim >
47 class SizeImpl<
Point, dim, codim >
50 dune_static_assert( (dim == Topology :: dimension),
"Wrong dimension" );
51 dune_static_assert( (codim <= dim),
"Invalid codimension" );
57 template<
class BaseTopology,
unsigned int dim,
unsigned int codim >
58 class SizeImpl<
Prism< BaseTopology >, dim, codim >
61 dune_static_assert( (dim == Topology :: dimension),
"Wrong dimension" );
62 dune_static_assert( (codim <= dim),
"Invalid codimension" );
64 enum { m =
Size< BaseTopology, codim-1 > :: value };
68 enum { value = n + 2*m };
71 template<
class BaseTopology,
unsigned int dim >
72 class SizeImpl<
Prism< BaseTopology >, dim, 0 >
75 dune_static_assert( (dim == Topology :: dimension),
"Wrong dimension" );
81 template<
class BaseTopology,
unsigned int dim >
82 class SizeImpl<
Prism< BaseTopology >, dim, dim >
85 dune_static_assert( (dim == Topology :: dimension),
"Wrong dimension" );
87 enum { m =
Size< BaseTopology, dim-1 > :: value };
93 template<
class BaseTopology,
unsigned int dim,
unsigned int codim >
94 class SizeImpl<
Pyramid< BaseTopology >, dim, codim >
97 dune_static_assert( (dim == Topology :: dimension),
"Wrong dimension" );
98 dune_static_assert( (codim <= dim),
"Invalid codimension" );
100 enum { m =
Size< BaseTopology, codim-1 > :: value };
104 enum { value = m+n };
107 template<
class BaseTopology,
unsigned int dim >
108 class SizeImpl<
Pyramid< BaseTopology >, dim, 0 >
111 dune_static_assert( (dim == Topology :: dimension),
"Wrong dimension" );
117 template<
class BaseTopology,
unsigned int dim >
118 class SizeImpl<
Pyramid< BaseTopology >, dim, dim >
121 dune_static_assert( (dim == Topology :: dimension),
"Wrong dimension" );
123 enum { m =
Size< BaseTopology, dim-1 > :: value };
126 enum { value = m+1 };
130 template<
class Topology,
unsigned int codim >
133 enum {
value = SizeImpl< Topology, Topology :: dimension, codim >
:: value };
140 unsigned int size (
unsigned int topologyId,
int dim,
int codim );
147 template<
class Topology,
unsigned int dim,
unsigned int codim,
unsigned int i >
148 class SubTopologyImpl;
150 template<
unsigned int dim,
unsigned int codim,
unsigned int i >
151 class SubTopologyImpl<
Point, dim, codim, i >
154 dune_static_assert( (dim == Topology :: dimension),
"Wrong dimension" );
155 dune_static_assert( (codim <= dim),
"Invalid codimension" );
157 "Invalid subentity index" );
163 template<
class BaseTopology,
unsigned int dim,
unsigned int codim,
unsigned int i >
164 class SubTopologyImpl<
Prism< BaseTopology >, dim, codim, i >
167 dune_static_assert( (dim == Topology :: dimension),
"Wrong dimension" );
168 dune_static_assert( (codim <= dim),
"Invalid codimension" );
170 "Invalid subentity index" );
172 enum { m =
Size< BaseTopology, codim-1 > :: value };
175 enum { s = (i < n+m ? 0 : 1) };
186 typedef typename SubTopology< BaseTopology, codim-1, i-(n+s*m) > :: type type;
190 typedef typename conditional< (i < n), PrismSub<true>, BaseSub<false> > :: type :: type type;
193 template<
class BaseTopology,
unsigned int dim,
unsigned int i >
194 class SubTopologyImpl<
Prism< BaseTopology >, dim, 0, i >
197 dune_static_assert( (dim == Topology :: dimension),
"Wrong dimension" );
199 "Invalid subentity index" );
204 template<
class BaseTopology,
unsigned int dim,
unsigned int i >
205 class SubTopologyImpl<
Prism< BaseTopology >, dim, dim, i >
208 dune_static_assert( (dim == Topology :: dimension),
"Wrong dimension" );
210 "Invalid subentity index" );
215 template<
class BaseTopology,
unsigned int dim,
unsigned int codim,
unsigned int i >
216 class SubTopologyImpl<
Pyramid< BaseTopology >, dim, codim, i >
219 dune_static_assert( (dim == Topology :: dimension),
"Wrong dimension" );
220 dune_static_assert( (codim <= dim),
"Invalid codimension" );
222 "Invalid subentity index" );
224 enum { m =
Size< BaseTopology, codim-1 > :: value };
229 typedef typename SubTopology< BaseTopology, codim-1, i > :: type type;
239 typedef typename conditional< (i < m), BaseSub<true>, PyramidSub<false> > :: type :: type type;
242 template<
class BaseTopology,
unsigned int dim,
unsigned int i >
243 class SubTopologyImpl<
Pyramid< BaseTopology >, dim, 0, i >
246 dune_static_assert( (dim == Topology :: dimension),
"Wrong dimension" );
248 "Invalid subentity index" );
254 template<
class BaseTopology,
unsigned int dim,
unsigned int i >
255 class SubTopologyImpl<
Pyramid< BaseTopology >, dim, dim, i >
258 dune_static_assert( (dim == Topology :: dimension),
"Wrong dimension" );
260 "Invalid subentity index" );
266 template<
class Topology,
unsigned int codim,
unsigned int i >
269 typedef typename SubTopologyImpl< Topology, Topology :: dimension, codim, i >
:: type type;
281 unsigned int subTopologyId (
unsigned int topologyId,
int dim,
int codim,
unsigned int i );
288 template<
class Topology,
unsigned int codim,
unsigned int subcodim >
298 ForLoop< Builder, 0, Size< Topology, codim > :: value-1 >
311 static unsigned int size (
unsigned int i )
314 return instance().size_[ i ];
318 template<
class Topology,
unsigned int codim,
unsigned int subcodim >
336 template<
class Topology,
unsigned int codim,
337 unsigned int subdim,
unsigned int subcodim >
338 struct GenericSubTopologyNumberingHelper;
340 template<
class BaseTopology,
unsigned int codim,
341 unsigned int subdim,
unsigned int subcodim >
342 struct GenericSubTopologyNumberingHelper
343 <
Prism< BaseTopology >, codim, subdim, subcodim >
347 enum { m =
Size< BaseTopology, codim-1 > :: value };
350 enum { mb =
Size< BaseTopology, codim+subcodim-1 > :: value };
353 static unsigned int number (
unsigned int i,
unsigned int j )
355 const unsigned int s = (i < n+m ? 0 : 1);
360 const unsigned int ss = (j < ns+ms ? 0 : 1);
366 :: number( i, j-(ns+ss*ms) ) + nb + ss*mb;
374 template<
class BaseTopology,
unsigned int codim,
unsigned int subdim >
375 struct GenericSubTopologyNumberingHelper
376 <
Prism< BaseTopology >, codim, subdim, 0 >
380 static unsigned int number (
unsigned int i,
unsigned int j )
382 DUNE_UNUSED_PARAMETER(j);
387 template<
class BaseTopology,
unsigned int codim,
unsigned int subdim >
388 struct GenericSubTopologyNumberingHelper
389 <
Prism< BaseTopology >, codim, subdim, subdim >
393 enum { m =
Size< BaseTopology, codim-1 > :: value };
396 enum { mb =
Size< BaseTopology, codim+subdim-1 > :: value };
398 static unsigned int number (
unsigned int i,
unsigned int j )
400 const unsigned int s = (i < n+m ? 0 : 1);
404 const unsigned int ss = (j < ms ? 0 : 1);
414 template<
class BaseTopology,
unsigned int codim,
415 unsigned int subdim,
unsigned int subcodim >
416 struct GenericSubTopologyNumberingHelper
417 <
Pyramid< BaseTopology >, codim, subdim, subcodim >
421 enum { m =
Size< BaseTopology, codim-1 > :: value };
423 enum { mb =
Size< BaseTopology, codim+subcodim-1 > :: value };
425 static unsigned int number (
unsigned int i,
unsigned int j )
443 template<
class BaseTopology,
unsigned int codim,
unsigned int subdim >
444 struct GenericSubTopologyNumberingHelper
445 <
Pyramid< BaseTopology >, codim, subdim, 0 >
449 static unsigned int number (
unsigned int i,
unsigned int j )
451 DUNE_UNUSED_PARAMETER(j);
456 template<
class BaseTopology,
unsigned int codim,
unsigned int subdim >
457 struct GenericSubTopologyNumberingHelper
458 <
Pyramid< BaseTopology >, codim, subdim, subdim >
462 enum { m =
Size< BaseTopology, codim-1 > :: value };
464 enum { mb =
Size< BaseTopology, codim+subdim-1 > :: value };
466 static unsigned int number (
unsigned int i,
unsigned int j )
483 template<
class Topology,
unsigned int codim,
unsigned int subcodim >
486 dune_static_assert( (codim <= Topology :: dimension),
"Invalid codimension" );
487 dune_static_assert( (codim + subcodim <= Topology :: dimension),
488 "Invalid subcodimension" );
493 static unsigned int number (
unsigned int i,
unsigned int j )
495 return (codim == 0 ? j : i );
502 static unsigned int number (
unsigned int i,
unsigned int j )
504 return GenericSubTopologyNumberingHelper
505 <
Topology, codim, Topology :: dimension - codim, subcodim >
511 static unsigned int number (
unsigned int i,
unsigned int j )
515 < (codim == 0) || (codim == Topology :: dimension), BorderCodim<true>, InnerCodim<false> >
516 :: type :: number( i, j );
525 void subTopologyNumbering (
unsigned int topologyId,
int dim,
int codim,
unsigned int i,
int subcodim,
526 unsigned int *beginOut,
unsigned int *endOut );
533 template<
class Topology,
unsigned int codim,
unsigned int subcodim >
542 static unsigned int number (
unsigned int i,
unsigned int j )
545 return instance().numbering_[ i ][ j ];
551 for(
unsigned int i = 0; i < Size< Topology, codim > :: value; ++i )
554 numbering_[ i ].resize( size );
555 for(
unsigned int j = 0; j <
size; ++j )
556 numbering_[ i ][ j ] = GenericNumbering :: number( i, j );
560 DUNE_EXPORT
static const SubTopologyNumbering &instance ()
562 static SubTopologyNumbering inst;
571 template<
class Topology >
574 static const unsigned int dimension = Topology::dimension;
576 template<
class A,
class B >
579 static const unsigned int value = A::value + B::value;
582 template<
int codim >
588 template<
int codim >
591 static void apply (
unsigned int (&offsets)[ dimension+2 ] )
593 offsets[ codim+1 ] = offsets[ codim ] + Size< codim >::value;
598 static const unsigned int staticSize = GenericForLoop< StaticSum, Size, 0, dimension >::value;
603 ForLoop< CalcOffset, 0, dimension >::apply( offsets_ );
604 assert(
size() == staticSize );
607 unsigned int operator() (
const unsigned int codim,
const unsigned int subEntity )
const
609 const unsigned int offset = offsets_[ codim ];
610 assert( offset + subEntity < offsets_[ codim+1 ] );
611 return offset + subEntity;
616 return offsets_[ dimension+1 ];
620 unsigned int offsets_[ dimension+2 ];
627 #endif // #ifndef DUNE_GEOMETRY_GENERICGEOMETRY_SUBTOPOLOGIES_HH