Dune Core Modules (2.4.1)

subtopologies.hh
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
12#include <dune/common/unused.hh>
13
14#include <dune/geometry/genericgeometry/topologytypes.hh>
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 >
130 struct Size
131 {
132 enum { value = SizeImpl< Topology, Topology :: dimension, codim > :: value };
133 };
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 >
147 class SubTopologyImpl;
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 {
177 typedef Prism< typename SubTopology< BaseTopology, codim, i > :: type > type;
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 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 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 >
259 struct SubTopology
260 {
261 typedef typename SubTopologyImpl< Topology, Topology :: dimension, codim, i > :: type type;
262 };
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 >
281 class SubTopologySize
282 {
283 template< int i >
284 struct Builder;
285
286 unsigned int size_[ Size< Topology, codim > :: value ];
287
288 SubTopologySize ()
289 {
290 ForLoop< Builder, 0, Size< Topology, codim > :: value-1 >
291 :: apply( *this );
292 }
293
294 SubTopologySize ( const SubTopologySize & );
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 >
315 SubTopologySize;
316 typedef typename GenericGeometry :: SubTopology< Topology, codim, i > :: type
317 SubTopology;
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 >
330 struct GenericSubTopologyNumberingHelper;
331
332 template< class BaseTopology, unsigned int codim,
333 unsigned int subdim, unsigned int subcodim >
334 struct GenericSubTopologyNumberingHelper
335 < Prism< BaseTopology >, codim, subdim, subcodim >
336 {
337 typedef Prism< BaseTopology > Topology;
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 };
343 enum { nb = Size< BaseTopology, codim+subcodim > :: 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 {
350 const unsigned int ms = SubTopologySize< BaseTopology, codim, subcodim-1 > :: size( i );
351 const unsigned int ns = SubTopologySize< BaseTopology, codim, subcodim > :: size( i );
352 const unsigned int ss = (j < ns+ms ? 0 : 1);
353 if( j < ns )
354 return GenericSubTopologyNumbering< BaseTopology, codim, subcodim >
355 :: number( i, j );
356 else
357 return GenericSubTopologyNumbering< BaseTopology, codim, subcodim-1 >
358 :: number( i, j-(ns+ss*ms) ) + nb + ss*mb;
359 }
360 else
361 return GenericSubTopologyNumbering< BaseTopology, codim-1, subcodim >
362 :: number( i-(n+s*m), j ) + nb + s*mb;
363 }
364 };
365
366 template< class BaseTopology, unsigned int codim, unsigned int subdim >
367 struct GenericSubTopologyNumberingHelper
368 < Prism< BaseTopology >, codim, subdim, 0 >
369 {
370 typedef Prism< BaseTopology > Topology;
371
372 static unsigned int number ( unsigned int i, unsigned int j )
373 {
375 return i;
376 }
377 };
378
379 template< class BaseTopology, unsigned int codim, unsigned int subdim >
380 struct GenericSubTopologyNumberingHelper
381 < Prism< BaseTopology >, codim, subdim, subdim >
382 {
383 typedef Prism< BaseTopology > Topology;
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 {
395 const unsigned int ms = SubTopologySize< BaseTopology, codim, subdim-1 > :: size( i );
396 const unsigned int ss = (j < ms ? 0 : 1);
397 return GenericSubTopologyNumbering< BaseTopology, codim, subdim-1 >
398 :: number( i, j-ss*ms ) + ss*mb;
399 }
400 else
401 return GenericSubTopologyNumbering< BaseTopology, codim-1, subdim >
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 >
408 struct GenericSubTopologyNumberingHelper
409 < Pyramid< BaseTopology >, codim, subdim, subcodim >
410 {
411 typedef Pyramid< BaseTopology > Topology;
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 )
420 return GenericSubTopologyNumbering< BaseTopology, codim-1, subcodim >
421 :: number( i, j );
422 else
423 {
424 const unsigned int ms = SubTopologySize< BaseTopology, codim, subcodim-1 > :: size( i-m );
425 if( j < ms )
426 return GenericSubTopologyNumbering< BaseTopology, codim, subcodim-1 >
427 :: number( i-m, j );
428 else
429 return GenericSubTopologyNumbering< BaseTopology, codim, subcodim >
430 :: number( i-m, j-ms ) + mb;
431 }
432 }
433 };
434
435 template< class BaseTopology, unsigned int codim, unsigned int subdim >
436 struct GenericSubTopologyNumberingHelper
437 < Pyramid< BaseTopology >, codim, subdim, 0 >
438 {
439 typedef Pyramid< BaseTopology > Topology;
440
441 static unsigned int number ( unsigned int i, unsigned int j )
442 {
444 return i;
445 }
446 };
447
448 template< class BaseTopology, unsigned int codim, unsigned int subdim >
449 struct GenericSubTopologyNumberingHelper
450 < Pyramid< BaseTopology >, codim, subdim, subdim >
451 {
452 typedef Pyramid< BaseTopology > Topology;
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 )
461 return GenericSubTopologyNumbering< BaseTopology, codim-1, subdim >
462 :: number( i, j );
463 else
464 {
465 const unsigned int ms = SubTopologySize< BaseTopology, codim, subdim-1 > :: size( i-m );
466 if( j < ms )
467 return GenericSubTopologyNumbering< BaseTopology, codim, subdim-1 >
468 :: number( i-m, j );
469 else
470 return mb;
471 }
472 }
473 };
474
475 template< class Topology, unsigned int codim, unsigned int subcodim >
476 class GenericSubTopologyNumbering
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 {
495 return GenericSubTopologyNumberingHelper
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 {
504 assert( (j <= SubTopologySize< Topology, codim, subcodim > :: size( i )) );
505 return 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 >
525 class SubTopologyNumbering
526 {
527 typedef GenericSubTopologyNumbering< Topology, codim, subcodim >
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 {
535 assert( (j <= SubTopologySize< Topology, codim, subcodim > :: size( i )) );
536 return instance().numbering_[ i ][ j ];
537 }
538
539 private:
540 SubTopologyNumbering ()
541 {
542 for( unsigned int i = 0; i < Size< Topology, codim > :: value; ++i )
543 {
544 const unsigned int size = SubTopologySize< Topology, codim, subcodim > :: size( i );
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 >
563 class SubTopologyMapper
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
591 SubTopologyMapper ()
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
A static for loop for template meta-programming.
Dune namespace.
Definition: alignment.hh:10
Statically compute the number of subentities of a given codimension.
Definition: subtopologies.hh:131
Traits for type conversions and type information.
Definition of the DUNE_UNUSED macro for the case that config.h is not available.
#define DUNE_UNUSED_PARAMETER(parm)
A macro to mark intentional unused function parameters with.
Definition: unused.hh:18
Definition of macros controlling symbol visibility at the ABI level.
#define DUNE_EXPORT
Export a symbol as part of the public ABI.
Definition: visibility.hh:18
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 12, 23:30, 2024)