dune-geometry  2.2.0
referencedomain.hh
Go to the documentation of this file.
1 #ifndef DUNE_GEOMETRY_GENERICGEOMETRY_REFERENCEDOMAIN_HH
2 #define DUNE_GEOMETRY_GENERICGEOMETRY_REFERENCEDOMAIN_HH
3 
4 #include <dune/common/array.hh>
5 #include <dune/common/fvector.hh>
6 #include <dune/common/typetraits.hh>
7 
10 
11 namespace Dune
12 {
13 
14  namespace GenericGeometry
15  {
16 
17  // Internal Forward Declarations
18  // -----------------------------
19 
20  template< class Topology >
21  struct ReferenceDomain;
22 
23 
24 
25  // ReferenceDomain
26  // ---------------
27 
28  template< class Topology >
29  class ReferenceDomainBase;
30 
32  template<>
33  class ReferenceDomainBase< Point >
34  {
35  typedef Point Topology;
36 
37  friend struct ReferenceDomain< Topology >;
38  friend class ReferenceDomainBase< Prism< Topology > >;
39  friend class ReferenceDomainBase< Pyramid< Topology > >;
40 
41  static const unsigned int numNormals = 0;
42 
43  template< class ctype, int dim >
44  static void corner ( unsigned int i, FieldVector< ctype, dim > &n )
45  {
46  assert( i < Topology::numCorners );
47  }
48 
49  template< class ctype, int dim >
50  static bool
51  checkInside ( const FieldVector< ctype, dim > &x, ctype factor )
52  {
53  return true;
54  }
55 
56  template< class ctype, int dim >
57  static void
58  integrationOuterNormal ( unsigned int i, FieldVector< ctype, dim > &n )
59  {
60  assert( i < numNormals );
61  }
62 
63  template< class ctype >
64  static ctype volume ()
65  {
66  return ctype( 1 );
67  }
68  };
69 
70 
71  template< class BaseTopology >
72  class ReferenceDomainBase< Prism< BaseTopology > >
73  {
74  typedef Prism< BaseTopology > Topology;
75 
76  friend struct ReferenceDomain< Topology >;
77  friend class ReferenceDomainBase< Prism< Topology > >;
78  friend class ReferenceDomainBase< Pyramid< Topology > >;
79 
80  static const unsigned int numNormals = Size< Topology, 1 >::value;
81 
82  static const unsigned int dimension = Topology::dimension;
83  static const unsigned int myindex = dimension - 1;
84 
85  template< class ctype, int dim >
86  static void corner ( unsigned int i, FieldVector< ctype, dim > &x )
87  {
88  assert( i < Topology::numCorners );
89  const unsigned int j = i % BaseTopology::numCorners;
90  ReferenceDomainBase< BaseTopology >::corner( j, x );
91  if( i >= BaseTopology::numCorners )
92  x[ myindex ] = ctype( 1 );
93  }
94 
95  template< class ctype, int dim >
96  static bool
97  checkInside ( const FieldVector< ctype, dim > &x, ctype factor )
98  {
99  const ctype xn = x[ myindex ];
100  const ctype cxn = factor - xn;
101  return (xn > -1e-12) && (cxn > -1e-12)
102  && ReferenceDomainBase< BaseTopology >::checkInside( x, factor );
103  }
104 
105  template< class ctype, int dim >
106  static void
107  integrationOuterNormal ( unsigned int i, FieldVector< ctype, dim > &n )
108  {
109  typedef ReferenceDomainBase< BaseTopology > BaseReferenceDomain;
110 
111  if( i >= BaseReferenceDomain::numNormals )
112  {
113  const unsigned int j = i - BaseReferenceDomain::numNormals;
114  n[ myindex ] = (j == 0 ? ctype( -1 ) : ctype( 1 ));
115  }
116  else
117  BaseReferenceDomain::integrationOuterNormal( i, n );
118  }
119 
120  template< class ctype >
121  static ctype volume ()
122  {
123  typedef ReferenceDomainBase< BaseTopology > BaseReferenceDomain;
124  return BaseReferenceDomain::template volume< ctype >();
125  }
126  };
127 
128 
129  template< class BaseTopology >
130  class ReferenceDomainBase< Pyramid< BaseTopology > >
131  {
132  typedef Pyramid< BaseTopology > Topology;
133 
134  friend struct ReferenceDomain< Topology >;
135  friend class ReferenceDomainBase< Prism< Topology > >;
136  friend class ReferenceDomainBase< Pyramid< Topology > >;
137 
138  static const unsigned int numNormals = Size< Topology, 1 >::value;
139 
140  static const unsigned int dimension = Topology::dimension;
141  static const unsigned int myindex = dimension - 1;
142 
143  template< bool >
144  struct MultiDimensional
145  {
146  template< class ctype, int dim >
147  static void
148  integrationOuterNormal ( unsigned int i, FieldVector< ctype, dim > &n )
149  {
150  multiDimensionalIntegrationOuterNormal( i, n );
151  }
152  };
153 
154  template< bool >
155  struct OneDimensional
156  {
157  template< class ctype, int dim >
158  static void
159  integrationOuterNormal ( unsigned int i, FieldVector< ctype, dim > &n )
160  {
161  n[ myindex ] = (i > 0) ? ctype( 1 ) : ctype( -1 );
162  }
163  };
164 
165  template< class ctype, int dim >
166  static void corner ( unsigned int i, FieldVector< ctype, dim > &x )
167  {
168  assert( i < Topology::numCorners );
169  if( i < BaseTopology::numCorners )
170  ReferenceDomainBase< BaseTopology >::corner( i, x );
171  else
172  x[ myindex ] = ctype( 1 );
173  }
174 
175  template< class ctype, int dim >
176  static bool
177  checkInside ( const FieldVector< ctype, dim > &x, ctype factor )
178  {
179  const ctype xn = x[ myindex ];
180  const ctype cxn = factor - xn;
181  return (xn > -1e-12) && (cxn > -1e-12)
182  && ReferenceDomainBase< BaseTopology >::checkInside( x, cxn );
183  }
184 
185  template< class ctype, int dim >
186  static void
187  multiDimensionalIntegrationOuterNormal ( unsigned int i, FieldVector< ctype, dim > &n )
188  {
189  typedef ReferenceDomainBase< BaseTopology > BaseReferenceDomain;
190  typedef SubTopologyNumbering< BaseTopology, 1, dimension-2 > Numbering;
191 
192  if( i > 0 )
193  {
194  const unsigned int j = Numbering::number( i-1, 0 );
195  FieldVector< ctype, dim > x( ctype( 0 ) );
196  BaseReferenceDomain::corner( j, x );
197 
198  BaseReferenceDomain::integrationOuterNormal ( i-1, n );
199  n[ myindex ] = (x * n);
200  }
201  else
202  n[ myindex ] = ctype( -1 );
203  }
204 
205  template< class ctype, int dim >
206  static void
207  integrationOuterNormal ( unsigned int i, FieldVector< ctype, dim > &n )
208  {
209  SelectType< (dimension > 1), MultiDimensional<true>, OneDimensional<false> > :: Type
210  ::integrationOuterNormal( i, n );
211  }
212 
213  template< class ctype >
214  static ctype volume ()
215  {
216  typedef ReferenceDomainBase< BaseTopology > BaseReferenceDomain;
217  const ctype baseVolume = BaseReferenceDomain::template volume< ctype >();
218  return baseVolume / ctype( (unsigned int)(dimension) ); // linker problem when using dimension directly
219  }
220  };
225  // ReferenceDomain
226  // ---------------
227 
228  template< class Topology >
230  {
231  static const unsigned int numCorners = Topology::numCorners;
232  static const unsigned int dimension = Topology::dimension;
233 
234  static const unsigned int numNormals
235  = ReferenceDomainBase< Topology >::numNormals;
236 
237  template< class ctype >
238  static void corner ( unsigned int i, FieldVector< ctype, dimension > &x )
239  {
240  x = ctype( 0 );
242  }
243 
244  template< class ctype >
245  static bool checkInside ( const FieldVector< ctype, dimension > &x )
246  {
247  return ReferenceDomainBase< Topology >::checkInside( x, ctype( 1 ) );
248  }
249 
250  template< class ctype >
251  static void
252  integrationOuterNormal ( unsigned int i, FieldVector< ctype, dimension > &n )
253  {
254  n = ctype( 0 );
256  }
257 
258  template< class ctype >
259  static ctype volume ()
260  {
261  return ReferenceDomainBase< Topology >::template volume< ctype >();
262  }
263  };
264 
265  }
266 
267 }
268 
269 #endif // DUNE_GEOMETRY_GENERICGEOMETRY_REFERENCEDOMAIN_HH