dune-grid  2.1.1
dynamicsubindexid.hh
Go to the documentation of this file.
00001 #ifndef DUNE_DYNAMICCODIMSUBINDEXID_HH
00002 #define DUNE_DYNAMICCODIMSUBINDEXID_HH
00003 
00004 #include <dune/common/forloop.hh>
00005 #include <dune/grid/genericgeometry/conversion.hh>
00006 #include <dune/common/typetraits.hh>
00007 
00008 namespace Dune
00009 {
00010 
00011   // DynamicSubIndex
00012   // ---------------
00013 
00014   template< class Grid, class IndexSet >
00015   class DynamicSubIndex
00016   {
00017     typedef DynamicSubIndex< Grid, IndexSet > This;
00018 
00019     typedef typename remove_const< Grid >::type::Traits Traits;
00020 
00021     static const unsigned int dimension = remove_const< Grid >::type::dimension;
00022 
00023     typedef typename Traits::template Codim< 0 >::Entity Element;
00024 
00025   public:
00026     typedef typename IndexSet::IndexType IndexType;
00027 
00028   private:
00029     struct Caller
00030     {
00031       virtual ~Caller ()
00032       {}
00033 
00034       virtual IndexType
00035       subIndex ( const IndexSet &indexSet, const Element &e, int i ) const = 0;
00036     };
00037 
00038     template< int codim >
00039     struct CallerImpl
00040     : public Caller
00041     {
00042       virtual IndexType
00043       subIndex ( const IndexSet &indexSet, const Element &e, int i ) const
00044       {
00045         typedef GenericGeometry::MapNumberingProvider< dimension > Numbering;
00046         const unsigned int tid = GenericGeometry::topologyId( e.type() );
00047         const int j = Numbering::template generic2dune< codim >( tid, i );
00048         return indexSet.template subIndex< codim >( e, j );
00049       }
00050 
00051       static void apply ( const Caller *(&caller)[ dimension+1 ] )
00052       {
00053         caller[ codim ] = new CallerImpl< codim >;
00054       }
00055     };
00056 
00057     // prohibit copying and assignment
00058     DynamicSubIndex ( const This & );
00059     This &operator= ( const This & );
00060 
00061   public:
00062     explicit DynamicSubIndex ( const IndexSet &indexSet )
00063     : indexSet_( indexSet )
00064     {
00065       Dune::ForLoop< CallerImpl, 0, dimension >::apply( caller_ );
00066     }
00067 
00068     ~DynamicSubIndex ()
00069     {
00070       for( unsigned int codim = 0; codim <= dimension; ++codim )
00071         delete caller_[ codim ];
00072     }
00073 
00074     IndexType operator() ( const Element &e, int i, unsigned int codim ) const
00075     {
00076       assert( codim <= dimension );
00077       return caller_[ codim ]->subIndex( indexSet_, e, i );
00078     }
00079 
00080   private:
00081     const IndexSet &indexSet_;
00082     const Caller *caller_[ dimension+1 ];
00083   };
00084 
00085 
00086 
00087   // DynamicSubId
00088   // ------------
00089 
00090   template< class Grid, class IdSet >
00091   class DynamicSubId
00092   {
00093     typedef DynamicSubId< Grid, IdSet > This;
00094 
00095     typedef typename remove_const< Grid >::type::Traits Traits;
00096 
00097     static const unsigned int dimension = remove_const< Grid >::type::dimension;
00098 
00099     typedef typename Traits::template Codim< 0 >::Entity Element;
00100 
00101   public:
00102     typedef typename IdSet::IdType IdType;
00103 
00104   private:
00105     struct Caller
00106     {
00107       virtual ~Caller ()
00108       {}
00109 
00110       virtual IdType
00111       subId ( const IdSet &idSet, const Element &e, int i ) const = 0;
00112     };
00113 
00114     template< int codim >
00115     struct CallerImpl
00116     : public Caller
00117     {
00118       virtual IdType
00119       subId ( const IdSet &idSet, const Element &e, int i ) const
00120       {
00121         typedef GenericGeometry::MapNumberingProvider< dimension > Numbering;
00122         const unsigned int tid = GenericGeometry::topologyId( e.type() );
00123         const int j = Numbering::template generic2dune< codim >( tid, i );
00124         return idSet.template subId< codim >( e, j );
00125       }
00126 
00127       static void apply ( const Caller *(&caller)[ dimension+1 ] )
00128       {
00129         caller[ codim ] = new CallerImpl< codim >;
00130       }
00131     };
00132 
00133     // prohibit copying and assignment
00134     DynamicSubId ( const This & );
00135     This &operator= ( const This & );
00136 
00137   public:
00138     explicit DynamicSubId ( const IdSet &idSet )
00139     : idSet_( idSet )
00140     {
00141       Dune::ForLoop< CallerImpl, 0, dimension >::apply( caller_ );
00142     }
00143 
00144     ~DynamicSubId ()
00145     {
00146       for( unsigned int codim = 0; codim <= dimension; ++codim )
00147         delete caller_[ codim ];
00148     }
00149 
00150     IdType operator() ( const Element &e, int i, unsigned int codim ) const
00151     {
00152       assert( codim <= dimension );
00153       return caller_[ codim ]->subId( idSet_, e, i );
00154     }
00155 
00156   private:
00157     const IdSet &idSet_;
00158     const Caller *caller_[ dimension+1 ];
00159   };
00160 
00161 }
00162 
00163 #endif // #ifndef DUNE_DYNAMICCODIMSUBINDEXID_HH