dune-geometry  2.2.0
traceprovider.hh
Go to the documentation of this file.
00001 #ifndef DUNE_GEOMETRY_GENERICGEOMETRY_TRACEPROVIDER_HH
00002 #define DUNE_GEOMETRY_GENERICGEOMETRY_TRACEPROVIDER_HH
00003 
00004 #include <dune/common/forloop.hh>
00005 #include <dune/common/typetraits.hh>
00006 
00007 #include "mapping.hh"
00008 #include "subtopologies.hh"
00009 
00010 namespace Dune
00011 {
00012 
00013   namespace GenericGeometry
00014   {
00015 
00016     // External Forward Declarations
00017     // -----------------------------
00018 
00019     template< class Topology, class GeometryTraits >
00020     class NonHybridMapping;
00021 
00022     template< unsigned int dim, class GeometryTraits >
00023     class HybridMapping;
00024 
00025     template< class Topology, class GeometryTraits >
00026     class VirtualMapping;
00027 
00028 
00029 
00030     // TraceProvider
00031     // -------------
00032 
00033     template< class Topology, class GeometryTraits, unsigned int codim, bool forceHybrid >
00034     class TraceProvider
00035     {
00036       typedef TraceProvider< Topology, GeometryTraits, codim, forceHybrid > This;
00037 
00038       typedef typename GeometryTraits::template Mapping< Topology >::type MappingImpl;
00039 
00040     public:
00041       static const unsigned int dimension = Topology::dimension;
00042       static const unsigned int codimension = codim;
00043       static const unsigned int mydimension = dimension - codimension;
00044 
00045       static const bool hybrid = (forceHybrid || IsCodimHybrid< Topology, codim >::value);
00046 
00047       typedef GenericGeometry::Mapping< typename GeometryTraits::CoordTraits, Topology, GeometryTraits::dimWorld, MappingImpl > Mapping;
00048 
00049     private:
00050       static const unsigned int numSubTopologies = Mapping::ReferenceElement::template Codim< codimension >::size;
00051 
00052       template< bool > class HybridFactory;
00053       template< bool > class NonHybridFactory;
00054 
00055       typedef typename SelectType< hybrid, HybridFactory< true >, NonHybridFactory< false > >::Type Factory;
00056 
00057       template< int i > struct Builder;
00058 
00059     public:
00060       typedef typename Factory::Trace Trace;
00061 
00062       static Trace *construct ( const Mapping &mapping, unsigned int i, char *traceStorage )
00063       {
00064         return (*instance().construct_[ i ])( mapping, traceStorage );
00065       }
00066 
00067     private:
00068       typedef Trace *(*Construct) ( const Mapping &mapping, char *traceStorage );
00069 
00070       TraceProvider ()
00071       {
00072         ForLoop< Builder, 0, numSubTopologies-1 >::apply( construct_ );
00073       }
00074 
00075       static const This &instance ()
00076       {
00077         static This theInstance;
00078         return theInstance;
00079       }
00080 
00081       Construct construct_[ numSubTopologies ];
00082     };
00083 
00084 
00085 
00086     // TraceProvider::HybridFactory
00087     // ----------------------------
00088 
00089     template< class Topology, class GeometryTraits, unsigned int codim, bool forceHybrid >
00090     template< bool >
00091     class TraceProvider< Topology, GeometryTraits, codim, forceHybrid >::HybridFactory
00092     {
00093       template< unsigned int i >
00094       struct VirtualTrace
00095       {
00096         typedef typename GenericGeometry::SubTopology< Topology, codim, i >::type SubTopology;
00097         typedef VirtualMapping< SubTopology, GeometryTraits > type;
00098       };
00099 
00100     public:
00101       typedef HybridMapping< mydimension, GeometryTraits > Trace;
00102 
00103       template< int i >
00104       static Trace *construct ( const Mapping &mapping, char *traceStorage )
00105       {
00106         typedef typename VirtualTrace< i >::type TraceImpl;
00107         return new( traceStorage ) TraceImpl( mapping.template trace< codim, i >() );
00108       }
00109     };
00110 
00111 
00112 
00113     // TraceProvider::NonHybridFactory
00114     // -------------------------------
00115 
00116     template< class Topology, class GeometryTraits, unsigned int codim, bool forceHybrid >
00117     template< bool >
00118     class TraceProvider< Topology, GeometryTraits, codim, forceHybrid >::NonHybridFactory
00119     {
00120       typedef typename GenericGeometry::SubTopology< Topology, codim, 0 >::type SubTopology;
00121 
00122     public:
00123       typedef NonHybridMapping< SubTopology, GeometryTraits > Trace;
00124 
00125       template< int i >
00126       static Trace *construct ( const Mapping &mapping, char *traceStorage )
00127       {
00128         return new( traceStorage ) Trace( mapping.template trace< codim, i >() );
00129       }
00130     };
00131 
00132 
00133 
00134     // TraceProvider::Builder
00135     // ----------------------
00136 
00137     template< class Topology, class GeometryTraits, unsigned int codim, bool forceHybrid >
00138     template< int i >
00139     struct TraceProvider< Topology, GeometryTraits, codim, forceHybrid >::Builder
00140     {
00141       static void apply ( Construct (&construct)[ numSubTopologies ] )
00142       {
00143         construct[ i ] = &(Factory::template construct< i >);
00144       }
00145     };
00146 
00147   } // namespace GenericGeometry
00148 
00149 } // namespace Dune
00150 
00151 #endif // #ifndef DUNE_GEOMETRY_GENERICGEOMETRY_TRACEPROVIDER_HH