|
shards Version of the Day
|
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