dune-geometry 3.0-git
subtopologies.hh
Go to the documentation of this file.
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3#ifndef DUNE_GEOMETRY_GENERICGEOMETRY_SUBTOPOLOGIES_HH
4#define DUNE_GEOMETRY_GENERICGEOMETRY_SUBTOPOLOGIES_HH
5
6#include <cassert>
7#include <vector>
8
9#include <dune/common/forloop.hh>
10#include <dune/common/typetraits.hh>
11#include <dune/common/visibility.hh>
12#include <dune/common/unused.hh>
13
15
16namespace Dune
17{
18
19 namespace GenericGeometry
20 {
21
22 template< class Topology, unsigned int codim >
23 struct Size;
24
25 template< class Topology, unsigned int codim, unsigned int i >
26 struct SubTopology;
27
28 template< class Topology, unsigned int codim, unsigned int subcodim >
29 class SubTopologySize;
30
31 template< class Topology, unsigned int codim, unsigned int subcodim >
32 class GenericSubTopologyNumbering;
33
34 template< class Topology, unsigned int codim, unsigned int subcodim >
35 class SubTopologyNumbering;
36
37
38
39 // Size
40 // ----
41
42 template< class Topology, unsigned int dim, unsigned int codim >
43 class SizeImpl;
44
45 template< unsigned int dim, unsigned int codim >
46 class SizeImpl< Point, dim, codim >
47 {
48 typedef Point Topology;
49 static_assert((dim == Topology :: dimension), "Wrong dimension");
50 static_assert((codim <= dim), "Invalid codimension");
51
52 public:
53 enum { value = 1 };
54 };
55
56 template< class BaseTopology, unsigned int dim, unsigned int codim >
57 class SizeImpl< Prism< BaseTopology >, dim, codim >
58 {
59 typedef Prism< BaseTopology > Topology;
60 static_assert((dim == Topology :: dimension), "Wrong dimension");
61 static_assert((codim <= dim), "Invalid codimension");
62
63 enum { m = Size< BaseTopology, codim-1 > :: value };
64 enum { n = Size< BaseTopology, codim > :: value };
65
66 public:
67 enum { value = n + 2*m };
68 };
69
70 template< class BaseTopology, unsigned int dim >
71 class SizeImpl< Prism< BaseTopology >, dim, 0 >
72 {
73 typedef Prism< BaseTopology > Topology;
74 static_assert((dim == Topology :: dimension), "Wrong dimension");
75
76 public:
77 enum { value = 1 };
78 };
79
80 template< class BaseTopology, unsigned int dim >
81 class SizeImpl< Prism< BaseTopology >, dim, dim >
82 {
83 typedef Prism< BaseTopology > Topology;
84 static_assert((dim == Topology :: dimension), "Wrong dimension");
85
86 enum { m = Size< BaseTopology, dim-1 > :: value };
87
88 public:
89 enum { value = 2*m };
90 };
91
92 template< class BaseTopology, unsigned int dim, unsigned int codim >
93 class SizeImpl< Pyramid< BaseTopology >, dim, codim >
94 {
95 typedef Pyramid< BaseTopology > Topology;
96 static_assert((dim == Topology :: dimension), "Wrong dimension");
97 static_assert((codim <= dim), "Invalid codimension");
98
99 enum { m = Size< BaseTopology, codim-1 > :: value };
100 enum { n = Size< BaseTopology, codim > :: value };
101
102 public:
103 enum { value = m+n };
104 };
105
106 template< class BaseTopology, unsigned int dim >
107 class SizeImpl< Pyramid< BaseTopology >, dim, 0 >
108 {
109 typedef Pyramid< BaseTopology > Topology;
110 static_assert((dim == Topology :: dimension), "Wrong dimension");
111
112 public:
113 enum { value = 1 };
114 };
115
116 template< class BaseTopology, unsigned int dim >
117 class SizeImpl< Pyramid< BaseTopology >, dim, dim >
118 {
119 typedef Pyramid< BaseTopology > Topology;
120 static_assert((dim == Topology :: dimension), "Wrong dimension");
121
122 enum { m = Size< BaseTopology, dim-1 > :: value };
123
124 public:
125 enum { value = m+1 };
126 };
127
129 template< class Topology, unsigned int codim >
134
135
136
137
139 unsigned int size ( unsigned int topologyId, int dim, int codim );
140
141
142
143 // SubTopology
144 // -----------
145
146 template< class Topology, unsigned int dim, unsigned int codim, unsigned int i >
148
149 template< unsigned int dim, unsigned int codim, unsigned int i >
150 class SubTopologyImpl< Point, dim, codim, i >
151 {
152 typedef Point Topology;
153 static_assert((dim == Topology :: dimension), "Wrong dimension");
154 static_assert((codim <= dim), "Invalid codimension");
155 static_assert((i < Size< Topology, codim > :: value), "Invalid subentity index");
156
157 public:
158 typedef Topology type;
159 };
160
161 template< class BaseTopology, unsigned int dim, unsigned int codim, unsigned int i >
162 class SubTopologyImpl< Prism< BaseTopology >, dim, codim, i >
163 {
164 typedef Prism< BaseTopology > Topology;
165 static_assert((dim == Topology :: dimension), "Wrong dimension");
166 static_assert((codim <= dim), "Invalid codimension");
167 static_assert((i < Size< Topology, codim > :: value), "Invalid subentity index");
168
169 enum { m = Size< BaseTopology, codim-1 > :: value };
170 enum { n = Size< BaseTopology, codim > :: value };
171
172 enum { s = (i < n+m ? 0 : 1) };
173
174 template< bool >
175 struct PrismSub
176 {
178 };
179
180 template< bool >
181 struct BaseSub
182 {
183 typedef typename SubTopology< BaseTopology, codim-1, i-(n+s*m) > :: type type;
184 };
185
186 public:
187 typedef typename std::conditional< (i < n), PrismSub<true>, BaseSub<false> > :: type :: type type;
188 };
189
190 template< class BaseTopology, unsigned int dim, unsigned int i >
191 class SubTopologyImpl< Prism< BaseTopology >, dim, 0, i >
192 {
193 typedef Prism< BaseTopology > Topology;
194 static_assert((dim == Topology :: dimension), "Wrong dimension");
195 static_assert((i < Size< Topology, 0 > :: value), "Invalid subentity index");
196 public:
197 typedef Topology type;
198 };
199
200 template< class BaseTopology, unsigned int dim, unsigned int i >
201 class SubTopologyImpl< Prism< BaseTopology >, dim, dim, i >
202 {
203 typedef Prism< BaseTopology > Topology;
204 static_assert((dim == Topology :: dimension), "Wrong dimension");
205 static_assert((i < Size< Topology, dim > :: value), "Invalid subentity index");
206 public:
207 typedef Point type;
208 };
209
210 template< class BaseTopology, unsigned int dim, unsigned int codim, unsigned int i >
211 class SubTopologyImpl< Pyramid< BaseTopology >, dim, codim, i >
212 {
213 typedef Pyramid< BaseTopology > Topology;
214 static_assert((dim == Topology :: dimension), "Wrong dimension");
215 static_assert((codim <= dim), "Invalid codimension" );
216 static_assert((i < Size< Topology, codim > :: value), "Invalid subentity index");
217
218 enum { m = Size< BaseTopology, codim-1 > :: value };
219
220 template< bool >
221 struct BaseSub
222 {
223 typedef typename SubTopology< BaseTopology, codim-1, i > :: type type;
224 };
225
226 template< bool >
227 struct PyramidSub
228 {
229 typedef Pyramid< typename SubTopology< BaseTopology, codim, i-m > :: type > type;
230 };
231
232 public:
233 typedef typename std::conditional< (i < m), BaseSub<true>, PyramidSub<false> > :: type :: type type;
234 };
235
236 template< class BaseTopology, unsigned int dim, unsigned int i >
237 class SubTopologyImpl< Pyramid< BaseTopology >, dim, 0, i >
238 {
239 typedef Pyramid< BaseTopology > Topology;
240 static_assert((dim == Topology :: dimension), "Wrong dimension");
241 static_assert((i < Size< Topology, 0 > :: value), "Invalid subentity index");
242
243 public:
244 typedef Topology type;
245 };
246
247 template< class BaseTopology, unsigned int dim, unsigned int i >
248 class SubTopologyImpl< Pyramid< BaseTopology >, dim, dim, i >
249 {
250 typedef Pyramid< BaseTopology > Topology;
251 static_assert((dim == Topology :: dimension), "Wrong dimension");
252 static_assert((i < Size< Topology, dim > :: value), "Invalid subentity index");
253
254 public:
255 typedef Point type;
256 };
257
258 template< class Topology, unsigned int codim, unsigned int i >
263
264
265
273 unsigned int subTopologyId ( unsigned int topologyId, int dim, int codim, unsigned int i );
274
275
276
277 // SubTopologySize
278 // ---------------
279
280 template< class Topology, unsigned int codim, unsigned int subcodim >
282 {
283 template< int i >
284 struct Builder;
285
286 unsigned int size_[ Size< Topology, codim > :: value ];
287
289 {
290 ForLoop< Builder, 0, Size< Topology, codim > :: value-1 >
291 :: apply( *this );
292 }
293
295
296 DUNE_EXPORT static const SubTopologySize &instance ()
297 {
298 static SubTopologySize inst;
299 return inst;
300 }
301
302 public:
303 static unsigned int size ( unsigned int i )
304 {
305 assert( (i < Size< Topology, codim > :: value) );
306 return instance().size_[ i ];
307 }
308 };
309
310 template< class Topology, unsigned int codim, unsigned int subcodim >
311 template< int i >
312 struct SubTopologySize< Topology, codim, subcodim > :: Builder
313 {
314 typedef GenericGeometry :: SubTopologySize< Topology, codim, subcodim >
316 typedef typename GenericGeometry :: SubTopology< Topology, codim, i > :: type
318
319 static void apply ( SubTopologySize &subTopologySize )
320 {
321 subTopologySize.size_[ i ] = Size< SubTopology, subcodim > :: value;
322 }
323 };
324
325
326
327
328 template< class Topology, unsigned int codim,
329 unsigned int subdim, unsigned int subcodim >
331
332 template< class BaseTopology, unsigned int codim,
333 unsigned int subdim, unsigned int subcodim >
335 < Prism< BaseTopology >, codim, subdim, subcodim >
336 {
338
339 enum { m = Size< BaseTopology, codim-1 > :: value };
340 enum { n = Size< BaseTopology, codim > :: value };
341
342 enum { mb = Size< BaseTopology, codim+subcodim-1 > :: value };
344
345 static unsigned int number ( unsigned int i, unsigned int j )
346 {
347 const unsigned int s = (i < n+m ? 0 : 1);
348 if( i < n )
349 {
352 const unsigned int ss = (j < ns+ms ? 0 : 1);
353 if( j < ns )
355 :: number( i, j );
356 else
358 :: number( i, j-(ns+ss*ms) ) + nb + ss*mb;
359 }
360 else
362 :: number( i-(n+s*m), j ) + nb + s*mb;
363 }
364 };
365
366 template< class BaseTopology, unsigned int codim, unsigned int subdim >
368 < Prism< BaseTopology >, codim, subdim, 0 >
369 {
371
372 static unsigned int number ( unsigned int i, unsigned int j )
373 {
374 DUNE_UNUSED_PARAMETER(j);
375 return i;
376 }
377 };
378
379 template< class BaseTopology, unsigned int codim, unsigned int subdim >
381 < Prism< BaseTopology >, codim, subdim, subdim >
382 {
384
385 enum { m = Size< BaseTopology, codim-1 > :: value };
386 enum { n = Size< BaseTopology, codim > :: value };
387
388 enum { mb = Size< BaseTopology, codim+subdim-1 > :: value };
389
390 static unsigned int number ( unsigned int i, unsigned int j )
391 {
392 const unsigned int s = (i < n+m ? 0 : 1);
393 if( i < n )
394 {
396 const unsigned int ss = (j < ms ? 0 : 1);
398 :: number( i, j-ss*ms ) + ss*mb;
399 }
400 else
402 :: number( i-(n+s*m), j ) + s*mb;
403 }
404 };
405
406 template< class BaseTopology, unsigned int codim,
407 unsigned int subdim, unsigned int subcodim >
409 < Pyramid< BaseTopology >, codim, subdim, subcodim >
410 {
412
413 enum { m = Size< BaseTopology, codim-1 > :: value };
414
415 enum { mb = Size< BaseTopology, codim+subcodim-1 > :: value };
416
417 static unsigned int number ( unsigned int i, unsigned int j )
418 {
419 if( i < m )
421 :: number( i, j );
422 else
423 {
425 if( j < ms )
427 :: number( i-m, j );
428 else
430 :: number( i-m, j-ms ) + mb;
431 }
432 }
433 };
434
435 template< class BaseTopology, unsigned int codim, unsigned int subdim >
437 < Pyramid< BaseTopology >, codim, subdim, 0 >
438 {
440
441 static unsigned int number ( unsigned int i, unsigned int j )
442 {
443 DUNE_UNUSED_PARAMETER(j);
444 return i;
445 }
446 };
447
448 template< class BaseTopology, unsigned int codim, unsigned int subdim >
450 < Pyramid< BaseTopology >, codim, subdim, subdim >
451 {
453
454 enum { m = Size< BaseTopology, codim-1 > :: value };
455
456 enum { mb = Size< BaseTopology, codim+subdim-1 > :: value };
457
458 static unsigned int number ( unsigned int i, unsigned int j )
459 {
460 if( i < m )
462 :: number( i, j );
463 else
464 {
466 if( j < ms )
468 :: number( i-m, j );
469 else
470 return mb;
471 }
472 }
473 };
474
475 template< class Topology, unsigned int codim, unsigned int subcodim >
477 {
478 static_assert((codim <= Topology :: dimension), "Invalid codimension");
479 static_assert((codim + subcodim <= Topology :: dimension), "Invalid subcodimension");
480
481 template< bool >
482 struct BorderCodim
483 {
484 static unsigned int number ( unsigned int i, unsigned int j )
485 {
486 return (codim == 0 ? j : i );
487 }
488 };
489
490 template< bool >
491 struct InnerCodim
492 {
493 static unsigned int number ( unsigned int i, unsigned int j )
494 {
496 < Topology, codim, Topology :: dimension - codim, subcodim >
497 :: number( i, j );
498 }
499 };
500
501 public:
502 static unsigned int number ( unsigned int i, unsigned int j )
503 {
505 return std::conditional
506 < (codim == 0) || (codim == Topology :: dimension), BorderCodim<true>, InnerCodim<false> >
507 :: type :: number( i, j );
508 }
509 };
510
511
512
513 // subTopologyNumbering
514 // --------------------
515
516 void subTopologyNumbering ( unsigned int topologyId, int dim, int codim, unsigned int i, int subcodim,
517 unsigned int *beginOut, unsigned int *endOut );
518
519
520
521 // SubTopologyNumbering
522 // --------------------
523
524 template< class Topology, unsigned int codim, unsigned int subcodim >
526 {
528 GenericNumbering;
529
530 std :: vector< unsigned int > numbering_[ Size< Topology, codim > :: value ];
531
532 public:
533 static unsigned int number ( unsigned int i, unsigned int j )
534 {
536 return instance().numbering_[ i ][ j ];
537 }
538
539 private:
541 {
542 for( unsigned int i = 0; i < Size< Topology, codim > :: value; ++i )
543 {
545 numbering_[ i ].resize( size );
546 for( unsigned int j = 0; j < size; ++j )
547 numbering_[ i ][ j ] = GenericNumbering :: number( i, j );
548 }
549 }
550
551 DUNE_EXPORT static const SubTopologyNumbering &instance ()
552 {
553 static SubTopologyNumbering inst;
554 return inst;
555 }
556 };
557
558
559 // SubTopologyMapper
560 // -----------------
561
562 template< class Topology >
564 {
565 static const unsigned int dimension = Topology::dimension;
566
567 template< class A, class B >
568 struct StaticSum
569 {
570 static const unsigned int value = A::value + B::value;
571 };
572
573 template< int codim >
574 struct Size
575 {
576 static const unsigned int value = GenericGeometry::Size< Topology, codim >::value;
577 };
578
579 template< int codim >
580 struct CalcOffset
581 {
582 static void apply ( unsigned int (&offsets)[ dimension+2 ] )
583 {
584 offsets[ codim+1 ] = offsets[ codim ] + Size< codim >::value;
585 }
586 };
587
588 public:
589 static const unsigned int staticSize = GenericForLoop< StaticSum, Size, 0, dimension >::value;
590
592 {
593 offsets_[ 0 ] = 0;
594 ForLoop< CalcOffset, 0, dimension >::apply( offsets_ );
595 assert( size() == staticSize );
596 }
597
598 unsigned int operator() ( const unsigned int codim, const unsigned int subEntity ) const
599 {
600 const unsigned int offset = offsets_[ codim ];
601 assert( offset + subEntity < offsets_[ codim+1 ] );
602 return offset + subEntity;
603 }
604
605 unsigned int size () const
606 {
607 return offsets_[ dimension+1 ];
608 }
609
610 private:
611 unsigned int offsets_[ dimension+2 ];
612 };
613
614 } // namespace GenericGeometry
615
616} // namespace Dune
617
618#endif // #ifndef DUNE_GEOMETRY_GENERICGEOMETRY_SUBTOPOLOGIES_HH
Definition affinegeometry.hh:19
void subTopologyNumbering(unsigned int topologyId, int dim, int codim, unsigned int i, int subcodim, unsigned int *beginOut, unsigned int *endOut)
Definition subtopologies.cc:85
unsigned int size(unsigned int topologyId, int dim, int codim)
Compute the number of subentities of a given codimension.
Definition subtopologies.cc:16
unsigned int subTopologyId(unsigned int topologyId, int dim, int codim, unsigned int i)
Compute the topology id of a given subentity.
Definition subtopologies.cc:47
Statically compute the number of subentities of a given codimension.
Definition subtopologies.hh:131
@ value
Definition subtopologies.hh:132
Definition subtopologies.hh:260
SubTopologyImpl< Topology, Topology::dimension, codim, i >::type type
Definition subtopologies.hh:261
Definition subtopologies.hh:282
static unsigned int size(unsigned int i)
Definition subtopologies.hh:303
static unsigned int number(unsigned int i, unsigned int j)
Definition subtopologies.hh:502
Definition subtopologies.hh:526
static unsigned int number(unsigned int i, unsigned int j)
Definition subtopologies.hh:533
Definition subtopologies.hh:43
Definition subtopologies.hh:147
std::conditional<(i< n), PrismSub< true >, BaseSub< false > >::type::type type
Definition subtopologies.hh:187
std::conditional<(i< m), BaseSub< true >, PyramidSub< false > >::type::type type
Definition subtopologies.hh:233
GenericGeometry ::SubTopologySize< Topology, codim, subcodim > SubTopologySize
Definition subtopologies.hh:315
static void apply(SubTopologySize &subTopologySize)
Definition subtopologies.hh:319
GenericGeometry::SubTopology< Topology, codim, i >::type SubTopology
Definition subtopologies.hh:317
static unsigned int number(unsigned int i, unsigned int j)
Definition subtopologies.hh:345
static unsigned int number(unsigned int i, unsigned int j)
Definition subtopologies.hh:372
static unsigned int number(unsigned int i, unsigned int j)
Definition subtopologies.hh:390
static unsigned int number(unsigned int i, unsigned int j)
Definition subtopologies.hh:417
static unsigned int number(unsigned int i, unsigned int j)
Definition subtopologies.hh:441
static unsigned int number(unsigned int i, unsigned int j)
Definition subtopologies.hh:458
Definition subtopologies.hh:564
unsigned int size() const
Definition subtopologies.hh:605
static const unsigned int staticSize
Definition subtopologies.hh:589
unsigned int operator()(const unsigned int codim, const unsigned int subEntity) const
Definition subtopologies.hh:598
SubTopologyMapper()
Definition subtopologies.hh:591
Definition topologytypes.hh:26
Definition topologytypes.hh:41
Definition topologytypes.hh:57
Definition topologytypes.hh:73
Definition topologytypes.hh:271