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