dune-geometry  2.4
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 
16 namespace 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 >
30 
31  template< class Topology, unsigned int codim, unsigned int subcodim >
33 
34  template< class Topology, unsigned int codim, unsigned int subcodim >
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  {
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  {
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  {
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  {
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  {
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  {
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  {
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 >
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 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  {
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  {
315  SubTopologySize;
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 >
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 };
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  {
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  {
424  const unsigned int ms = SubTopologySize< BaseTopology, codim, subcodim-1 > :: size( i-m );
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  {
465  const unsigned int ms = SubTopologySize< BaseTopology, codim, subdim-1 > :: size( i-m );
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 >
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  {
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  {
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
static unsigned int number(unsigned int i, unsigned int j)
Definition: subtopologies.hh:502
Definition: topologytypes.hh:40
static unsigned int number(unsigned int i, unsigned int j)
Definition: subtopologies.hh:441
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
Definition: affinegeometry.hh:18
Definition: subtopologies.hh:43
static unsigned int number(unsigned int i, unsigned int j)
Definition: subtopologies.hh:533
Definition: subtopologies.hh:35
unsigned int size(unsigned int topologyId, int dim, int codim)
Compute the number of subentities of a given codimension.
Definition: subtopologies.cc:16
Definition: subtopologies.hh:147
Statically compute the number of subentities of a given codimension.
Definition: subtopologies.hh:23
Definition: topologytypes.hh:56
Definition: subtopologies.hh:563
Definition: topologytypes.hh:25
conditional< (i< n), PrismSub< true >, BaseSub< false > >::type::type type
Definition: subtopologies.hh:187
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:372
conditional< (i< m), BaseSub< true >, PyramidSub< false > >::type::type type
Definition: subtopologies.hh:233
Definition: subtopologies.hh:26
static unsigned int number(unsigned int i, unsigned int j)
Definition: subtopologies.hh:345
unsigned int size() const
Definition: subtopologies.hh:605
Definition: subtopologies.hh:132
Definition: topologytypes.hh:73
void subTopologyNumbering(unsigned int topologyId, int dim, int codim, unsigned int i, int subcodim, unsigned int *beginOut, unsigned int *endOut)
Definition: subtopologies.cc:85
SubTopologyMapper()
Definition: subtopologies.hh:591
Definition: subtopologies.hh:29
SubTopologyImpl< Topology, Topology::dimension, codim, i >::type type
Definition: subtopologies.hh:261
static unsigned int size(unsigned int i)
Definition: subtopologies.hh:303
static unsigned int number(unsigned int i, unsigned int j)
Definition: subtopologies.hh:458