Shards_CellTopology.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 /* Questions? Contact Pavel Bochev      (pbboche@sandia.gov)              */
00023 /*                    H. Carter Edwards (hcedwar@sandia.gov)              */
00024 /*                    Denis Ridzal      (dridzal@sandia.gov).             */
00025 /*------------------------------------------------------------------------*/
00026 
00027 #ifndef Shards_CellTopology_hpp
00028 #define Shards_CellTopology_hpp
00029 
00030 #ifdef HAVE_SHARDS_DEBUG
00031 #define SHARDS_REQUIRE( S )  S
00032 #else
00033 #define SHARDS_REQUIRE( S ) /* empty */
00034 #endif
00035 
00036 #include <string>
00037 #include <vector>
00038 #include <Shards_CellTopologyData.h>
00039 #include <Shards_BasicTopologies.hpp>
00040 
00041 namespace shards {
00042 
00047 /*------------------------------------------------------------------------*/
00048 
00049 class CellTopology ;
00050 class CellTopologyPrivate ;
00051 
00053 //std::ostream & operator << ( std::ostream & , const CellTopologyData & );
00054 
00055 
00057 std::ostream & operator << ( std::ostream & , const CellTopology & );
00058 
00059 
00063 enum ECellType {
00064   ALL_CELLS = 0,
00065   STANDARD_CELL,
00066   NONSTANDARD_CELL
00067 };
00068 
00069 inline std::string ECellTypeToString(ECellType cellType) {
00070   std::string retString;
00071   switch(cellType){
00072     case ALL_CELLS:         retString = "All";           break;
00073     case STANDARD_CELL:     retString = "Standard";      break;
00074     case NONSTANDARD_CELL:  retString = "Nonstandard";   break;
00075     default:                retString = "Invalid Cell";
00076   }
00077   return retString;
00078 }
00079 
00080 
00084 enum ETopologyType {
00085   ALL_TOPOLOGIES,
00086   BASE_TOPOLOGY,
00087   EXTENDED_TOPOLOGY
00088 };
00089 
00090 inline std::string ETopologyTypeToString(ETopologyType topologyType) {
00091   std::string retString;
00092   switch(topologyType){
00093     case ALL_TOPOLOGIES:      retString = "All";            break;
00094     case BASE_TOPOLOGY:       retString = "Base";           break;
00095     case EXTENDED_TOPOLOGY:   retString = "Extended";       break;
00096     default:                  retString = "Invalid Topology";
00097   }
00098   return retString;
00099 }
00100 
00101 
00110 void getTopologies(std::vector<shards::CellTopology>& topologies,
00111                    const unsigned       cellDim   = 4,
00112                    const ECellType      cellType      = ALL_CELLS,
00113                    const ETopologyType  topologyType  = ALL_TOPOLOGIES);
00114 
00115 
00116 
00123 int isPredefinedCell(const CellTopology &  cell);
00124 
00125 
00126 
00127 /*------------------------------------------------------------------------*/
00149 class CellTopology {
00150 private:
00151   
00153   void deleteOwned();
00154 
00158   void requireCell() const ;
00159   
00160   
00165   void requireDimension( const unsigned subcellDim ) const ;
00166   
00167   
00173   void requireSubcell( const unsigned subcellDim ,
00174                        const unsigned subcellOrd ) const ;
00175   
00176   
00183   void requireNodeMap( const unsigned subcellDim ,
00184                        const unsigned subcellOrd ,
00185                        const unsigned nodeOrd ) const ;
00186 
00187   void requireNodePermutation( const unsigned permutationOrd ,
00188                                const unsigned nodeOrd ) const ;
00189   
00190   const CellTopologyData    * m_cell ;
00191         CellTopologyPrivate * m_owned ;
00192 
00193 public:
00194 
00195   /*------------------------------------------------------------------*/
00202   unsigned getDimension() const
00203     {
00204       SHARDS_REQUIRE( requireCell() );
00205       return m_cell->dimension ;
00206     }
00207   
00208         
00214   unsigned getKey() const
00215     {
00216       SHARDS_REQUIRE( requireCell() );
00217       return m_cell->key ;
00218     }
00219 
00220         
00226   unsigned getBaseKey() const
00227     {
00228       SHARDS_REQUIRE( requireCell() );
00229       return m_cell->base->key ;
00230     }
00231         
00232         
00233         
00239   const char* getName() const
00240     {
00241         SHARDS_REQUIRE( requireCell() );
00242         return m_cell->name ;
00243     }
00244 
00245         
00249   const char* getBaseName() const
00250     {
00251       SHARDS_REQUIRE( requireCell() );
00252       return m_cell->base->name ;
00253     }
00254         
00255         
00257   unsigned getNodeCount() const
00258     {
00259       SHARDS_REQUIRE( requireCell() );
00260       return m_cell->node_count ;
00261     }
00262   
00263         
00265   unsigned getVertexCount() const
00266     {
00267       SHARDS_REQUIRE( requireCell() );
00268       return m_cell->vertex_count ;
00269     }
00270   
00271         
00273   unsigned getEdgeCount() const
00274     {
00275       SHARDS_REQUIRE( requireCell() );
00276       return m_cell->edge_count ;
00277     }
00278   
00280   unsigned getFaceCount() const
00281     {
00282       SHARDS_REQUIRE( requireCell() );
00283       return m_cell->dimension == 3 ? m_cell->side_count : 0 ;
00284     }
00285   
00286         
00288   unsigned getSideCount() const
00289     {
00290       SHARDS_REQUIRE( requireCell() );
00291       return m_cell->side_count ;
00292     }
00293   
00294         
00296   const CellTopologyData * getTopology() const
00297     { return m_cell ; }
00298 
00299         
00301   const CellTopologyData * getBaseTopology() const
00302     {
00303       SHARDS_REQUIRE( requireCell() );
00304       return m_cell->base ;
00305     }
00306 
00307         
00313   const CellTopologyData * getTopology( const unsigned subcell_dim ,
00314                                         const unsigned subcell_ord ) const
00315     {
00316       SHARDS_REQUIRE( requireCell() );
00317       SHARDS_REQUIRE( requireDimension(subcell_dim) );
00318       SHARDS_REQUIRE( requireSubcell(subcell_dim,subcell_ord) );
00319       return m_cell->subcell[subcell_dim][subcell_ord].topology ;
00320     }
00321 
00322         
00328   const CellTopologyData * getBaseTopology( const unsigned subcell_dim ,
00329                                             const unsigned subcell_ord ) const
00330     {
00331       return getTopology(subcell_dim,subcell_ord)->base ;
00332     }
00333 
00334         
00339   unsigned getKey( const unsigned subcell_dim ,
00340                    const unsigned subcell_ord ) const
00341     {
00342       return getTopology(subcell_dim,subcell_ord)->key ;
00343     }
00344 
00345 
00346         
00351   const char * getName(const unsigned subcell_dim,   
00352                        const unsigned subcell_ord) const
00353     {
00354       return getTopology(subcell_dim,subcell_ord) -> name;
00355     }
00356         
00357         
00362   unsigned getNodeCount( const unsigned subcell_dim ,
00363                          const unsigned subcell_ord ) const
00364     {
00365       return getTopology(subcell_dim,subcell_ord)->node_count ;
00366     }
00367 
00368         
00373   unsigned getVertexCount( const unsigned subcell_dim ,
00374                            const unsigned subcell_ord ) const
00375     {
00376       return getTopology(subcell_dim,subcell_ord)->vertex_count ;
00377     }
00378 
00379         
00384   unsigned getEdgeCount( const unsigned subcell_dim ,
00385                          const unsigned subcell_ord ) const
00386     {
00387       return getTopology(subcell_dim,subcell_ord)->edge_count ;
00388     }
00389   
00390         
00395   unsigned getSideCount( const unsigned subcell_dim ,
00396                          const unsigned subcell_ord ) const
00397     {
00398       return getTopology(subcell_dim,subcell_ord)->side_count ;
00399     }
00400 
00401         
00405   unsigned getSubcellCount( const unsigned subcell_dim ) const
00406     {
00407       SHARDS_REQUIRE( requireCell() );
00408       SHARDS_REQUIRE( requireDimension(subcell_dim) );
00409       return m_cell->subcell_count[subcell_dim] ;
00410     }
00411   
00412         
00417   bool getSubcellHomogeneity( const unsigned subcell_dim ) const
00418     {
00419       SHARDS_REQUIRE( requireCell() );
00420       SHARDS_REQUIRE( requireDimension(subcell_dim) );
00421       return m_cell->subcell_homogeneity[subcell_dim] ;
00422     }
00423   
00424         
00431   unsigned getNodeMap( const unsigned  subcell_dim ,
00432                        const unsigned  subcell_ord ,
00433                        const unsigned  subcell_node_ord ) const
00434     {
00435       SHARDS_REQUIRE( requireCell() );
00436       SHARDS_REQUIRE( requireDimension(subcell_dim) );
00437       SHARDS_REQUIRE( requireSubcell(subcell_dim,subcell_ord) );
00438       SHARDS_REQUIRE( requireNodeMap(subcell_dim,subcell_ord,subcell_node_ord));
00439       return m_cell->subcell[subcell_dim][subcell_ord].node[subcell_node_ord];
00440     }
00441 
00442 
00444   unsigned getNodePermutationCount() const
00445     {
00446       SHARDS_REQUIRE(requireCell());
00447       return m_cell->permutation_count ;
00448     }
00449 
00454   unsigned getNodePermutation( const unsigned permutation_ord ,
00455                                const unsigned node_ord ) const
00456     {
00457       SHARDS_REQUIRE(requireCell());
00458       SHARDS_REQUIRE(requireNodePermutation(permutation_ord,node_ord));
00459       return m_cell->permutation[permutation_ord].node[node_ord];
00460     }
00461   
00466   unsigned getNodePermutationPolarity( const unsigned permutation_ord ) const
00467     {
00468       SHARDS_REQUIRE(requireCell());
00469       SHARDS_REQUIRE(requireNodePermutation(permutation_ord,0));
00470       return m_cell->permutation[permutation_ord].polarity;
00471     }
00472   
00477   unsigned getNodePermutationInverse( const unsigned permutation_ord ,
00478                                       const unsigned node_ord ) const
00479     {
00480       SHARDS_REQUIRE(requireCell());
00481       SHARDS_REQUIRE(requireNodePermutation(permutation_ord,node_ord));
00482       return m_cell->permutation_inverse[permutation_ord].node[node_ord];
00483     }
00484   
00487   /*------------------------------------------------------------------*/
00501   CellTopology( const CellTopologyData * cell )
00502     : m_cell( cell ), m_owned( NULL )
00503     {}
00504   
00505         
00513   CellTopology( const std::string & name,
00514                 const unsigned      nodeCount);
00515   
00516         
00526   CellTopology( const std::string                             & name,
00527                 const unsigned                                  vertex_count,
00528                 const unsigned                                  node_count,
00529                 const std::vector< const CellTopologyData * > & edges ,
00530                 const std::vector< unsigned >                 & edge_node_map ,
00531                 const CellTopologyData                        * base = NULL );
00532 
00533   
00545   CellTopology( const std::string                             & name,
00546                 const unsigned                                  vertex_count,
00547                 const unsigned                                  node_count,
00548                 const std::vector< const CellTopologyData * > & edges ,
00549                 const std::vector< unsigned >                 & edge_node_map ,
00550                 const std::vector< const CellTopologyData * > & faces ,
00551                 const std::vector< unsigned >                 & face_node_map ,
00552                 const CellTopologyData                        * base = NULL );
00553   
00554   
00556   CellTopology& operator = (const CellTopology& right);
00557 
00559   CellTopology( const CellTopology& right );
00560 
00562   CellTopology();
00563 
00565   ~CellTopology();
00566   
00569 }; // class CellTopology
00570 
00571 /*------------------------------------------------------------------------*/
00572 /* \brief  Find the permutation from the expected nodes to the actual nodes,
00573  *
00574  *  Find permutation 'p' such that:
00575  *    actual_node[j] == expected_node[ top.permutation[p].node[j] ]
00576  *  for all vertices.
00577  */
00578 template< typename id_type >
00579 int findPermutation( const CellTopologyData & top ,
00580                      const id_type * const expected_node ,
00581                      const id_type * const actual_node )
00582 {
00583   const int nv = top.vertex_count ;
00584   const int np = top.permutation_count ;
00585   int p = 0 ;
00586   for ( ; p < np ; ++p ) {
00587     const unsigned * const perm_node = top.permutation[p].node ;
00588     int j = 0 ;
00589     for ( ; j < nv && actual_node[j] == expected_node[ perm_node[j] ] ; ++j );
00590     if ( nv == j ) break ;
00591   }
00592   if ( np == p ) p = -1 ;
00593   return p ;
00594 }
00595 
00596 template< typename id_type >
00597 int findPermutation( const CellTopology & top ,
00598                      const id_type * const expected_node ,
00599                      const id_type * const actual_node )
00600 {
00601   return findPermutation( * top.getTopology() , expected_node , actual_node );
00602 }
00603 
00604 /*------------------------------------------------------------------------*/
00614 void badCellTopologyKey( const unsigned dimension ,
00615                          const unsigned face_count ,
00616                          const unsigned edge_count ,
00617                          const unsigned vertex_count ,
00618                          const unsigned node_count );
00619   
00620 
00629 inline
00630 unsigned cellTopologyKey( const unsigned dimension ,
00631                           const unsigned face_count ,
00632                           const unsigned edge_count ,
00633                           const unsigned vertex_count ,
00634                           const unsigned node_count )
00635 {
00636   const bool bad = ( dimension    >> 3 ) ||
00637                    ( face_count   >> 6 ) ||
00638                    ( edge_count   >> 6 ) ||
00639                    ( vertex_count >> 6 ) ||
00640                    ( node_count   >> 10 );
00641 
00642   if ( bad ) {
00643     badCellTopologyKey( dimension , 
00644                         face_count ,
00645                         edge_count , 
00646                         vertex_count , 
00647                         node_count );
00648   }
00649 
00650   const unsigned key = ( dimension    << 28  ) |
00651                        ( face_count   << 22  ) |
00652                        ( edge_count   << 16  ) |
00653                        ( vertex_count << 10  ) |
00654                        ( node_count          ) ;
00655 
00656   return key ;
00657 }
00658 
00659 
00660 
00663 } // namespace shards
00664 
00665 #undef SHARDS_REQUIRE
00666 
00667 #endif // Shards_CellTopology_hpp
00668 

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