dune-geometry  2.3.1
genericreferenceelements.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_GENERICREFERENCEELEMENTS_HH
4 #define DUNE_GEOMETRY_GENERICREFERENCEELEMENTS_HH
5 
6 #include <dune/common/deprecated.hh>
7 #include <dune/common/forloop.hh>
8 #include <dune/common/typetraits.hh>
9 #include <dune/common/visibility.hh>
10 
16 
17 namespace Dune
18 {
19 
20  // Internal Forward Declarations
21  // -----------------------------
22 
23  template< class ctype, int dim >
24  class GenericReferenceElementContainer;
25 
26 
27 
28  // GenericReferenceElement
29  // -----------------------
30 
50  template< class ctype, int dim >
52  {
54 
55  friend class GenericReferenceElementContainer< ctype, dim >;
56 
57  // make copy constructor private
59 
61 
63  {
64  ForLoop< Destroy, 0, dim >::apply( mappings_ );
65  integral_constant< int, 0 > codim0Variable;
66  if(mappings_[ codim0Variable ].size())
67  delete mappings_[ codim0Variable ][ 0 ];
68  }
69 
70  class SubEntityInfo;
71  template< class Topology > class CornerStorage;
72  template< class Topology > struct Initialize;
73  template< int codim > struct Destroy;
74 
75  struct GeometryTraits
76  : public GenericGeometry::DefaultGeometryTraits< ctype, dim, dim >
77  {
78  typedef GenericGeometry::DefaultGeometryTraits< ctype, dim, dim > Base;
79 
80  typedef typename Base::CoordTraits CoordTraits;
81 
82  template< class Topology >
83  struct Mapping
84  {
86  };
87 
88  struct Caching
89  {
94  };
95 
96  };
97 
98  public:
100  template< int codim >
101  struct Codim
102  {
104  typedef GenericGeometry::HybridMapping< dim-codim, GeometryTraits > Mapping;
105  };
106 
107  private:
109  template< int codim >
110  struct MappingArray
111  : public std::vector< typename Codim< codim >::Mapping * >
112  {};
113 
116 
117  std::vector< SubEntityInfo > info_[ dim+1 ];
118 
120  ctype volume_;
121  std::vector< FieldVector< ctype, dim > > volumeNormals_;
122 
124  MappingsTable mappings_;
125 
126  public:
131  int size ( int c ) const
132  {
133  assert( (c >= 0) && (c <= dim) );
134  return info_[ c ].size();
135  }
136 
148  int size ( int i, int c, int cc ) const
149  {
150  assert( (c >= 0) && (c <= dim) );
151  return info_[ c ][ i ].size( cc );
152  }
153 
167  int subEntity ( int i, int c, int ii, int cc ) const
168  {
169  assert( (c >= 0) && (c <= dim) );
170  return info_[ c ][ i ].number( ii, cc );
171  }
172 
182  const FieldVector< ctype, dim > &position( int i, int c ) const
183  {
184  assert( (c >= 0) && (c <= dim) );
185  return info_[ c ][ i ].position();
186  }
187 
195  bool checkInside ( const FieldVector< ctype, dim > &local ) const
196  {
197  return checkInside< 0 >( local, 0 );
198  }
199 
214  template< int codim >
215  bool checkInside ( const FieldVector< ctype, dim-codim > &local, int i ) const
216  {
217  return mapping< codim >( i ).checkInside( local );
218  }
219 
241  template< int codim >
242  FieldVector< ctype, dim >
243  global( const FieldVector< ctype, dim-codim > &local, int i, int c ) const
244  {
245  if( c != codim )
246  DUNE_THROW( Exception, "Local Coordinate Type does not correspond to codimension c." );
247  assert( c == codim );
248  return mapping< codim >( i ).global( local );
249  }
250 
269  template< int codim >
270  FieldVector< ctype, dim >
271  global( const FieldVector< ctype, dim-codim > &local, int i ) const
272  {
273  return mapping< codim >( i ).global( local );
274  }
275 
291  template< int codim >
292  typename Codim< codim >::Mapping &mapping( int i ) const
293  {
294  integral_constant< int, codim > codimVariable;
295  return *(mappings_[ codimVariable ][ i ]);
296  }
297 
306  const GeometryType &type ( int i, int c ) const
307  {
308  assert( (c >= 0) && (c <= dim) );
309  return info_[ c ][ i ].type();
310  }
311 
313  const GeometryType &type () const { return type( 0, 0 ); }
314 
316  ctype volume () const
317  {
318  return volume_;
319  }
320 
328  const FieldVector< ctype, dim > &volumeOuterNormal ( int face ) const
329  {
330  assert( (face >= 0) && (face < int( volumeNormals_.size())) );
331  return volumeNormals_[ face ];
332  }
333 
340  template< class Topology >
342  {
343  dune_static_assert( (Topology::dimension == dim),
344  "Cannot initialize reference element for different dimension." );
345  typedef Initialize< Topology > Init;
347 
348  // set up subentities
349  integral_constant< int, 0 > codim0Variable;
350  mappings_[ codim0Variable ].resize( 1 );
351  mappings_[ codim0Variable ][ 0 ] = new VirtualMapping( codim0Variable );
352 
353  Dune::ForLoop< Init::template Codim, 0, dim >::apply( info_, mappings_ );
354 
355  // compute reference element volume
356  typedef GenericGeometry::ReferenceDomain< Topology > ReferenceDomain;
357  volume_ = ReferenceDomain::template volume< ctype >();
358 
359  // compute normals
360  volumeNormals_.resize( ReferenceDomain::numNormals );
361  for( unsigned int i = 0; i < ReferenceDomain::numNormals; ++i )
362  ReferenceDomain::integrationOuterNormal( i ,volumeNormals_[ i ] );
363  }
364  };
365 
366 
370  template< class ctype, int dim >
372  {
373  template< class Topology, int codim > struct Initialize
374  {
375  template< int subcodim > struct SubCodim;
376  };
377 
378  std::vector< int > numbering_[ dim+1 ];
379  FieldVector< ctype, dim > baryCenter_;
380  GeometryType type_;
381 
382  public:
383  int size ( int cc ) const
384  {
385  assert( cc <= dim );
386  return numbering_[ cc ].size();
387  }
388 
389  int number ( int ii, int cc ) const
390  {
391  assert( cc <= dim );
392  return numbering_[ cc ][ ii ];
393  }
394 
395  const FieldVector< ctype, dim > &position () const
396  {
397  return baryCenter_;
398  }
399 
400  const GeometryType &type () const
401  {
402  return type_;
403  }
404 
405  template< class Topology, unsigned int codim, unsigned int i >
406  DUNE_EXPORT void initialize ()
407  {
408  typedef Initialize< Topology, codim > Init;
410 
411  const unsigned int iVariable = i;
412  Dune::ForLoop< Init::template SubCodim, 0, dim-codim >::apply( iVariable, numbering_ );
413 
414  baryCenter_ = ctype( 0 );
415  static const unsigned int numCorners = size( dim );
416  for( unsigned int j = 0; j < numCorners; ++j )
417  {
418  FieldVector< ctype, dim > corner;
419  RefDomain::corner( number( j, dim ), corner );
420  baryCenter_ += corner;
421  }
422  baryCenter_ *= ctype( 1 ) / ctype( numCorners );
423 
425  type_ = GeometryType( SubTopology::id, SubTopology::dimension );
426  }
427  };
428 
429 
430  template< class ctype, int dim >
431  template< class Topology >
433  {
435 
436  public:
437  static const unsigned int size = Topology::numCorners;
438 
439  template< class SubTopology >
440  struct SubStorage
441  {
443  };
444 
445  explicit CornerStorage ( const integral_constant< int, 0 > & )
446  {
447  for( unsigned int i = 0; i < size; ++i )
448  RefDomain::corner( i, coords_[ i ] );
449  }
450 
451  template< class Mapping, unsigned int codim >
452  explicit
454  {
455  for( unsigned int i = 0; i < size; ++i )
456  coords_[ i ] = coords[ i ];
457  }
458 
459  const FieldVector< ctype, dim > &operator[] ( unsigned int i ) const
460  {
461  return coords_[ i ];
462  }
463 
464  private:
465  FieldVector< ctype, dim > coords_[ size ];
466  };
467 
468 
469  template< class ctype, int dim >
470  template< class Topology, int codim >
471  template< int subcodim >
472  struct GenericReferenceElement< ctype, dim >::SubEntityInfo::Initialize< Topology, codim >::SubCodim
473  {
476 
477  static void apply ( unsigned int i, std::vector< int > (&numbering)[ dim+1 ] )
478  {
479  const unsigned int size = SubSize::size( i );
480  numbering[ codim+subcodim ].resize( size );
481  for( unsigned int j = 0; j < size; ++j )
482  numbering[ codim+subcodim ][ j ] = SubNumbering::number( i, j );
483  }
484  };
485 
486 
487  template< class ctype, int dim >
488  template< class Topology >
489  struct GenericReferenceElement< ctype, dim >::Initialize
490  {
492 
493  typedef typename GenericReferenceElement::template Codim< 0 >::Mapping ReferenceMapping;
494 
495  template< int codim >
496  struct Codim
497  {
498  template< int i >
499  struct SubTopology
500  {
501  static void apply ( std::vector< SubEntityInfo > &info )
502  {
503  info[ i ].template initialize< Topology, codim, i >();
504  }
505  };
506 
507  static void
508  apply ( std::vector< SubEntityInfo > (&info)[ dim+1 ],
509  MappingsTable &mappings )
510  {
512  info[ codim ].resize( size );
513  Dune::ForLoop< SubTopology, 0, size-1 >::apply( info[ codim ] );
514 
515  if( codim > 0 )
516  {
517  integral_constant< int, 0 > codim0Variable;
518  const ReferenceMapping &refMapping = *(mappings[ codim0Variable ][ 0 ]);
519 
520  typedef typename GenericGeometry::MappingProvider< ReferenceMapping, codim > MappingProvider;
521 
522  integral_constant< int, codim > codimVariable;
523  mappings[ codimVariable ].resize( size );
524  for( unsigned int i = 0; i < size; ++i ) {
525  char* storage = new char[MappingProvider::maxMappingSize];
526  mappings[ codimVariable ][ i ] = refMapping.template trace< codim >( i, storage );
527  }
528  }
529  }
530  };
531  };
532 
533 
534 
535  template< class ctype, int dim >
536  template< int codim >
537  struct GenericReferenceElement< ctype, dim >::Destroy
538  {
539  static void apply ( MappingsTable &mappings )
540  {
541  if (codim > 0 )
542  {
543  integral_constant< int, codim > codimVariable;
544  for( size_t i = 0; i < mappings[ codimVariable ].size(); ++i ) {
545  typedef typename Codim<codim>::Mapping Mapping;
546  mappings[ codimVariable ][ i ]->~Mapping();
547  char* storage = (char*)mappings[ codimVariable ][ i ];
548  delete[](storage);
549  }
550  }
551  }
552  };
553 
554 
555  // GenericReferenceElementContainer
556  // --------------------------------
557 
562  template< class ctype, int dim >
564  {
565  static const unsigned int numTopologies = (1u << dim);
566 
567  public:
569  typedef const value_type *const_iterator;
570 
571  DUNE_DEPRECATED_MSG("GenericReferenceElementContainer was renamed to ReferenceElementContainer.")
573  {
574  ForLoop< Builder, 0, numTopologies-1 >::apply( values_ );
575  }
576 
577  const value_type &operator() ( const GeometryType &type ) const
578  {
579  assert( type.dim() == dim );
580  return values_[ type.id() ];
581  }
582 
583  const value_type &simplex () const
584  {
586  }
587 
588  const value_type &cube () const
589  {
591  }
592 
593  const value_type &pyramid () const
594  {
596  }
597 
598  const value_type &prism () const
599  {
601  }
602 
603  const_iterator begin () const { return values_; }
604  const_iterator end () const { return values_ + numTopologies; }
605 
606  private:
607  template< int topologyId >
608  struct Builder
609  {
610  static void apply ( value_type (&values)[ numTopologies ] )
611  {
612  typedef typename GenericGeometry::Topology< topologyId, dim >::type Topology;
613  values[ topologyId ].template initializeTopology< Topology >();
614  }
615  };
616 
617  value_type values_[ numTopologies ];
618  };
619 
620 
621  // GenericReferenceElements
622  // ------------------------
623 
635  template< class ctype, int dim >
637  {
639 
640  DUNE_DEPRECATED_MSG("GenericReferenceElements was renamed to ReferenceElements.")
642 
645  DUNE_DEPRECATED_MSG("GenericReferenceElements was renamed to ReferenceElements.")
646  general ( const GeometryType &type )
647  {
648  return container() ( type );
649  }
650 
653  DUNE_DEPRECATED_MSG("GenericReferenceElements was renamed to ReferenceElements.")
655  {
656  return container().simplex();
657  }
658 
661  DUNE_DEPRECATED_MSG("GenericReferenceElements was renamed to ReferenceElements.")
662  cube ()
663  {
664  return container().cube();
665  }
666 
667  static Iterator begin () { return container().begin(); }
668  static Iterator end () { return container().end(); }
669 
670  private:
671  DUNE_EXPORT static const GenericReferenceElementContainer< ctype, dim > &container ()
672  {
674  return container;
675  }
676  };
677 
678 } // namespace Dune
679 
680 #endif // #ifndef DUNE_GEOMETRY_GENERICREFERENCEELEMENTS_HH