dune-fem  2.4.1-rc
genericgeometry.hh
Go to the documentation of this file.
1 #ifndef DUNE_FEM_SPACE_LAGRANGE_GENERICGEOMETRY_HH
2 #define DUNE_FEM_SPACE_LAGRANGE_GENERICGEOMETRY_HH
3 
4 // dune-common includes
5 #include <dune/common/fvector.hh>
6 
7 // dune-geometry includes
8 #include <dune/geometry/type.hh>
9 
10 // dune-fem includes
11 #include <dune/fem/misc/metaprogramming.hh>
12 
13 
14 namespace Dune
15 {
16 
17  namespace Fem
18  {
19 
61  {
62  public:
64  static const unsigned int dimension = 0;
65 
66  template< unsigned int codim >
67  class Codim
68  {
69  static_assert( (codim <= dimension), "Codimension must be less or equal to dimension." );
70 
71  public:
72  static const unsigned int numSubEntities = ((codim == 0) ? 1 : 0);
73  };
74 
76  static unsigned int numSubEntities ( unsigned int codim )
77  {
78  return ((codim == 0) ? 1 : 0);
79  }
80  };
81 
82 
83 
88  template< class BaseGeometry >
90  {
91  public:
93  typedef BaseGeometry BaseGeometryType;
94 
96  static const unsigned int dimension = BaseGeometryType::dimension + 1;
97 
98  template< unsigned int codim >
99  class Codim
100  {
101  static_assert( (codim <= dimension), "Codimension must be less or equal to dimension." );
102 
103  public:
104  static const unsigned int numSubEntities
105  = MetaIf< (codim > 0),
106  MetaPlus< MetaInt< Protect< BaseGeometryType::template Codim, codim-1, PointGeometry::template Codim< 0 >, 0 >::numSubEntities >,
107  MetaInt< Protect< BaseGeometryType::template Codim, codim, PointGeometry::template Codim< 0 >, dimension >::numSubEntities > >,
108  MetaInt< 1 > >::value;
109  };
110 
112  static unsigned int numSubEntities ( unsigned int codim )
113  {
114  if( codim > 0 )
115  {
116  const unsigned int sameCodimCount = BaseGeometryType::numSubEntities( codim-1 );
117  if( codim < dimension )
118  return sameCodimCount + BaseGeometryType::numSubEntities( codim );
119  else
120  return (codim == dimension ? sameCodimCount+1 : 0);
121  }
122  else
123  return 1;
124  }
125  };
126 
127 
128 
133  template< class FirstGeometry, class SecondGeometry >
135  {
136  public:
138  typedef FirstGeometry FirstGeometryType;
140  typedef SecondGeometry SecondGeometryType;
141 
143  static const unsigned int dimension = FirstGeometryType::dimension + SecondGeometryType::dimension;
144 
145  template< unsigned int codim >
146  class Codim
147  {
148  static_assert( (codim <= dimension), "Codimension must be less or equal to dimension." );
149 
150  template< unsigned int i >
151  struct NumSubEntities
152  : public MetaInt< FirstGeometryType::template Codim< codim-i >::numSubEntities * SecondGeometryType::template Codim< i >::numSubEntities >
153  {};
154 
155  public:
156  static const unsigned int numSubEntities = Loop< MetaPlus, NumSubEntities, codim >::value;
157  };
158 
160  static unsigned int numSubEntities ( unsigned int codim )
161  {
162  unsigned int cnt = 0;
163  for( unsigned int i = 0; i <= codim; ++i )
164  cnt += FirstGeometryType::numSubEntities( codim - i ) * SecondGeometryType::numSubEntities( i );
165  return cnt;
166  }
167  };
168 
169 
170 
171  template< unsigned int id, unsigned int dim >
173  {
174  static_assert( (id < (1 << dim)), "id too large." );
175 
176  static const bool isPrism = ((id >> (dim-1)) != 0);
177 
178  typedef GeometryWrapper< (id & ~(1 << (dim-1))), dim-1 > DimensionReductionType;
179 
180  template< bool >
181  struct Prism
182  {
183  typedef GeometryWrapper< (id & 1), 1 > LineGeometryType;
186  };
187 
188  template< bool >
189  struct Pyramid
190  {
193  };
194 
195  public:
196  static const unsigned int dimension = dim;
197 
198  typedef typename conditional< isPrism, Prism< true >, Pyramid< false > >::type::GenericGeometryType
200  };
201 
202  template< unsigned int id >
203  class GeometryWrapper< id, 1 >
204  {
205  static_assert( (id < 2), "id too large." );
206 
207  public:
208  static const unsigned int dimension = 1;
209 
211  };
212 
213  template< unsigned int id >
214  class GeometryWrapper< id, 0 >
215  {
216  static_assert( (id < 1), "id too large." );
217 
218  public:
219  static const unsigned int dimension = 0;
220 
222  };
223 
224 
225 
226  // Local Coordinates
227  // -----------------
228 
229  template< class Geometry, class Field, unsigned int offset = 0 >
231 
232 
233 
234  template< class Field, unsigned int offset >
235  class LocalCoordinate< PointGeometry, Field, offset >
236  {
238 
239  public:
241 
242  static const unsigned int dimension = GeometryType::dimension;
243 
244  typedef Field FieldType;
245 
246  inline LocalCoordinate ()
247  {}
248 
249  template< int sz >
250  explicit LocalCoordinate ( const FieldVector< FieldType, sz > &x )
251  {
252  static_assert( (sz >= offset + dimension), "Invalid vector size" );
253  }
254 
255  ThisType &operator= ( const FieldType s )
256  {
257  return *this;
258  }
259 
260  template< int sz >
261  ThisType &operator= ( const FieldVector< FieldType, sz > &x )
262  {
263  static_assert( (sz >= offset + dimension), "Invalid vector size" );
264  return *this;
265  }
266 
267  ThisType &operator= ( const ThisType &v )
268  {
269  return *this;
270  }
271 
272  ThisType &operator*= ( const FieldType s )
273  {
274  return *this;
275  }
276 
277  ThisType &operator+= ( const ThisType &v )
278  {
279  return *this;
280  }
281 
282  ThisType &operator-= ( const ThisType &v )
283  {
284  return *this;
285  }
286 
287  const FieldType &operator[] ( const unsigned int i ) const
288  {
289  DUNE_THROW( RangeError, "LocalCoordinate: No such index." );
290  }
291 
292  FieldType &operator[] ( const unsigned int i )
293  {
294  DUNE_THROW( RangeError, "LocalCoordinate: No such index." );
295  }
296  };
297 
298 
299 
300  template< class BaseGeometry, class Field, unsigned int offset >
301  class LocalCoordinate< PyramidGeometry< BaseGeometry >, Field, offset >
302  {
304 
305  public:
306  typedef BaseGeometry BaseGeometryType;
307 
309 
310  static const unsigned int dimension = GeometryType::dimension;
311 
312  typedef Field FieldType;
313 
315 
316  static const unsigned int index = offset + BaseGeometryType::dimension;
317 
319  {}
320 
321  template< int sz >
322  explicit LocalCoordinate ( const FieldVector< FieldType, sz > &x )
323  : myCoordinate_( x[ index ] ),
324  baseCoordinate_( x )
325  {
326  static_assert( (sz >= offset + dimension), "Invalid vector size" );
327  }
328 
329  ThisType &operator= ( const FieldType s )
330  {
331  myCoordinate_ = s;
332  baseCoordinate_ = s;
333  return *this;
334  }
335 
336  template< int sz >
337  ThisType &operator= ( const FieldVector< FieldType, sz > &x )
338  {
339  static_assert( (sz >= offset + dimension), "Invalid vector size" );
340 
341  myCoordinate_ = x[ index ];
342  baseCoordinate_ = x;
343  return *this;
344  }
345 
346  ThisType &operator= ( const ThisType &v )
347  {
348  myCoordinate_ = v.myCoordinate_;
349  baseCoordinate_ = v.baseCoordinate_;
350  return *this;
351  }
352 
353  ThisType &operator*= ( const FieldType s )
354  {
355  myCoordinate_ *= s;
356  baseCoordinate_ *= s;
357  return *this;
358  }
359 
360  ThisType &operator+= ( const ThisType &v )
361  {
362  myCoordinate_ += v.myCoordinate_;
363  baseCoordinate_ += v.baseCoordinate_;
364  return *this;
365  }
366 
367  ThisType &operator-= ( const ThisType &v )
368  {
369  myCoordinate_ -= v.myCoordinate_;
370  baseCoordinate_ -= v.baseCoordinate_;
371  return *this;
372  }
373 
374  const FieldType &operator[] ( const unsigned int i ) const
375  {
376  if( i == index )
377  return myCoordinate_;
378  else
379  return baseCoordinate_[ i ];
380  }
381 
382  FieldType &operator[] ( const unsigned int i )
383  {
384  if( i == index )
385  return myCoordinate_;
386  else
387  return baseCoordinate_[ i ];
388  }
389 
390  const FieldType &operator* () const
391  {
392  return myCoordinate_;
393  }
394 
395  FieldType &operator* ()
396  {
397  return myCoordinate_;
398  }
399 
400  const BaseCoordinateType &base () const
401  {
402  return baseCoordinate_;
403  }
404 
405  BaseCoordinateType &base ()
406  {
407  return baseCoordinate_;
408  }
409 
410  private:
411  FieldType myCoordinate_;
412  BaseCoordinateType baseCoordinate_;
413  };
414 
415 
416 
417  template< class FirstGeometry, class SecondGeometry, class Field, unsigned int offset >
418  class LocalCoordinate< ProductGeometry< FirstGeometry, SecondGeometry >, Field, offset >
419  {
421 
422  public:
423  typedef FirstGeometry FirstGeometryType;
424  typedef SecondGeometry SecondGeometryType;
426 
427  static const unsigned int dimension = GeometryType::dimension;
428 
429  typedef Field FieldType;
430 
431  protected:
432  static const unsigned int firstOffset = offset;
433  static const unsigned int secondOffset = offset + FirstGeometryType::dimension;
434 
435  public:
438 
440  {}
441 
442  template< int sz >
443  explicit LocalCoordinate ( const FieldVector< FieldType, sz > &x )
444  : firstCoordinate_( x ),
445  secondCoordinate_( x )
446  {
447  static_assert( (sz >= offset + dimension), "Invalid vector size" );
448  }
449 
450  ThisType &operator= ( const FieldType s )
451  {
452  firstCoordinate_ = s;
453  secondCoordinate_ = s;
454  return *this;
455  }
456 
457  template< int sz >
458  ThisType &operator= ( const FieldVector< FieldType, sz > &x )
459  {
460  static_assert( (sz >= offset + dimension), "Invalid vector size" );
461 
462  firstCoordinate_ = x;
463  secondCoordinate_ = x;
464  return *this;
465  }
466 
467  ThisType &operator= ( const ThisType &v )
468  {
469  firstCoordinate_ = v;
470  secondCoordinate_ = v;
471  return *this;
472  }
473 
474  ThisType &operator*= ( const FieldType s )
475  {
476  firstCoordinate_ *= s;
477  secondCoordinate_ *= s;
478  return *this;
479  }
480 
481  ThisType &operator+= ( const ThisType &v )
482  {
483  firstCoordinate_ += v;
484  secondCoordinate_ += v;
485  return *this;
486  }
487 
488  ThisType &operator-= ( const ThisType &v )
489  {
490  firstCoordinate_ -= v;
491  secondCoordinate_ -= v;
492  return *this;
493  }
494 
495  const FieldType &operator[] ( const unsigned int i ) const
496  {
497  if( i < secondOffset )
498  return firstCoordinate_[ i ];
499  else
500  return secondCoordinate_[ i ];
501  }
502 
503  FieldType &operator[] ( const unsigned int i )
504  {
505  if( i < secondOffset )
506  return firstCoordinate_[ i ];
507  else
508  return secondCoordinate_[ i ];
509  }
510 
511  const FirstCoordinateType &first () const
512  {
513  return firstCoordinate_;
514  }
515 
516  FirstCoordinateType &first ()
517  {
518  return firstCoordinate_;
519  }
520 
521  const SecondCoordinateType &second () const
522  {
523  return secondCoordinate_;
524  }
525 
526  SecondCoordinateType &second ()
527  {
528  return secondCoordinate_;
529  }
530 
531  private:
532  FirstCoordinateType firstCoordinate_;
533  SecondCoordinateType secondCoordinate_;
534  };
535 
536  } // namespace Fem
537 
538 } // namespace Dune
539 
540 #endif // #ifndef DUNE_FEM_SPACE_LAGRANGE_GENERICGEOMETRY_HH
PyramidGeometry< BaseGeometryType > GeometryType
Definition: genericgeometry.hh:308
Definition: genericgeometry.hh:230
Definition: genericgeometry.hh:67
static const unsigned int dimension
dimension of the geometry object
Definition: genericgeometry.hh:64
FirstGeometry FirstGeometryType
type of the first base geometry
Definition: genericgeometry.hh:138
BaseCoordinateType & base()
Definition: genericgeometry.hh:405
static unsigned int numSubEntities(unsigned int codim)
number of subentites of a given codimension
Definition: genericgeometry.hh:160
static unsigned int numSubEntities(unsigned int codim)
number of subentites of a given codimension
Definition: genericgeometry.hh:112
LocalCoordinate< SecondGeometryType, FieldType, secondOffset > SecondCoordinateType
Definition: genericgeometry.hh:437
LocalCoordinate(const FieldVector< FieldType, sz > &x)
Definition: genericgeometry.hh:250
generic geometry modelling a pyramid over a base geometry
Definition: genericgeometry.hh:89
Field FieldType
Definition: genericgeometry.hh:244
conditional< isPrism, Prism< true >, Pyramid< false > >::type::GenericGeometryType GenericGeometryType
Definition: genericgeometry.hh:199
PyramidGeometry< PointGeometry > GenericGeometryType
Definition: genericgeometry.hh:210
Definition: genericgeometry.hh:146
Definition: coordinate.hh:4
LocalCoordinate()
Definition: genericgeometry.hh:246
Definition: genericgeometry.hh:172
generic geometry modelling a single point
Definition: genericgeometry.hh:60
const FirstCoordinateType & first() const
Definition: genericgeometry.hh:511
LocalCoordinate< FirstGeometryType, FieldType, firstOffset > FirstCoordinateType
Definition: genericgeometry.hh:436
static const unsigned int numSubEntities
Definition: genericgeometry.hh:72
Double operator*(const Double &a, const Double &b)
Definition: double.hh:495
BaseGeometry BaseGeometryType
Definition: genericgeometry.hh:306
BaseGeometry BaseGeometryType
type of base geometry
Definition: genericgeometry.hh:93
PointGeometry GeometryType
Definition: genericgeometry.hh:240
const SecondCoordinateType & second() const
Definition: genericgeometry.hh:521
LocalCoordinate(const FieldVector< FieldType, sz > &x)
Definition: genericgeometry.hh:443
LocalCoordinate(const FieldVector< FieldType, sz > &x)
Definition: genericgeometry.hh:322
Definition: genericgeometry.hh:99
SecondGeometry SecondGeometryType
type of the second base geometry
Definition: genericgeometry.hh:140
PointGeometry GenericGeometryType
Definition: genericgeometry.hh:221
ProductGeometry< FirstGeometryType, SecondGeometryType > GeometryType
Definition: genericgeometry.hh:425
LocalCoordinate< BaseGeometry, FieldType, offset > BaseCoordinateType
Definition: genericgeometry.hh:314
static unsigned int numSubEntities(unsigned int codim)
number of subentites of a given codimension
Definition: genericgeometry.hh:76
generic geometry modelling the product of two base geometries
Definition: genericgeometry.hh:134
const BaseCoordinateType & base() const
Definition: genericgeometry.hh:400