shards Version of the Day
Shards_CellTopologyTraits.hpp
00001 /*
00002 //@HEADER
00003 // ************************************************************************
00004 //
00005 //                Shards : Shared Discretization Tools
00006 //                 Copyright 2008 Sandia Corporation
00007 //
00008 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00009 // the U.S. Government retains certain rights in this software.
00010 //
00011 // Redistribution and use in source and binary forms, with or without
00012 // modification, are permitted provided that the following conditions are
00013 // met:
00014 //
00015 // 1. Redistributions of source code must retain the above copyright
00016 // notice, this list of conditions and the following disclaimer.
00017 //
00018 // 2. Redistributions in binary form must reproduce the above copyright
00019 // notice, this list of conditions and the following disclaimer in the
00020 // documentation and/or other materials provided with the distribution.
00021 //
00022 // 3. Neither the name of the Corporation nor the names of the
00023 // contributors may be used to endorse or promote products derived from
00024 // this software without specific prior written permission.
00025 //
00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037 //
00038 // Questions? Contact Carter Edwards (hcedwar@sandia.gov),
00039 //                    Pavel Bochev (pbboche@sandia.gov), or
00040 //                    Denis Ridzal (dridzal@sandia.gov).
00041 //
00042 // ************************************************************************
00043 //@HEADER
00044 */
00045 
00046 #ifndef Shards_CellTopologyTraits_hpp
00047 #define Shards_CellTopologyTraits_hpp
00048 
00049 #include <Shards_TypeList.hpp>
00050 #include <Shards_IndexList.hpp>
00051 #include <Shards_CellTopologyData.h>
00052 
00053 namespace shards {
00054 
00062 template< class Traits >
00063 const CellTopologyData * getCellTopologyData();
00064 
00065 template< unsigned Dimension ,
00066           unsigned Number_Vertex ,
00067           unsigned Number_Node ,
00068           class    EdgeList = TypeListEnd ,
00069           class    EdgeMaps = TypeListEnd ,
00070           class    FaceList = TypeListEnd ,
00071           class    FaceMaps = TypeListEnd ,
00072           class    PermutationMaps = TypeListEnd ,
00073           class    PermutationPolarity = IndexList<> >
00074 struct CellTopologyTraits ;
00075 
00076 struct Node ;
00077 
00078 //----------------------------------------------------------------------
00079 //----------------------------------------------------------------------
00080 // Implementation details for a much of this file ...
00081 
00082 #ifndef DOXYGEN_COMPILE
00083 
00084 template< class CellTop , class CellMap , unsigned Index , bool Good >
00085 struct SubcellNodeIndex ;
00086 
00087 template< class CellTop , class CellMap , unsigned Index >
00088 struct SubcellNodeIndex< CellTop , CellMap , Index , false >
00089 { enum { value = ~0u }; };
00090 
00091 template< class CellTop , class CellMap , unsigned Index >
00092 struct SubcellNodeIndex< CellTop , CellMap , Index , true >
00093 {
00094   enum { value = Index < CellTop::template subcell<0>::count
00095                ? IndexListAt< CellMap , Index >::value : ~0u };
00096 };
00097 
00098 //----------------------------------------------------------------------
00099 
00100 template< unsigned SubcellDim , unsigned SubcellOrd , unsigned NodeIndex ,
00101           unsigned Dimension , unsigned Number_Vertex , unsigned Number_Node ,
00102           class EdgeList , class EdgeMaps ,
00103           class FaceList , class FaceMaps ,
00104           class PermMaps , class Pol>
00105 struct SubcellTopologyTraits ;
00106 
00107 template< class ListType > struct TypeListHomogeneous ;
00108 
00109 //----------------------------------------------------------------------
00110 // Self-subcell reference
00111 
00112 template<>
00113 struct SubcellTopologyTraits<0,0,0,0,0,0,TypeListEnd,TypeListEnd,
00114                                          TypeListEnd,TypeListEnd,
00115                                          TypeListEnd,IndexList<> >
00116 {
00117   typedef CellTopologyTraits<0,0,0> topology ;
00118   enum { count = 1 };
00119   enum { node = ~0u };
00120   enum { homogeneity = true };
00121 };
00122 
00123 template< unsigned NodeIndex ,
00124           unsigned NV , unsigned NN ,
00125           class EList , class EMaps ,
00126           class FList , class FMaps ,
00127           class PMaps , class Pol>
00128 struct SubcellTopologyTraits<1,0,NodeIndex, 1,NV,NN,EList,EMaps,FList,FMaps,PMaps,Pol>
00129 {
00130   typedef CellTopologyTraits<1,NV,NN,EList,EMaps,FList,FMaps,PMaps,Pol> topology ;
00131   enum { count = 1 };
00132   enum { node = NodeIndex < NN ? NodeIndex : ~0u };
00133   enum { homogeneity = true };
00134 };
00135 
00136 template< unsigned NodeIndex ,
00137           unsigned NV , unsigned NN ,
00138           class EList , class EMaps ,
00139           class FList , class FMaps ,
00140           class PMaps , class Pol>
00141 struct SubcellTopologyTraits<2,0,NodeIndex, 2,NV,NN,EList,EMaps,FList,FMaps,PMaps,Pol>
00142 {
00143   typedef CellTopologyTraits<2,NV,NN,EList,EMaps,FList,FMaps,PMaps,Pol> topology ;
00144   enum { count = 1 };
00145   enum { node = NodeIndex < NN ? NodeIndex : ~0u };
00146   enum { homogeneity = true };
00147 };
00148 
00149 template< unsigned NodeIndex ,
00150           unsigned NV , unsigned NN ,
00151           class EList , class EMaps ,
00152           class FList , class FMaps ,
00153           class PMaps , class Pol>
00154 struct SubcellTopologyTraits<3,0,NodeIndex, 3,NV,NN,EList,EMaps,FList,FMaps,PMaps,Pol>
00155 {
00156   typedef CellTopologyTraits<3,NV,NN,EList,EMaps,FList,FMaps,PMaps,Pol> topology ;
00157   enum { count = 1 };
00158   enum { node = NodeIndex < NN ? NodeIndex : ~0u };
00159   enum { homogeneity = true };
00160 };
00161 
00162 //----------------------------------------------------------------------
00163 // Node-subcell reference:
00164 
00165 template< unsigned SubcellOrd ,
00166           unsigned D , unsigned NV , unsigned NN ,
00167           class EList , class EMaps ,
00168           class FList , class FMaps ,
00169           class PMaps , class Pol>
00170 struct SubcellTopologyTraits<0,SubcellOrd,0, D,NV,NN,EList,EMaps,FList,FMaps,PMaps,Pol>
00171 {
00172   typedef CellTopologyTraits<0,0,0> topology ;
00173   enum { count = NN };
00174   enum { node = SubcellOrd < NN ? SubcellOrd : ~0u };
00175   enum { homogeneity = true };
00176 };
00177 
00178 // Edge-subcell reference:
00179 
00180 template< unsigned SubcellOrd , unsigned NodeIndex ,
00181           unsigned D , unsigned NV , unsigned NN ,
00182           class EList , class EMaps ,
00183           class FList , class FMaps ,
00184           class PMaps , class Pol>
00185 struct SubcellTopologyTraits<1,SubcellOrd,NodeIndex,
00186                              D,NV,NN,EList,EMaps,FList,FMaps,PMaps,Pol>
00187 {
00188 private:
00189   typedef typename TypeListAt<EMaps,SubcellOrd>::type node_map ;
00190 public:
00191 
00192   typedef typename TypeListAt<EList,SubcellOrd>::type topology ;
00193 
00194   enum { count = TypeListLength<EList>::value };
00195 
00196   enum { node = SubcellNodeIndex< topology , node_map , NodeIndex ,
00197                                   SubcellOrd < count >::value };
00198 
00199   enum { homogeneity = TypeListHomogeneous<EList>::value };
00200 };
00201 
00202 // Face-subcell reference:
00203 
00204 template< unsigned SubcellOrd , unsigned NodeIndex ,
00205           unsigned D , unsigned NV , unsigned NN ,
00206           class EList , class EMaps ,
00207           class FList , class FMaps ,
00208           class PMaps , class Pol>
00209 struct SubcellTopologyTraits< 2, SubcellOrd, NodeIndex,
00210                               D,NV,NN,EList,EMaps,FList,FMaps,PMaps,Pol >
00211 {
00212 private:
00213   typedef typename TypeListAt<FMaps,SubcellOrd>::type node_map ;
00214 public:
00215 
00216   typedef typename TypeListAt<FList,SubcellOrd>::type topology ;
00217 
00218   enum { count = TypeListLength<FList>::value };
00219 
00220   enum { node = SubcellNodeIndex< topology , node_map , NodeIndex ,
00221                                   SubcellOrd < count >::value };
00222 
00223   enum { homogeneity = TypeListHomogeneous<FList>::value };
00224 };
00225 
00226 //----------------------------------------------------------------------
00227 // Only partially specialized subcell references are valid.
00228 
00229 template< unsigned SubcellDim , unsigned SubcellOrd , unsigned NodeIndex ,
00230           unsigned Dimension ,
00231           unsigned Number_Vertex , unsigned Number_Node ,
00232           class EdgeList , class EdgeMaps ,
00233           class FaceList , class FaceMaps ,
00234           class PermMaps , class Pol >
00235 struct SubcellTopologyTraits
00236 {
00237   typedef void topology ;
00238   enum { count = 0 };
00239   enum { node = ~0u };
00240   enum { homogeneity = false };
00241 };
00242 
00243 //----------------------------------------------------------------------
00244 
00245 template<>
00246 struct TypeListHomogeneous<TypeListEnd> {
00247   enum { value = true };
00248 };
00249 
00250 template< class T >
00251 struct TypeListHomogeneous< TypeList<T,TypeListEnd> > {
00252   enum { value = true };
00253 };
00254 
00255 template< class T , class Tail >
00256 struct TypeListHomogeneous< TypeList< T, TypeList< T , Tail > > > {
00257   enum { value = TypeListHomogeneous< TypeList<T,Tail> >::value };
00258 };
00259 
00260 template< class ListType >
00261 struct TypeListHomogeneous 
00262 {
00263   enum { value = false };
00264 };
00265 
00266 //----------------------------------------------------------------------
00267 
00268 template< unsigned I , unsigned J > struct AssertEqual ;
00269 
00270 template< unsigned I > struct AssertEqual<I,I> { enum { OK = true }; };
00271 
00272 #endif /* DOXYGEN_COMPILE */
00273 
00274 //----------------------------------------------------------------------
00276 template< unsigned Dimension , unsigned Number_Vertex , unsigned Number_Node ,
00277           class EdgeList , class EdgeMaps ,
00278           class FaceList , class FaceMaps ,
00279           class PermutationMaps ,
00280           class PermutationPolarity >
00281 struct CellTopologyTraits
00282 {
00284   typedef CellTopologyTraits< Dimension, Number_Vertex, Number_Node,
00285                               EdgeList, EdgeMaps, FaceList, FaceMaps,
00286                               PermutationMaps, PermutationPolarity > Traits ;
00287 
00288   enum {
00290     dimension    = Dimension ,
00291 
00293     vertex_count = Number_Vertex ,
00294 
00296     node_count   = Number_Node ,
00297 
00299     edge_count   = TypeListLength<EdgeList>::value ,
00300 
00301 #ifndef DOXYGEN_COMPILE
00302     face_count   = TypeListLength<FaceList>::value ,
00303 #endif
00304 
00306     side_count   = Dimension == 3 ? face_count : (
00307                    Dimension == 2 ? edge_count : 0 ),
00308 
00316     key  = ( dimension    << 28 /*  4 bits, max    7 */ ) |
00317            ( face_count   << 22 /*  6 bits, max   63 */ ) |
00318            ( edge_count   << 16 /*  6 bits, max   63 */ ) |
00319            ( vertex_count << 10 /*  6 bits, max   63 */ ) |
00320            ( node_count         /* 10 bits, max 1023 */ ) };
00321 
00329   template< unsigned Dim, unsigned Ord = 0, unsigned J = 0 >
00330   struct subcell :
00331     public SubcellTopologyTraits< Dim , Ord , J ,
00332                                   dimension , vertex_count , node_count ,
00333                                   EdgeList , EdgeMaps ,
00334                                   FaceList , FaceMaps ,
00335                                   PermutationMaps, PermutationPolarity > {};
00336 
00344   template< unsigned Ord = 0 , unsigned J = 0 >
00345   struct side :
00346     public SubcellTopologyTraits< ( 1 < dimension ? dimension - 1 : 4 ) ,
00347                                   Ord , J ,
00348                                   dimension , vertex_count , node_count ,
00349                                   EdgeList , EdgeMaps ,
00350                                   FaceList , FaceMaps ,
00351                                   TypeListEnd , IndexList<> > {};
00352 
00360   template< unsigned Ord = 0 , unsigned J = 0 >
00361   struct edge :
00362     public SubcellTopologyTraits< ( 1 < dimension ? 1 : 4 ) , Ord , J ,
00363                                   dimension , vertex_count , node_count ,
00364                                   EdgeList , EdgeMaps ,
00365                                   TypeListEnd , TypeListEnd ,
00366                                   TypeListEnd , IndexList<> > {};
00367 
00368   //--------------------------------------------------------------------
00386   template< unsigned Perm , unsigned J = 0 >
00387   struct permutation {
00388   private:
00389     typedef typename TypeListAt< PermutationMaps , Perm >::type node_map ;
00390   public:
00391     enum { node = J < node_count ? IndexListAt< node_map , J >::value : ~0u };
00392     enum { polarity = IndexListAt< PermutationPolarity , Perm >::value };
00393   };
00394 
00395   template< unsigned Perm , unsigned J = 0 >
00396   struct permutation_inverse {
00397   private:
00398     typedef typename TypeListAt< PermutationMaps , Perm >::type forward_map ;
00399     typedef typename IndexListInverse< forward_map >::type node_map ;
00400   public:
00401     enum { node = J < node_count ? IndexListAt< node_map , J >::value : ~0u };
00402     enum { polarity = IndexListAt< PermutationPolarity , Perm >::value };
00403   };
00404 
00405   enum { permutation_count = TypeListLength< PermutationMaps >::value };
00406 
00407   //--------------------------------------------------------------------
00408 
00409 private:
00410 
00411 #ifndef DOXYGEN_COMPILE
00412 
00413   enum { nedge_map = TypeListLength<EdgeMaps>::value ,
00414          nface_map = TypeListLength<FaceMaps>::value ,
00415          polarity_count = IndexListLength< PermutationPolarity >::value };
00416 
00417   enum { OK_edge  = AssertEqual< edge_count , nedge_map >::OK };
00418   enum { OK_face  = AssertEqual< face_count , nface_map >::OK };
00419   enum { OK_dimen = AssertEqual< 0 , (dimension    >>  3) >::OK };
00420   enum { OK_faceN = AssertEqual< 0 , (face_count   >>  6) >::OK };
00421   enum { OK_edgeN = AssertEqual< 0 , (edge_count   >>  6) >::OK };
00422   enum { OK_vertN = AssertEqual< 0 , (vertex_count >>  6) >::OK };
00423   enum { OK_nodeN = AssertEqual< 0 , (node_count   >> 10) >::OK };
00424   enum { OK_permN = AssertEqual< permutation_count, polarity_count >::OK };
00425 
00426 #endif
00427 
00428 };
00429 
00432 } // namespace shards
00433 
00434 #endif // Shards_CellTopologyTraits_hpp
00435 
 All Classes Functions Variables Typedefs Enumerator