Shards_CellTopologyTraits.hpp

00001 /*------------------------------------------------------------------------*/
00002 /*                  shards : Shared Discretization Tools                  */
00003 /*                Copyright (2008) Sandia Corporation                     */
00004 /*                                                                        */
00005 /*  Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive   */
00006 /*  license for use of this work by or on behalf of the U.S. Government.  */
00007 /*                                                                        */
00008 /*  This library is free software; you can redistribute it and/or modify  */
00009 /*  it under the terms of the GNU Lesser General Public License as        */
00010 /*  published by the Free Software Foundation; either version 2.1 of the  */
00011 /*  License, or (at your option) any later version.                       */
00012 /*                                                                        */
00013 /*  This library is distributed in the hope that it will be useful,       */
00014 /*  but WITHOUT ANY WARRANTY; without even the implied warranty of        */
00015 /*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     */
00016 /*  Lesser General Public License for more details.                       */
00017 /*                                                                        */
00018 /*  You should have received a copy of the GNU Lesser General Public      */
00019 /*  License along with this library; if not, write to the Free Software   */
00020 /*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307   */
00021 /*  USA                                                                   */
00022 /*------------------------------------------------------------------------*/
00023 
00024 #ifndef Shards_CellTopologyTraits_hpp
00025 #define Shards_CellTopologyTraits_hpp
00026 
00027 #include <Shards_TypeList.hpp>
00028 #include <Shards_IndexList.hpp>
00029 #include <Shards_CellTopologyData.h>
00030 
00031 namespace shards {
00032 
00040 template< class Traits >
00041 const CellTopologyData * getCellTopologyData();
00042 
00043 template< unsigned Dimension ,
00044           unsigned Number_Vertex ,
00045           unsigned Number_Node ,
00046           class    EdgeList = TypeListEnd ,
00047           class    EdgeMaps = TypeListEnd ,
00048           class    FaceList = TypeListEnd ,
00049           class    FaceMaps = TypeListEnd ,
00050           class    PermutationMaps = TypeListEnd ,
00051           class    PermutationPolarity = IndexList<> >
00052 struct CellTopologyTraits ;
00053 
00054 struct Node ;
00055 
00056 //----------------------------------------------------------------------
00057 //----------------------------------------------------------------------
00058 // Implementation details for a much of this file ...
00059 
00060 #ifndef DOXYGEN_COMPILE
00061 
00062 template< class CellTop , class CellMap , unsigned Index , bool Good >
00063 struct SubcellNodeIndex ;
00064 
00065 template< class CellTop , class CellMap , unsigned Index >
00066 struct SubcellNodeIndex< CellTop , CellMap , Index , false >
00067 { enum { value = ~0u }; };
00068 
00069 template< class CellTop , class CellMap , unsigned Index >
00070 struct SubcellNodeIndex< CellTop , CellMap , Index , true >
00071 {
00072   enum { value = Index < CellTop::template subcell<0>::count
00073                ? IndexListAt< CellMap , Index >::value : ~0u };
00074 };
00075 
00076 //----------------------------------------------------------------------
00077 
00078 template< unsigned SubcellDim , unsigned SubcellOrd , unsigned NodeIndex ,
00079           unsigned Dimension , unsigned Number_Vertex , unsigned Number_Node ,
00080           class EdgeList , class EdgeMaps ,
00081           class FaceList , class FaceMaps ,
00082           class PermMaps , class Pol>
00083 struct SubcellTopologyTraits ;
00084 
00085 template< class ListType > struct TypeListHomogeneous ;
00086 
00087 //----------------------------------------------------------------------
00088 // Self-subcell reference
00089 
00090 template<>
00091 struct SubcellTopologyTraits<0,0,0,0,0,0,TypeListEnd,TypeListEnd,
00092                                          TypeListEnd,TypeListEnd,
00093                                          TypeListEnd,IndexList<> >
00094 {
00095   typedef CellTopologyTraits<0,0,0> topology ;
00096   enum { count = 1 };
00097   enum { node = ~0u };
00098   enum { homogeneity = true };
00099 };
00100 
00101 template< unsigned NodeIndex ,
00102           unsigned NV , unsigned NN ,
00103           class EList , class EMaps ,
00104           class FList , class FMaps ,
00105           class PMaps , class Pol>
00106 struct SubcellTopologyTraits<1,0,NodeIndex, 1,NV,NN,EList,EMaps,FList,FMaps,PMaps,Pol>
00107 {
00108   typedef CellTopologyTraits<1,NV,NN,EList,EMaps,FList,FMaps,PMaps,Pol> topology ;
00109   enum { count = 1 };
00110   enum { node = NodeIndex < NN ? NodeIndex : ~0u };
00111   enum { homogeneity = true };
00112 };
00113 
00114 template< unsigned NodeIndex ,
00115           unsigned NV , unsigned NN ,
00116           class EList , class EMaps ,
00117           class FList , class FMaps ,
00118           class PMaps , class Pol>
00119 struct SubcellTopologyTraits<2,0,NodeIndex, 2,NV,NN,EList,EMaps,FList,FMaps,PMaps,Pol>
00120 {
00121   typedef CellTopologyTraits<2,NV,NN,EList,EMaps,FList,FMaps,PMaps,Pol> topology ;
00122   enum { count = 1 };
00123   enum { node = NodeIndex < NN ? NodeIndex : ~0u };
00124   enum { homogeneity = true };
00125 };
00126 
00127 template< unsigned NodeIndex ,
00128           unsigned NV , unsigned NN ,
00129           class EList , class EMaps ,
00130           class FList , class FMaps ,
00131           class PMaps , class Pol>
00132 struct SubcellTopologyTraits<3,0,NodeIndex, 3,NV,NN,EList,EMaps,FList,FMaps,PMaps,Pol>
00133 {
00134   typedef CellTopologyTraits<3,NV,NN,EList,EMaps,FList,FMaps,PMaps,Pol> topology ;
00135   enum { count = 1 };
00136   enum { node = NodeIndex < NN ? NodeIndex : ~0u };
00137   enum { homogeneity = true };
00138 };
00139 
00140 //----------------------------------------------------------------------
00141 // Node-subcell reference:
00142 
00143 template< unsigned SubcellOrd ,
00144           unsigned D , unsigned NV , unsigned NN ,
00145           class EList , class EMaps ,
00146           class FList , class FMaps ,
00147           class PMaps , class Pol>
00148 struct SubcellTopologyTraits<0,SubcellOrd,0, D,NV,NN,EList,EMaps,FList,FMaps,PMaps,Pol>
00149 {
00150   typedef CellTopologyTraits<0,0,0> topology ;
00151   enum { count = NN };
00152   enum { node = SubcellOrd < NN ? SubcellOrd : ~0u };
00153   enum { homogeneity = true };
00154 };
00155 
00156 // Edge-subcell reference:
00157 
00158 template< unsigned SubcellOrd , unsigned NodeIndex ,
00159           unsigned D , unsigned NV , unsigned NN ,
00160           class EList , class EMaps ,
00161           class FList , class FMaps ,
00162           class PMaps , class Pol>
00163 struct SubcellTopologyTraits<1,SubcellOrd,NodeIndex,
00164                              D,NV,NN,EList,EMaps,FList,FMaps,PMaps,Pol>
00165 {
00166 private:
00167   typedef typename TypeListAt<EMaps,SubcellOrd>::type node_map ;
00168 public:
00169 
00170   typedef typename TypeListAt<EList,SubcellOrd>::type topology ;
00171 
00172   enum { count = TypeListLength<EList>::value };
00173 
00174   enum { node = SubcellNodeIndex< topology , node_map , NodeIndex ,
00175                                   SubcellOrd < count >::value };
00176 
00177   enum { homogeneity = TypeListHomogeneous<EList>::value };
00178 };
00179 
00180 // Face-subcell reference:
00181 
00182 template< unsigned SubcellOrd , unsigned NodeIndex ,
00183           unsigned D , unsigned NV , unsigned NN ,
00184           class EList , class EMaps ,
00185           class FList , class FMaps ,
00186           class PMaps , class Pol>
00187 struct SubcellTopologyTraits< 2, SubcellOrd, NodeIndex,
00188                               D,NV,NN,EList,EMaps,FList,FMaps,PMaps,Pol >
00189 {
00190 private:
00191   typedef typename TypeListAt<FMaps,SubcellOrd>::type node_map ;
00192 public:
00193 
00194   typedef typename TypeListAt<FList,SubcellOrd>::type topology ;
00195 
00196   enum { count = TypeListLength<FList>::value };
00197 
00198   enum { node = SubcellNodeIndex< topology , node_map , NodeIndex ,
00199                                   SubcellOrd < count >::value };
00200 
00201   enum { homogeneity = TypeListHomogeneous<FList>::value };
00202 };
00203 
00204 //----------------------------------------------------------------------
00205 // Only partially specialized subcell references are valid.
00206 
00207 template< unsigned SubcellDim , unsigned SubcellOrd , unsigned NodeIndex ,
00208           unsigned Dimension ,
00209           unsigned Number_Vertex , unsigned Number_Node ,
00210           class EdgeList , class EdgeMaps ,
00211           class FaceList , class FaceMaps ,
00212           class PermMaps , class Pol >
00213 struct SubcellTopologyTraits
00214 {
00215   typedef void topology ;
00216   enum { count = 0 };
00217   enum { node = ~0u };
00218   enum { homogeneity = false };
00219 };
00220 
00221 //----------------------------------------------------------------------
00222 
00223 template<>
00224 struct TypeListHomogeneous<TypeListEnd> {
00225   enum { value = true };
00226 };
00227 
00228 template< class T >
00229 struct TypeListHomogeneous< TypeList<T,TypeListEnd> > {
00230   enum { value = true };
00231 };
00232 
00233 template< class T , class Tail >
00234 struct TypeListHomogeneous< TypeList< T, TypeList< T , Tail > > > {
00235   enum { value = TypeListHomogeneous< TypeList<T,Tail> >::value };
00236 };
00237 
00238 template< class ListType >
00239 struct TypeListHomogeneous 
00240 {
00241   enum { value = false };
00242 };
00243 
00244 //----------------------------------------------------------------------
00245 
00246 template< unsigned I , unsigned J > struct AssertEqual ;
00247 
00248 template< unsigned I > struct AssertEqual<I,I> { enum { OK = true }; };
00249 
00250 #endif /* DOXYGEN_COMPILE */
00251 
00252 //----------------------------------------------------------------------
00254 template< unsigned Dimension , unsigned Number_Vertex , unsigned Number_Node ,
00255           class EdgeList , class EdgeMaps ,
00256           class FaceList , class FaceMaps ,
00257           class PermutationMaps ,
00258           class PermutationPolarity >
00259 struct CellTopologyTraits
00260 {
00262   typedef CellTopologyTraits< Dimension, Number_Vertex, Number_Node,
00263                               EdgeList, EdgeMaps, FaceList, FaceMaps,
00264                               PermutationMaps, PermutationPolarity > Traits ;
00265 
00266   enum {
00268     dimension    = Dimension ,
00269 
00271     vertex_count = Number_Vertex ,
00272 
00274     node_count   = Number_Node ,
00275 
00277     edge_count   = TypeListLength<EdgeList>::value ,
00278 
00279 #ifndef DOXYGEN_COMPILE
00280     face_count   = TypeListLength<FaceList>::value ,
00281 #endif
00282 
00284     side_count   = Dimension == 3 ? face_count : (
00285                    Dimension == 2 ? edge_count : 0 ),
00286 
00294     key  = ( dimension    << 28 /*  4 bits, max    7 */ ) |
00295            ( face_count   << 22 /*  6 bits, max   63 */ ) |
00296            ( edge_count   << 16 /*  6 bits, max   63 */ ) |
00297            ( vertex_count << 10 /*  6 bits, max   63 */ ) |
00298            ( node_count         /* 10 bits, max 1023 */ ) };
00299 
00307   template< unsigned Dim, unsigned Ord = 0, unsigned J = 0 >
00308   struct subcell :
00309     public SubcellTopologyTraits< Dim , Ord , J ,
00310                                   dimension , vertex_count , node_count ,
00311                                   EdgeList , EdgeMaps ,
00312                                   FaceList , FaceMaps ,
00313                                   PermutationMaps, PermutationPolarity > {};
00314 
00322   template< unsigned Ord = 0 , unsigned J = 0 >
00323   struct side :
00324     public SubcellTopologyTraits< ( 1 < dimension ? dimension - 1 : 4 ) ,
00325                                   Ord , J ,
00326                                   dimension , vertex_count , node_count ,
00327                                   EdgeList , EdgeMaps ,
00328                                   FaceList , FaceMaps ,
00329                                   TypeListEnd , IndexList<> > {};
00330 
00338   template< unsigned Ord = 0 , unsigned J = 0 >
00339   struct edge :
00340     public SubcellTopologyTraits< ( 1 < dimension ? 1 : 4 ) , Ord , J ,
00341                                   dimension , vertex_count , node_count ,
00342                                   EdgeList , EdgeMaps ,
00343                                   TypeListEnd , TypeListEnd ,
00344                                   TypeListEnd , IndexList<> > {};
00345 
00346   //--------------------------------------------------------------------
00364   template< unsigned Perm , unsigned J = 0 >
00365   struct permutation {
00366   private:
00367     typedef typename TypeListAt< PermutationMaps , Perm >::type node_map ;
00368   public:
00369     enum { node = J < node_count ? IndexListAt< node_map , J >::value : ~0u };
00370     enum { polarity = IndexListAt< PermutationPolarity , Perm >::value };
00371   };
00372 
00373   template< unsigned Perm , unsigned J = 0 >
00374   struct permutation_inverse {
00375   private:
00376     typedef typename TypeListAt< PermutationMaps , Perm >::type forward_map ;
00377     typedef typename IndexListInverse< forward_map >::type node_map ;
00378   public:
00379     enum { node = J < node_count ? IndexListAt< node_map , J >::value : ~0u };
00380     enum { polarity = IndexListAt< PermutationPolarity , Perm >::value };
00381   };
00382 
00383   enum { permutation_count = TypeListLength< PermutationMaps >::value };
00384 
00385   //--------------------------------------------------------------------
00386 
00387 private:
00388 
00389 #ifndef DOXYGEN_COMPILE
00390 
00391   enum { nedge_map = TypeListLength<EdgeMaps>::value ,
00392          nface_map = TypeListLength<FaceMaps>::value ,
00393          polarity_count = IndexListLength< PermutationPolarity >::value };
00394 
00395   enum { OK_edge  = AssertEqual< edge_count , nedge_map >::OK };
00396   enum { OK_face  = AssertEqual< face_count , nface_map >::OK };
00397   enum { OK_dimen = AssertEqual< 0 , (dimension    >>  3) >::OK };
00398   enum { OK_faceN = AssertEqual< 0 , (face_count   >>  6) >::OK };
00399   enum { OK_edgeN = AssertEqual< 0 , (edge_count   >>  6) >::OK };
00400   enum { OK_vertN = AssertEqual< 0 , (vertex_count >>  6) >::OK };
00401   enum { OK_nodeN = AssertEqual< 0 , (node_count   >> 10) >::OK };
00402   enum { OK_permN = AssertEqual< permutation_count, polarity_count >::OK };
00403 
00404 #endif
00405 
00406 };
00407 
00410 } // namespace shards
00411 
00412 #endif // Shards_CellTopologyTraits_hpp
00413 

Generated on Tue Oct 20 14:14:35 2009 for shards by  doxygen 1.6.1