dune-geometry  2.3beta2
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/static_assert.hh>
11 #include <dune/common/typetraits.hh>
12 #include <dune/common/visibility.hh>
13 #include <dune/common/unused.hh>
14 
16 
17 namespace 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  {
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  {
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  {
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  {
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  {
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  {
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" );
156  dune_static_assert( (i < Size< Topology, codim > :: value),
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  {
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  {
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  {
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  {
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  {
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  {
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  {
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 >
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  {
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  {
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  {
360  const unsigned int ss = (j < ns+ms ? 0 : 1);
361  if( j < ns )
363  :: number( i, j );
364  else
366  :: number( i, j-(ns+ss*ms) ) + nb + ss*mb;
367  }
368  else
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  {
379 
380  static unsigned int number ( unsigned int i, unsigned int j )
381  {
382  DUNE_UNUSED_PARAMETER(j);
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  {
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  {
404  const unsigned int ss = (j < ms ? 0 : 1);
406  :: number( i, j-ss*ms ) + ss*mb;
407  }
408  else
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  {
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 )
429  :: number( i, j );
430  else
431  {
432  const unsigned int ms = SubTopologySize< BaseTopology, codim, subcodim-1 > :: size( i-m );
433  if( j < ms )
435  :: number( i-m, j );
436  else
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  {
448 
449  static unsigned int number ( unsigned int i, unsigned int j )
450  {
451  DUNE_UNUSED_PARAMETER(j);
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  {
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 )
470  :: number( i, j );
471  else
472  {
473  const unsigned int ms = SubTopologySize< BaseTopology, codim, subdim-1 > :: size( i-m );
474  if( j < ms )
476  :: number( i-m, j );
477  else
478  return mb;
479  }
480  }
481  };
482 
483  template< class Topology, unsigned int codim, unsigned int subcodim >
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  {
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 >
535  {
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  {
545  return instance().numbering_[ i ][ j ];
546  }
547 
548  private:
550  {
551  for( unsigned int i = 0; i < Size< Topology, codim > :: value; ++i )
552  {
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 >
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 
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