dune-geometry  2.2.0
genericgeometry/referenceelements.hh
Go to the documentation of this file.
00001 // -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
00002 // vi: set et ts=8 sw=2 sts=2:
00003 
00004 #ifndef DUNE_GEOMETRY_GENERICGEOMETRY_REFERENCEELEMENTS_HH
00005 #define DUNE_GEOMETRY_GENERICGEOMETRY_REFERENCEELEMENTS_HH
00006 
00011 #include <dune/common/array.hh>
00012 #include <dune/common/fvector.hh>
00013 #include <dune/common/typetraits.hh>
00014 
00015 #include <dune/geometry/genericgeometry/referencedomain.hh>
00016 
00017 namespace Dune
00018 {
00019 
00020   namespace GenericGeometry
00021   {
00022 
00023     // ReferenceElement
00024     // ----------------
00025 
00026     template< class Topology, class ctype >
00027     struct ReferenceElement
00028     {
00029       static const unsigned int topologyId = Topology :: id;
00030       static const unsigned int dimension = Topology :: dimension;
00031 
00032       static const unsigned int numCorners = Topology :: numCorners;
00033       static const unsigned int numNormals = ReferenceDomain< Topology > :: numNormals;
00034 
00035       typedef FieldVector< ctype, dimension > CoordinateType;
00036 
00037       template< unsigned int codim >
00038       struct Codim
00039       {
00040         enum { size = Size< Topology, codim > :: value };
00041       };
00042 
00043       template< unsigned int codim, unsigned int subcodim >
00044       static unsigned int subNumbering ( unsigned int i, unsigned int j )
00045       {
00046         return SubTopologyNumbering< Topology, codim, subcodim > :: number( i, j );
00047       }
00048 
00049       template< unsigned int codim, unsigned int subcodim >
00050       static unsigned int size ( unsigned int i )
00051       {
00052         return SubTopologySize< Topology, codim, subcodim > :: size( i );
00053       }
00054 
00055       template< unsigned int codim >
00056       static const FieldVector< ctype, dimension > &
00057       baryCenter ( unsigned int i )
00058       {
00059         integral_constant< int, codim > codimVariable;
00060         return instance().baryCenters_[ codimVariable ][ i ];
00061       }
00062 
00063       static const CoordinateType &corner ( unsigned int i )
00064       {
00065         assert( i < numCorners );
00066         return instance().corners_[ i ];
00067       }
00068 
00069       static bool checkInside ( const CoordinateType &x )
00070       {
00071         return ReferenceDomain< Topology >::checkInside( x );
00072       }
00073 
00074       static const CoordinateType &
00075       integrationOuterNormal ( unsigned int i )
00076       {
00077         assert( i < numNormals );
00078         return instance().normals_[ i ];
00079       }
00080 
00081       static ctype volume ()
00082       {
00083         return ReferenceDomain< Topology > :: template volume< ctype >();
00084       }
00085 
00086       static const ReferenceElement &instance ()
00087       {
00088         static ReferenceElement inst;
00089         return inst;
00090       }
00091 
00092     private:
00093       template< int codim >
00094       class BaryCenterArray;
00095 
00096       ReferenceElement ()
00097       {
00098         for( unsigned int i = 0; i < numCorners; ++i )
00099           ReferenceDomain< Topology > :: corner( i, corners_[ i ] );
00100         for( unsigned int i = 0; i < numNormals; ++i )
00101           ReferenceDomain< Topology > :: integrationOuterNormal( i, normals_[ i ] );
00102       }
00103       
00104       Dune::array< CoordinateType, numCorners > corners_;
00105       CodimTable< BaryCenterArray, dimension > baryCenters_;
00106       Dune::array< CoordinateType, numNormals > normals_;
00107     };
00108 
00109 
00110 
00111     template< class Topology, class ctype >
00112     template< int codim >
00113     class ReferenceElement< Topology, ctype > :: BaryCenterArray
00114     {
00115       enum { Size = GenericGeometry :: Size< Topology, codim > :: value };
00116 
00117       typedef FieldVector< ctype, dimension > CoordinateType;
00118 
00119       template< int i >
00120       struct Builder;
00121       
00122       CoordinateType baryCenters_[ Size ];
00123 
00124     public:
00125       BaryCenterArray ()
00126       {
00127         ForLoop< Builder, 0, Size-1 > :: apply( baryCenters_ );
00128       }
00129       
00130       const CoordinateType &operator[] ( unsigned int i ) const
00131       {
00132         assert( i < Size );
00133         return baryCenters_[ i ];
00134       }
00135       
00136       static unsigned int size ()
00137       {
00138         return Size;
00139       }
00140     };
00141 
00142     template< class Topology, class ctype >
00143     template< int codim >
00144     template< int i >
00145     struct ReferenceElement< Topology, ctype > :: BaryCenterArray< codim > :: Builder
00146     {
00147       static void apply ( CoordinateType (&baryCenters)[ Size ] )
00148       {
00149         typedef SubTopologyNumbering< Topology, codim, dimension - codim > Numbering;
00150         typedef SubTopologySize< Topology, codim, dimension - codim > Size;
00151 
00152         CoordinateType &x = baryCenters[ i ];
00153         x = 0;
00154         const unsigned int numCorners = Size :: size( i );
00155         for( unsigned int k = 0; k < numCorners; ++k )
00156         {
00157           unsigned int j = Numbering :: number( i, k );
00158 
00159           CoordinateType y;
00160           ReferenceDomain< Topology > :: corner( j, y );
00161           x += y;
00162         }
00163         x *= ctype( 1 ) / ctype( numCorners );
00164       }
00165     };
00166 
00167   }
00168 
00169 }
00170 
00171 #endif // DUNE_GEOMETRY_GENERICGEOMETRY_REFERENCEELEMENTS_HH