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 private:
00095   typedef typename CellTop::template subcell<0> subcell_node ;
00096 public:
00097   enum { value = Index < subcell_node::count
00098                ? IndexListAt< CellMap , Index >::value : ~0u };
00099 };
00100 
00101 //----------------------------------------------------------------------
00102 
00103 template< unsigned SubcellDim , unsigned SubcellOrd , unsigned NodeIndex ,
00104           unsigned Dimension , unsigned Number_Vertex , unsigned Number_Node ,
00105           class EdgeList , class EdgeMaps ,
00106           class FaceList , class FaceMaps ,
00107           class PermMaps , class Pol>
00108 struct SubcellTopologyTraits ;
00109 
00110 template< class ListType > struct TypeListHomogeneous ;
00111 
00112 //----------------------------------------------------------------------
00113 // Self-subcell reference
00114 
00115 template<>
00116 struct SubcellTopologyTraits<0,0,0,0,0,0,TypeListEnd,TypeListEnd,
00117                                          TypeListEnd,TypeListEnd,
00118                                          TypeListEnd,IndexList<> >
00119 {
00120   typedef CellTopologyTraits<0,0,0> topology ;
00121   enum { count = 1 };
00122   enum { node = ~0u };
00123   enum { homogeneity = true };
00124 };
00125 
00126 template< unsigned NodeIndex ,
00127           unsigned NV , unsigned NN ,
00128           class EList , class EMaps ,
00129           class FList , class FMaps ,
00130           class PMaps , class Pol>
00131 struct SubcellTopologyTraits<1,0,NodeIndex, 1,NV,NN,EList,EMaps,FList,FMaps,PMaps,Pol>
00132 {
00133   typedef CellTopologyTraits<1,NV,NN,EList,EMaps,FList,FMaps,PMaps,Pol> topology ;
00134   enum { count = 1 };
00135   enum { node = NodeIndex < NN ? NodeIndex : ~0u };
00136   enum { homogeneity = true };
00137 };
00138 
00139 template< unsigned NodeIndex ,
00140           unsigned NV , unsigned NN ,
00141           class EList , class EMaps ,
00142           class FList , class FMaps ,
00143           class PMaps , class Pol>
00144 struct SubcellTopologyTraits<2,0,NodeIndex, 2,NV,NN,EList,EMaps,FList,FMaps,PMaps,Pol>
00145 {
00146   typedef CellTopologyTraits<2,NV,NN,EList,EMaps,FList,FMaps,PMaps,Pol> topology ;
00147   enum { count = 1 };
00148   enum { node = NodeIndex < NN ? NodeIndex : ~0u };
00149   enum { homogeneity = true };
00150 };
00151 
00152 template< unsigned NodeIndex ,
00153           unsigned NV , unsigned NN ,
00154           class EList , class EMaps ,
00155           class FList , class FMaps ,
00156           class PMaps , class Pol>
00157 struct SubcellTopologyTraits<3,0,NodeIndex, 3,NV,NN,EList,EMaps,FList,FMaps,PMaps,Pol>
00158 {
00159   typedef CellTopologyTraits<3,NV,NN,EList,EMaps,FList,FMaps,PMaps,Pol> topology ;
00160   enum { count = 1 };
00161   enum { node = NodeIndex < NN ? NodeIndex : ~0u };
00162   enum { homogeneity = true };
00163 };
00164 
00165 //----------------------------------------------------------------------
00166 // Node-subcell reference:
00167 
00168 template< unsigned SubcellOrd ,
00169           unsigned D , unsigned NV , unsigned NN ,
00170           class EList , class EMaps ,
00171           class FList , class FMaps ,
00172           class PMaps , class Pol>
00173 struct SubcellTopologyTraits<0,SubcellOrd,0, D,NV,NN,EList,EMaps,FList,FMaps,PMaps,Pol>
00174 {
00175   typedef CellTopologyTraits<0,0,0> topology ;
00176   enum { count = NN };
00177   enum { node = SubcellOrd < NN ? SubcellOrd : ~0u };
00178   enum { homogeneity = true };
00179 };
00180 
00181 // Edge-subcell reference:
00182 
00183 template< unsigned SubcellOrd , unsigned NodeIndex ,
00184           unsigned D , unsigned NV , unsigned NN ,
00185           class EList , class EMaps ,
00186           class FList , class FMaps ,
00187           class PMaps , class Pol>
00188 struct SubcellTopologyTraits<1,SubcellOrd,NodeIndex,
00189                              D,NV,NN,EList,EMaps,FList,FMaps,PMaps,Pol>
00190 {
00191 private:
00192   typedef typename TypeListAt<EMaps,SubcellOrd>::type node_map ;
00193 public:
00194 
00195   typedef typename TypeListAt<EList,SubcellOrd>::type topology ;
00196 
00197   enum { count = TypeListLength<EList>::value };
00198 
00199   enum { node = SubcellNodeIndex< topology , node_map , NodeIndex ,
00200                                   SubcellOrd < count >::value };
00201 
00202   enum { homogeneity = TypeListHomogeneous<EList>::value };
00203 };
00204 
00205 // Face-subcell reference:
00206 
00207 template< unsigned SubcellOrd , unsigned NodeIndex ,
00208           unsigned D , unsigned NV , unsigned NN ,
00209           class EList , class EMaps ,
00210           class FList , class FMaps ,
00211           class PMaps , class Pol>
00212 struct SubcellTopologyTraits< 2, SubcellOrd, NodeIndex,
00213                               D,NV,NN,EList,EMaps,FList,FMaps,PMaps,Pol >
00214 {
00215 private:
00216   typedef typename TypeListAt<FMaps,SubcellOrd>::type node_map ;
00217 public:
00218 
00219   typedef typename TypeListAt<FList,SubcellOrd>::type topology ;
00220 
00221   enum { count = TypeListLength<FList>::value };
00222 
00223   enum { node = SubcellNodeIndex< topology , node_map , NodeIndex ,
00224                                   SubcellOrd < count >::value };
00225 
00226   enum { homogeneity = TypeListHomogeneous<FList>::value };
00227 };
00228 
00229 //----------------------------------------------------------------------
00230 // Only partially specialized subcell references are valid.
00231 
00232 template< unsigned SubcellDim , unsigned SubcellOrd , unsigned NodeIndex ,
00233           unsigned Dimension ,
00234           unsigned Number_Vertex , unsigned Number_Node ,
00235           class EdgeList , class EdgeMaps ,
00236           class FaceList , class FaceMaps ,
00237           class PermMaps , class Pol >
00238 struct SubcellTopologyTraits
00239 {
00240   typedef void topology ;
00241   enum { count = 0 };
00242   enum { node = ~0u };
00243   enum { homogeneity = false };
00244 };
00245 
00246 //----------------------------------------------------------------------
00247 
00248 template<>
00249 struct TypeListHomogeneous<TypeListEnd> {
00250   enum { value = true };
00251 };
00252 
00253 template< class T >
00254 struct TypeListHomogeneous< TypeList<T,TypeListEnd> > {
00255   enum { value = true };
00256 };
00257 
00258 template< class T , class Tail >
00259 struct TypeListHomogeneous< TypeList< T, TypeList< T , Tail > > > {
00260   enum { value = TypeListHomogeneous< TypeList<T,Tail> >::value };
00261 };
00262 
00263 template< class ListType >
00264 struct TypeListHomogeneous 
00265 {
00266   enum { value = false };
00267 };
00268 
00269 //----------------------------------------------------------------------
00270 
00271 template< unsigned I , unsigned J > struct AssertEqual ;
00272 
00273 template< unsigned I > struct AssertEqual<I,I> { enum { OK = true }; };
00274 
00275 #endif /* DOXYGEN_COMPILE */
00276 
00277 //----------------------------------------------------------------------
00279 template< unsigned Dimension , unsigned Number_Vertex , unsigned Number_Node ,
00280           class EdgeList , class EdgeMaps ,
00281           class FaceList , class FaceMaps ,
00282           class PermutationMaps ,
00283           class PermutationPolarity >
00284 struct CellTopologyTraits
00285 {
00287   typedef CellTopologyTraits< Dimension, Number_Vertex, Number_Node,
00288                               EdgeList, EdgeMaps, FaceList, FaceMaps,
00289                               PermutationMaps, PermutationPolarity > Traits ;
00290 
00291   enum {
00293     dimension    = Dimension ,
00294 
00296     vertex_count = Number_Vertex ,
00297 
00299     node_count   = Number_Node ,
00300 
00302     edge_count   = TypeListLength<EdgeList>::value ,
00303 
00304 #ifndef DOXYGEN_COMPILE
00305     face_count   = TypeListLength<FaceList>::value ,
00306 #endif
00307 
00309     side_count   = Dimension == 3 ? face_count : (
00310                    Dimension == 2 ? edge_count : 0 ),
00311 
00319     key  = ( dimension    << 28 /*  4 bits, max    7 */ ) |
00320            ( face_count   << 22 /*  6 bits, max   63 */ ) |
00321            ( edge_count   << 16 /*  6 bits, max   63 */ ) |
00322            ( vertex_count << 10 /*  6 bits, max   63 */ ) |
00323            ( node_count         /* 10 bits, max 1023 */ ) };
00324 
00332   template< unsigned Dim, unsigned Ord = 0, unsigned J = 0 >
00333   struct subcell :
00334     public SubcellTopologyTraits< Dim , Ord , J ,
00335                                   dimension , vertex_count , node_count ,
00336                                   EdgeList , EdgeMaps ,
00337                                   FaceList , FaceMaps ,
00338                                   PermutationMaps, PermutationPolarity > {};
00339 
00347   template< unsigned Ord = 0 , unsigned J = 0 >
00348   struct side :
00349     public SubcellTopologyTraits< ( 1 < dimension ? dimension - 1 : 4 ) ,
00350                                   Ord , J ,
00351                                   dimension , vertex_count , node_count ,
00352                                   EdgeList , EdgeMaps ,
00353                                   FaceList , FaceMaps ,
00354                                   TypeListEnd , IndexList<> > {};
00355 
00363   template< unsigned Ord = 0 , unsigned J = 0 >
00364   struct edge :
00365     public SubcellTopologyTraits< ( 1 < dimension ? 1 : 4 ) , Ord , J ,
00366                                   dimension , vertex_count , node_count ,
00367                                   EdgeList , EdgeMaps ,
00368                                   TypeListEnd , TypeListEnd ,
00369                                   TypeListEnd , IndexList<> > {};
00370 
00371   //--------------------------------------------------------------------
00389   template< unsigned Perm , unsigned J = 0 >
00390   struct permutation {
00391   private:
00392     typedef typename TypeListAt< PermutationMaps , Perm >::type node_map ;
00393   public:
00394     enum { node = J < node_count ? IndexListAt< node_map , J >::value : ~0u };
00395     enum { polarity = IndexListAt< PermutationPolarity , Perm >::value };
00396   };
00397 
00398   template< unsigned Perm , unsigned J = 0 >
00399   struct permutation_inverse {
00400   private:
00401     typedef typename TypeListAt< PermutationMaps , Perm >::type forward_map ;
00402     typedef typename IndexListInverse< forward_map >::type node_map ;
00403   public:
00404     enum { node = J < node_count ? IndexListAt< node_map , J >::value : ~0u };
00405     enum { polarity = IndexListAt< PermutationPolarity , Perm >::value };
00406   };
00407 
00408   enum { permutation_count = TypeListLength< PermutationMaps >::value };
00409 
00410   //--------------------------------------------------------------------
00411 
00412 private:
00413 
00414 #ifndef DOXYGEN_COMPILE
00415 
00416   enum { nedge_map = TypeListLength<EdgeMaps>::value ,
00417          nface_map = TypeListLength<FaceMaps>::value ,
00418          polarity_count = IndexListLength< PermutationPolarity >::value };
00419 
00420   enum { OK_edge  = AssertEqual< edge_count , nedge_map >::OK };
00421   enum { OK_face  = AssertEqual< face_count , nface_map >::OK };
00422   enum { OK_dimen = AssertEqual< 0 , (dimension    >>  3) >::OK };
00423   enum { OK_faceN = AssertEqual< 0 , (face_count   >>  6) >::OK };
00424   enum { OK_edgeN = AssertEqual< 0 , (edge_count   >>  6) >::OK };
00425   enum { OK_vertN = AssertEqual< 0 , (vertex_count >>  6) >::OK };
00426   enum { OK_nodeN = AssertEqual< 0 , (node_count   >> 10) >::OK };
00427   enum { OK_permN = AssertEqual< permutation_count, polarity_count >::OK };
00428 
00429 #endif
00430 
00431 };
00432 
00435 } // namespace shards
00436 
00437 #endif // Shards_CellTopologyTraits_hpp
00438 
 All Classes Functions Variables Typedefs Enumerator