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