genericreferenceelements.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_GENERICREFERENCEELEMENTS_HH
00005 #define DUNE_GENERICREFERENCEELEMENTS_HH
00006 
00007 #include <dune/common/forloop.hh>
00008 #include <dune/common/typetraits.hh>
00009 
00010 #include <dune/grid/genericgeometry/subtopologies.hh>
00011 #include <dune/grid/genericgeometry/referencedomain.hh>
00012 #include <dune/grid/genericgeometry/conversion.hh>
00013 #include <dune/grid/genericgeometry/hybridmapping.hh>
00014 #include <dune/grid/genericgeometry/mappingprovider.hh>
00015 
00016 namespace Dune
00017 {
00018 
00019   // forward declaration, needed for friend decl
00020   template< class ctype, int dim >
00021   class GenericReferenceElementContainer;
00022   
00023   // GenericReferenceElement
00024   // -----------------------
00025 
00042   template< class ctype, int dim >
00043   class GenericReferenceElement
00044   {
00045     typedef GenericReferenceElement< ctype, dim > This;
00046 
00047     friend class GenericReferenceElementContainer< ctype, dim >;
00048 
00049     // make copy constructor private
00050     GenericReferenceElement(const GenericReferenceElement &);
00051 
00052     // make empty constructor
00053     GenericReferenceElement() {};
00054     
00055     ~GenericReferenceElement ()
00056     {
00057       ForLoop< Destroy, 0, dim >::apply( mappings_ );
00058     }
00059 
00060     class SubEntityInfo;
00061     template< class Topology > class CornerStorage;
00062     template< class Topology > struct Initialize;
00063     template< int codim > struct Destroy;
00064 
00065     struct GeometryTraits
00066       : public GenericGeometry::DefaultGeometryTraits< ctype, dim, dim >
00067     {
00068       typedef GenericGeometry::DefaultGeometryTraits< ctype, dim, dim > Base;
00069 
00070       typedef typename Base::CoordTraits CoordTraits;
00071 
00072       template< class Topology >
00073       struct Mapping
00074       {
00075         typedef GenericGeometry::CornerMapping< CoordTraits, Topology, dim, CornerStorage< Topology >, true > type;
00076       };
00077 
00078       struct Caching
00079       {
00080         static const GenericGeometry::EvaluationType evaluateJacobianTransposed = GenericGeometry::PreCompute;
00081         static const GenericGeometry::EvaluationType evaluateJacobianInverseTransposed = GenericGeometry::PreCompute;
00082         static const GenericGeometry::EvaluationType evaluateIntegrationElement = GenericGeometry::PreCompute;
00083         static const GenericGeometry::EvaluationType evaluateNormal = GenericGeometry::PreCompute;
00084       };
00085 
00086     };
00087 
00088   public:
00090     template< int codim >
00091     struct Codim
00092     {
00094       typedef GenericGeometry::HybridMapping< dim-codim, GeometryTraits > Mapping;
00095     };
00096 
00097   private:
00098       
00100     template< int codim >
00101     struct MappingArray
00102     : public std::vector< typename Codim< codim >::Mapping * >
00103     {};
00104 
00106     typedef GenericGeometry::CodimTable< MappingArray, dim > MappingsTable;
00107 
00108     std::vector< SubEntityInfo > info_[ dim+1 ];
00109     
00111     double volume_;
00112     std::vector< FieldVector< ctype, dim > > volumeNormals_;
00113 
00115     MappingsTable mappings_;
00116 
00117   public:
00122     int size ( int c ) const
00123     {
00124       assert( (c >= 0) && (c <= dim) );
00125       return info_[ c ].size();
00126     }
00127 
00139     int size ( int i, int c, int cc ) const
00140     {
00141       assert( (c >= 0) && (c <= dim) );
00142       return info_[ c ][ i ].size( cc );
00143     }
00144 
00158     int subEntity ( int i, int c, int ii, int cc ) const
00159     {
00160       assert( (c >= 0) && (c <= dim) );
00161       return info_[ c ][ i ].number( ii, cc );
00162     }
00163 
00173     const FieldVector< ctype, dim > &position( int i, int c ) const
00174     {
00175       assert( (c >= 0) && (c <= dim) );
00176       return info_[ c ][ i ].position();
00177     }
00178     
00186     bool checkInside ( const FieldVector< ctype, dim > &local ) const
00187     {
00188       return checkInside< 0 >( local, 0 );
00189     }
00190 
00205     template< int codim >
00206     bool checkInside ( const FieldVector< ctype, dim-codim > &local, int i ) const
00207     {
00208       return mapping< codim >( i ).checkInside( local );
00209     }
00210 
00232     template< int codim >
00233     FieldVector< ctype, dim >
00234     global( const FieldVector< ctype, dim-codim > &local, int i, int c ) const
00235     {
00236       if( c != codim )
00237         DUNE_THROW( Exception, "Local Coordinate Type does not correspond to codimension c." );
00238       assert( c == codim );
00239       return mapping< codim >( i ).global( local );
00240     }
00241 
00260     template< int codim >
00261     FieldVector< ctype, dim >
00262     global( const FieldVector< ctype, dim-codim > &local, int i ) const
00263     {
00264       return mapping< codim >( i ).global( local );
00265     }
00266 
00282     template< int codim >
00283     typename Codim< codim >::Mapping &mapping( int i ) const
00284     {
00285       integral_constant< int, codim > codimVariable;
00286       return *(mappings_[ codimVariable ][ i ]);
00287     }
00288 
00297     const GeometryType &type ( int i, int c ) const
00298     {
00299       assert( (c >= 0) && (c <= dim) );
00300       return info_[ c ][ i ].type();
00301     }
00302 
00303     unsigned int topologyId ( int i, int c ) const DUNE_DEPRECATED
00304     {
00305       assert( (c >= 0) && (c <= dim) );
00306       return info_[ c ][ i ].topologyId();
00307     }
00308 
00310     double volume () const
00311     {
00312       return volume_;
00313     }
00314 
00322     const FieldVector< ctype, dim > &volumeOuterNormal ( int face ) const
00323     {
00324       assert( (face >= 0) && (face < int( volumeNormals_.size())) );
00325       return volumeNormals_[ face ];
00326     }
00327 
00334     template< class Topology >
00335     void initializeTopology ()
00336     {
00337       dune_static_assert( (Topology::dimension == dim),
00338                           "Cannot initialize reference element for different dimension." );
00339       typedef Initialize< Topology > Init;
00340       typedef GenericGeometry::VirtualMapping< Topology, GeometryTraits > VirtualMapping;
00341 
00342       // set up subentities
00343       integral_constant< int, 0 > codim0Variable;
00344       mappings_[ codim0Variable ].resize( 1 );
00345       mappings_[ codim0Variable ][ 0 ]  = new VirtualMapping( codim0Variable );
00346 
00347       Dune::ForLoop< Init::template Codim, 0, dim >::apply( info_, mappings_ );
00348       
00349       // compute reference element volume
00350       typedef GenericGeometry::ReferenceDomain< Topology > ReferenceDomain;
00351       volume_ = ReferenceDomain::template volume< double >();
00352       
00353       // compute normals
00354       volumeNormals_.resize( ReferenceDomain::numNormals );
00355       for( unsigned int i = 0; i < ReferenceDomain::numNormals; ++i )
00356         ReferenceDomain::integrationOuterNormal( i ,volumeNormals_[ i ] );
00357     }
00358   };
00359 
00360 
00364   template< class ctype, int dim >
00365   class GenericReferenceElement< ctype, dim >::SubEntityInfo
00366   {
00367     template< class Topology, int codim > struct Initialize
00368     {
00369       template< int subcodim > struct SubCodim;
00370     };
00371 
00372     int codim_;
00373     std::vector< int > numbering_[ dim+1 ];
00374     FieldVector< ctype, dim > baryCenter_;
00375     GeometryType type_;
00376 
00377   public:
00378     int size ( int cc ) const
00379     {
00380       assert( (cc >= codim_) && (cc <= dim) );
00381       return numbering_[ cc ].size();
00382     }
00383 
00384     int number ( int ii, int cc ) const
00385     {
00386       assert( (cc >= codim_) && (cc <= dim) );
00387       return numbering_[ cc ][ ii ];
00388     }
00389 
00390     const FieldVector< ctype, dim > &position () const
00391     {
00392       return baryCenter_;
00393     }
00394 
00395     const GeometryType &type () const
00396     {
00397       return type_;
00398     }
00399 
00400     unsigned int topologyId () const DUNE_DEPRECATED
00401     {
00402       return type_.id();
00403     }
00404 
00405     template< class Topology, unsigned int codim, unsigned int i >
00406     void initialize ()
00407     {
00408       typedef Initialize< Topology, codim > Init;
00409       typedef GenericGeometry::ReferenceDomain< Topology > RefDomain;
00410 
00411       codim_ = codim;
00412 
00413       const unsigned int iVariable = i;
00414       Dune::ForLoop< Init::template SubCodim, 0, dim-codim >::apply( iVariable, numbering_ );
00415 
00416       baryCenter_ = ctype( 0 );
00417       static const unsigned int numCorners = size( dim );
00418       for( unsigned int j = 0; j < numCorners; ++j )
00419       {
00420         FieldVector< ctype, dim > corner;
00421         RefDomain::corner( number( j, dim ), corner );
00422         baryCenter_ += corner;
00423       }
00424       baryCenter_ *= ctype( 1 ) / ctype( numCorners );
00425 
00426       typedef typename GenericGeometry::SubTopology< Topology, codim, i >::type SubTopology;
00427       type_ = GeometryType( SubTopology::id, SubTopology::dimension );
00428       // type_ = GenericGeometry::DuneGeometryType< SubTopology, GeometryType::simplex >::type();
00429     }
00430   };
00431 
00432 
00433   template< class ctype, int dim >
00434   template< class Topology >
00435   class GenericReferenceElement< ctype, dim >::CornerStorage
00436   {
00437     typedef GenericGeometry::ReferenceDomain< Topology > RefDomain;
00438 
00439   public:
00440     static const unsigned int size = Topology::numCorners;
00441 
00442     template< class SubTopology >
00443     struct SubStorage
00444     {
00445       typedef CornerStorage< SubTopology > type;
00446     };
00447 
00448     explicit CornerStorage ( const integral_constant< int, 0 > & )
00449     {
00450       for( unsigned int i = 0; i < size; ++i )
00451         RefDomain::corner( i, coords_[ i ] );
00452     }
00453 
00454     template< class Mapping, unsigned int codim >
00455     explicit
00456     CornerStorage ( const GenericGeometry::SubMappingCoords< Mapping, codim > &coords )
00457     {
00458       for( unsigned int i = 0; i < size; ++i )
00459         coords_[ i ] = coords[ i ];
00460     }
00461 
00462     const FieldVector< ctype, dim > &operator[] ( unsigned int i ) const
00463     {
00464       return coords_[ i ];
00465     }
00466 
00467   private:
00468     FieldVector< ctype, dim > coords_[ size ];
00469   };
00470 
00471 
00472   template< class ctype, int dim >
00473   template< class Topology, int codim >
00474   template< int subcodim >
00475   struct GenericReferenceElement< ctype, dim >::SubEntityInfo::Initialize< Topology, codim >::SubCodim
00476   {
00477     typedef GenericGeometry::SubTopologySize< Topology, codim, subcodim > SubSize;
00478     typedef GenericGeometry::GenericSubTopologyNumbering< Topology, codim, subcodim > SubNumbering;
00479     
00480     static void apply ( unsigned int i, std::vector< int > (&numbering)[ dim+1 ] )
00481     {
00482       const unsigned int size = SubSize::size( i );
00483       numbering[ codim+subcodim ].resize( size );
00484       for( unsigned int j = 0; j < size; ++j )
00485         numbering[ codim+subcodim ][ j ] = SubNumbering::number( i, j );
00486     }
00487   };
00488 
00489 
00490   template< class ctype, int dim >
00491   template< class Topology >
00492   struct GenericReferenceElement< ctype, dim >::Initialize
00493   {
00494     typedef Dune::GenericReferenceElement< ctype, dim > GenericReferenceElement;
00495 
00496     typedef typename GenericReferenceElement::template Codim< 0 >::Mapping ReferenceMapping;
00497 
00498     template< int codim >
00499     struct Codim
00500     {
00501       template< int i >
00502       struct SubTopology
00503       {
00504         static void apply ( std::vector< SubEntityInfo > &info )
00505         {
00506           info[ i ].template initialize< Topology, codim, i >();
00507         }
00508       };
00509 
00510       static void
00511       apply ( std::vector< SubEntityInfo > (&info)[ dim+1 ],
00512               MappingsTable &mappings )
00513       {
00514         const unsigned int size = GenericGeometry::Size< Topology, codim >::value;
00515         info[ codim ].resize( size );
00516         Dune::ForLoop< SubTopology, 0, size-1 >::apply( info[ codim ] );
00517 
00518         if( codim > 0 )
00519         {
00520           integral_constant< int, 0 > codim0Variable;
00521           const ReferenceMapping &refMapping = *(mappings[ codim0Variable ][ 0 ]);
00522           
00523           typedef typename GenericGeometry::MappingProvider< ReferenceMapping, codim > MappingProvider;
00524 
00525           integral_constant< int, codim > codimVariable;
00526           mappings[ codimVariable ].resize( size );
00527           for( unsigned int i = 0; i < size; ++i ) {
00528               char* storage = new char[MappingProvider::maxMappingSize];
00529             mappings[ codimVariable ][ i ] = refMapping.template trace< codim >( i, storage );
00530           }
00531         }
00532       }
00533     };
00534   };
00535 
00536 
00537 
00538   template< class ctype, int dim >
00539   template< int codim >
00540   struct GenericReferenceElement< ctype, dim >::Destroy
00541   {
00542     static void apply ( MappingsTable &mappings )
00543     {
00544       if (codim > 0 )
00545       {
00546         integral_constant< int, codim > codimVariable;
00547         for( size_t i = 0; i < mappings[ codimVariable ].size(); ++i ) {
00548            typedef typename Codim<codim>::Mapping Mapping;
00549            mappings[ codimVariable ][ i ]->~Mapping();
00550            char* storage = (char*)mappings[ codimVariable ][ i ];
00551            delete[](storage);
00552         }
00553       }
00554     }
00555   };
00556 
00557 
00558 
00559   // GenericReferenceElementContainer
00560   // --------------------------------
00561 
00562   template< class ctype, int dim >
00563   class GenericReferenceElementContainer
00564   {
00565     static const unsigned int numTopologies = (1u << dim);
00566 
00567   public:
00568     typedef GenericReferenceElement< ctype, dim > value_type;
00569 
00570     const value_type &operator() ( const unsigned int topologyId ) const DUNE_DEPRECATED
00571     {
00572       return values_[ topologyId ];
00573     }
00574 
00575     const value_type &operator() ( const GeometryType &type ) const
00576     {
00577       assert( type.dim() == dim );
00578       return values_[ type.id() ];
00579     }
00580 
00581     const value_type &simplex () const
00582     {
00583       return values_[ GenericGeometry::SimplexTopology< dim >::type::id ];
00584     }
00585 
00586     const value_type &cube () const
00587     {
00588       return values_[ GenericGeometry::CubeTopology< dim >::type::id ];
00589     }
00590 
00591     const value_type &pyramid () const
00592     {
00593       return values_[ GenericGeometry::PyramidTopology< dim >::type::id ];
00594     }
00595 
00596     const value_type &prism () const
00597     {
00598       return values_[ GenericGeometry::PrismTopology< dim >::type::id ];
00599     }
00600 
00601     static const GenericReferenceElementContainer &instance ()
00602     {
00603       static GenericReferenceElementContainer inst;
00604       return inst;
00605     }
00606     
00607   private:
00608     template< int topologyId >
00609     struct Builder
00610     {
00611       static void apply ( value_type (&values)[ numTopologies ] )
00612       {
00613         typedef typename GenericGeometry::Topology< topologyId, dim >::type Topology;
00614         values[ topologyId ].template initializeTopology< Topology >();
00615       }
00616     };
00617 
00618     GenericReferenceElementContainer ()
00619     {
00620       ForLoop< Builder, 0, numTopologies-1 >::apply( values_ );
00621     }
00622     
00623     value_type values_[ numTopologies ];
00624   };
00625 
00626 
00627   // GenericReferenceElements
00628   // ------------------------
00629 
00638   template< class ctype, int dim >
00639   struct GenericReferenceElements
00640   {
00642     static const GenericReferenceElement< ctype, dim > &
00643     general ( const GeometryType &type )
00644     {
00645       return GenericReferenceElementContainer< ctype, dim >::instance()( type );
00646     }
00647 
00649     static const GenericReferenceElement< ctype, dim > &simplex ()
00650     {
00651       return GenericReferenceElementContainer< ctype, dim >::instance().simplex();
00652     }
00653 
00655     static const GenericReferenceElement< ctype, dim > &cube ()
00656     {
00657       return GenericReferenceElementContainer< ctype, dim >::instance().cube();
00658     }
00659   };
00660 
00661 }
00662 
00663 #endif // #ifndef DUNE_GENERICREFERENCEELEMENTS_HH

Generated on Fri Apr 29 2011 with Doxygen (ver 1.7.1) [doxygen-log,error-log].