dune-geometry  2.2.0
referencedomain.hh
Go to the documentation of this file.
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