dune-geometry
2.2.0
|
00001 #ifndef DUNE_GEOMETRY_GENERICGEOMETRY_REFERENCEDOMAIN_HH 00002 #define DUNE_GEOMETRY_GENERICGEOMETRY_REFERENCEDOMAIN_HH 00003 00004 #include <dune/common/array.hh> 00005 #include <dune/common/fvector.hh> 00006 #include <dune/common/typetraits.hh> 00007 00008 #include <dune/geometry/genericgeometry/topologytypes.hh> 00009 #include <dune/geometry/genericgeometry/subtopologies.hh> 00010 00011 namespace Dune 00012 { 00013 00014 namespace GenericGeometry 00015 { 00016 00017 // Internal Forward Declarations 00018 // ----------------------------- 00019 00020 template< class Topology > 00021 struct ReferenceDomain; 00022 00023 00024 00025 // ReferenceDomain 00026 // --------------- 00027 00028 template< class Topology > 00029 class ReferenceDomainBase; 00030 00032 template<> 00033 class ReferenceDomainBase< Point > 00034 { 00035 typedef Point Topology; 00036 00037 friend struct ReferenceDomain< Topology >; 00038 friend class ReferenceDomainBase< Prism< Topology > >; 00039 friend class ReferenceDomainBase< Pyramid< Topology > >; 00040 00041 static const unsigned int numNormals = 0; 00042 00043 template< class ctype, int dim > 00044 static void corner ( unsigned int i, FieldVector< ctype, dim > &n ) 00045 { 00046 assert( i < Topology::numCorners ); 00047 } 00048 00049 template< class ctype, int dim > 00050 static bool 00051 checkInside ( const FieldVector< ctype, dim > &x, ctype factor ) 00052 { 00053 return true; 00054 } 00055 00056 template< class ctype, int dim > 00057 static void 00058 integrationOuterNormal ( unsigned int i, FieldVector< ctype, dim > &n ) 00059 { 00060 assert( i < numNormals ); 00061 } 00062 00063 template< class ctype > 00064 static ctype volume () 00065 { 00066 return ctype( 1 ); 00067 } 00068 }; 00069 00070 00071 template< class BaseTopology > 00072 class ReferenceDomainBase< Prism< BaseTopology > > 00073 { 00074 typedef Prism< BaseTopology > Topology; 00075 00076 friend struct ReferenceDomain< Topology >; 00077 friend class ReferenceDomainBase< Prism< Topology > >; 00078 friend class ReferenceDomainBase< Pyramid< Topology > >; 00079 00080 static const unsigned int numNormals = Size< Topology, 1 >::value; 00081 00082 static const unsigned int dimension = Topology::dimension; 00083 static const unsigned int myindex = dimension - 1; 00084 00085 template< class ctype, int dim > 00086 static void corner ( unsigned int i, FieldVector< ctype, dim > &x ) 00087 { 00088 assert( i < Topology::numCorners ); 00089 const unsigned int j = i % BaseTopology::numCorners; 00090 ReferenceDomainBase< BaseTopology >::corner( j, x ); 00091 if( i >= BaseTopology::numCorners ) 00092 x[ myindex ] = ctype( 1 ); 00093 } 00094 00095 template< class ctype, int dim > 00096 static bool 00097 checkInside ( const FieldVector< ctype, dim > &x, ctype factor ) 00098 { 00099 const ctype xn = x[ myindex ]; 00100 const ctype cxn = factor - xn; 00101 return (xn > -1e-12) && (cxn > -1e-12) 00102 && ReferenceDomainBase< BaseTopology >::checkInside( x, factor ); 00103 } 00104 00105 template< class ctype, int dim > 00106 static void 00107 integrationOuterNormal ( unsigned int i, FieldVector< ctype, dim > &n ) 00108 { 00109 typedef ReferenceDomainBase< BaseTopology > BaseReferenceDomain; 00110 00111 if( i >= BaseReferenceDomain::numNormals ) 00112 { 00113 const unsigned int j = i - BaseReferenceDomain::numNormals; 00114 n[ myindex ] = (j == 0 ? ctype( -1 ) : ctype( 1 )); 00115 } 00116 else 00117 BaseReferenceDomain::integrationOuterNormal( i, n ); 00118 } 00119 00120 template< class ctype > 00121 static ctype volume () 00122 { 00123 typedef ReferenceDomainBase< BaseTopology > BaseReferenceDomain; 00124 return BaseReferenceDomain::template volume< ctype >(); 00125 } 00126 }; 00127 00128 00129 template< class BaseTopology > 00130 class ReferenceDomainBase< Pyramid< BaseTopology > > 00131 { 00132 typedef Pyramid< BaseTopology > Topology; 00133 00134 friend struct ReferenceDomain< Topology >; 00135 friend class ReferenceDomainBase< Prism< Topology > >; 00136 friend class ReferenceDomainBase< Pyramid< Topology > >; 00137 00138 static const unsigned int numNormals = Size< Topology, 1 >::value; 00139 00140 static const unsigned int dimension = Topology::dimension; 00141 static const unsigned int myindex = dimension - 1; 00142 00143 template< bool > 00144 struct MultiDimensional 00145 { 00146 template< class ctype, int dim > 00147 static void 00148 integrationOuterNormal ( unsigned int i, FieldVector< ctype, dim > &n ) 00149 { 00150 multiDimensionalIntegrationOuterNormal( i, n ); 00151 } 00152 }; 00153 00154 template< bool > 00155 struct OneDimensional 00156 { 00157 template< class ctype, int dim > 00158 static void 00159 integrationOuterNormal ( unsigned int i, FieldVector< ctype, dim > &n ) 00160 { 00161 n[ myindex ] = (i > 0) ? ctype( 1 ) : ctype( -1 ); 00162 } 00163 }; 00164 00165 template< class ctype, int dim > 00166 static void corner ( unsigned int i, FieldVector< ctype, dim > &x ) 00167 { 00168 assert( i < Topology::numCorners ); 00169 if( i < BaseTopology::numCorners ) 00170 ReferenceDomainBase< BaseTopology >::corner( i, x ); 00171 else 00172 x[ myindex ] = ctype( 1 ); 00173 } 00174 00175 template< class ctype, int dim > 00176 static bool 00177 checkInside ( const FieldVector< ctype, dim > &x, ctype factor ) 00178 { 00179 const ctype xn = x[ myindex ]; 00180 const ctype cxn = factor - xn; 00181 return (xn > -1e-12) && (cxn > -1e-12) 00182 && ReferenceDomainBase< BaseTopology >::checkInside( x, cxn ); 00183 } 00184 00185 template< class ctype, int dim > 00186 static void 00187 multiDimensionalIntegrationOuterNormal ( unsigned int i, FieldVector< ctype, dim > &n ) 00188 { 00189 typedef ReferenceDomainBase< BaseTopology > BaseReferenceDomain; 00190 typedef SubTopologyNumbering< BaseTopology, 1, dimension-2 > Numbering; 00191 00192 if( i > 0 ) 00193 { 00194 const unsigned int j = Numbering::number( i-1, 0 ); 00195 FieldVector< ctype, dim > x( ctype( 0 ) ); 00196 BaseReferenceDomain::corner( j, x ); 00197 00198 BaseReferenceDomain::integrationOuterNormal ( i-1, n ); 00199 n[ myindex ] = (x * n); 00200 } 00201 else 00202 n[ myindex ] = ctype( -1 ); 00203 } 00204 00205 template< class ctype, int dim > 00206 static void 00207 integrationOuterNormal ( unsigned int i, FieldVector< ctype, dim > &n ) 00208 { 00209 SelectType< (dimension > 1), MultiDimensional<true>, OneDimensional<false> > :: Type 00210 ::integrationOuterNormal( i, n ); 00211 } 00212 00213 template< class ctype > 00214 static ctype volume () 00215 { 00216 typedef ReferenceDomainBase< BaseTopology > BaseReferenceDomain; 00217 const ctype baseVolume = BaseReferenceDomain::template volume< ctype >(); 00218 return baseVolume / ctype( (unsigned int)(dimension) ); // linker problem when using dimension directly 00219 } 00220 }; 00225 // ReferenceDomain 00226 // --------------- 00227 00228 template< class Topology > 00229 struct ReferenceDomain 00230 { 00231 static const unsigned int numCorners = Topology::numCorners; 00232 static const unsigned int dimension = Topology::dimension; 00233 00234 static const unsigned int numNormals 00235 = ReferenceDomainBase< Topology >::numNormals; 00236 00237 template< class ctype > 00238 static void corner ( unsigned int i, FieldVector< ctype, dimension > &x ) 00239 { 00240 x = ctype( 0 ); 00241 ReferenceDomainBase< Topology >::corner( i, x ); 00242 } 00243 00244 template< class ctype > 00245 static bool checkInside ( const FieldVector< ctype, dimension > &x ) 00246 { 00247 return ReferenceDomainBase< Topology >::checkInside( x, ctype( 1 ) ); 00248 } 00249 00250 template< class ctype > 00251 static void 00252 integrationOuterNormal ( unsigned int i, FieldVector< ctype, dimension > &n ) 00253 { 00254 n = ctype( 0 ); 00255 return ReferenceDomainBase< Topology >::integrationOuterNormal( i, n ); 00256 } 00257 00258 template< class ctype > 00259 static ctype volume () 00260 { 00261 return ReferenceDomainBase< Topology >::template volume< ctype >(); 00262 } 00263 }; 00264 00265 } 00266 00267 } 00268 00269 #endif // DUNE_GEOMETRY_GENERICGEOMETRY_REFERENCEDOMAIN_HH