|
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_CellTopology_hpp 00047 #define Shards_CellTopology_hpp 00048 00049 #ifdef HAVE_SHARDS_DEBUG 00050 #define SHARDS_REQUIRE( S ) S 00051 #else 00052 #define SHARDS_REQUIRE( S ) /* empty */ 00053 #endif 00054 00055 #include <string> 00056 #include <vector> 00057 #include <Shards_CellTopologyData.h> 00058 #include <Shards_BasicTopologies.hpp> 00059 00060 namespace shards { 00061 00066 /*------------------------------------------------------------------------*/ 00067 00068 class CellTopology ; 00069 class CellTopologyPrivate ; 00070 00072 //std::ostream & operator << ( std::ostream & , const CellTopologyData & ); 00073 00074 00076 std::ostream & operator << ( std::ostream & , const CellTopology & ); 00077 00078 00082 enum ECellType { 00083 ALL_CELLS = 0, 00084 STANDARD_CELL, 00085 NONSTANDARD_CELL 00086 }; 00087 00088 inline std::string ECellTypeToString(ECellType cellType) { 00089 std::string retString; 00090 switch(cellType){ 00091 case ALL_CELLS: retString = "All"; break; 00092 case STANDARD_CELL: retString = "Standard"; break; 00093 case NONSTANDARD_CELL: retString = "Nonstandard"; break; 00094 default: retString = "Invalid Cell"; 00095 } 00096 return retString; 00097 } 00098 00099 00103 enum ETopologyType { 00104 ALL_TOPOLOGIES, 00105 BASE_TOPOLOGY, 00106 EXTENDED_TOPOLOGY 00107 }; 00108 00109 inline std::string ETopologyTypeToString(ETopologyType topologyType) { 00110 std::string retString; 00111 switch(topologyType){ 00112 case ALL_TOPOLOGIES: retString = "All"; break; 00113 case BASE_TOPOLOGY: retString = "Base"; break; 00114 case EXTENDED_TOPOLOGY: retString = "Extended"; break; 00115 default: retString = "Invalid Topology"; 00116 } 00117 return retString; 00118 } 00119 00120 00129 void getTopologies(std::vector<shards::CellTopology>& topologies, 00130 const unsigned cellDim = 4, 00131 const ECellType cellType = ALL_CELLS, 00132 const ETopologyType topologyType = ALL_TOPOLOGIES); 00133 00134 00135 00142 int isPredefinedCell(const CellTopology & cell); 00143 00144 00145 00146 /*------------------------------------------------------------------------*/ 00168 class CellTopology { 00169 private: 00170 00172 void deleteOwned(); 00173 00177 void requireCell() const ; 00178 00179 00184 void requireDimension( const unsigned subcellDim ) const ; 00185 00186 00192 void requireSubcell( const unsigned subcellDim , 00193 const unsigned subcellOrd ) const ; 00194 00195 00202 void requireNodeMap( const unsigned subcellDim , 00203 const unsigned subcellOrd , 00204 const unsigned nodeOrd ) const ; 00205 00206 void requireNodePermutation( const unsigned permutationOrd , 00207 const unsigned nodeOrd ) const ; 00208 00209 const CellTopologyData * m_cell ; 00210 CellTopologyPrivate * m_owned ; 00211 00212 public: 00213 00214 /*------------------------------------------------------------------*/ 00221 unsigned getDimension() const 00222 { 00223 SHARDS_REQUIRE( requireCell() ); 00224 return m_cell->dimension ; 00225 } 00226 00227 00233 unsigned getKey() const 00234 { 00235 SHARDS_REQUIRE( requireCell() ); 00236 return m_cell->key ; 00237 } 00238 00239 00245 unsigned getBaseKey() const 00246 { 00247 SHARDS_REQUIRE( requireCell() ); 00248 return m_cell->base->key ; 00249 } 00250 00251 00252 00258 const char* getName() const 00259 { 00260 SHARDS_REQUIRE( requireCell() ); 00261 return m_cell->name ; 00262 } 00263 00264 00268 const char* getBaseName() const 00269 { 00270 SHARDS_REQUIRE( requireCell() ); 00271 return m_cell->base->name ; 00272 } 00273 00274 00276 unsigned getNodeCount() const 00277 { 00278 SHARDS_REQUIRE( requireCell() ); 00279 return m_cell->node_count ; 00280 } 00281 00282 00284 unsigned getVertexCount() const 00285 { 00286 SHARDS_REQUIRE( requireCell() ); 00287 return m_cell->vertex_count ; 00288 } 00289 00290 00292 unsigned getEdgeCount() const 00293 { 00294 SHARDS_REQUIRE( requireCell() ); 00295 return m_cell->edge_count ; 00296 } 00297 00299 unsigned getFaceCount() const 00300 { 00301 SHARDS_REQUIRE( requireCell() ); 00302 return m_cell->dimension == 3 ? m_cell->side_count : 0 ; 00303 } 00304 00305 00307 unsigned getSideCount() const 00308 { 00309 SHARDS_REQUIRE( requireCell() ); 00310 return m_cell->side_count ; 00311 } 00312 00313 00315 const CellTopologyData * getTopology() const 00316 { return m_cell ; } 00317 00318 00320 const CellTopologyData * getBaseTopology() const 00321 { 00322 SHARDS_REQUIRE( requireCell() ); 00323 return m_cell->base ; 00324 } 00325 00326 00332 const CellTopologyData * getTopology( const unsigned subcell_dim , 00333 const unsigned subcell_ord ) const 00334 { 00335 SHARDS_REQUIRE( requireCell() ); 00336 SHARDS_REQUIRE( requireDimension(subcell_dim) ); 00337 SHARDS_REQUIRE( requireSubcell(subcell_dim,subcell_ord) ); 00338 return m_cell->subcell[subcell_dim][subcell_ord].topology ; 00339 } 00340 00341 00347 const CellTopologyData * getBaseTopology( const unsigned subcell_dim , 00348 const unsigned subcell_ord ) const 00349 { 00350 return getTopology(subcell_dim,subcell_ord)->base ; 00351 } 00352 00353 00358 unsigned getKey( const unsigned subcell_dim , 00359 const unsigned subcell_ord ) const 00360 { 00361 return getTopology(subcell_dim,subcell_ord)->key ; 00362 } 00363 00364 00365 00370 const char * getName(const unsigned subcell_dim, 00371 const unsigned subcell_ord) const 00372 { 00373 return getTopology(subcell_dim,subcell_ord) -> name; 00374 } 00375 00376 00381 unsigned getNodeCount( const unsigned subcell_dim , 00382 const unsigned subcell_ord ) const 00383 { 00384 return getTopology(subcell_dim,subcell_ord)->node_count ; 00385 } 00386 00387 00392 unsigned getVertexCount( const unsigned subcell_dim , 00393 const unsigned subcell_ord ) const 00394 { 00395 return getTopology(subcell_dim,subcell_ord)->vertex_count ; 00396 } 00397 00398 00403 unsigned getEdgeCount( const unsigned subcell_dim , 00404 const unsigned subcell_ord ) const 00405 { 00406 return getTopology(subcell_dim,subcell_ord)->edge_count ; 00407 } 00408 00409 00414 unsigned getSideCount( const unsigned subcell_dim , 00415 const unsigned subcell_ord ) const 00416 { 00417 return getTopology(subcell_dim,subcell_ord)->side_count ; 00418 } 00419 00420 00424 unsigned getSubcellCount( const unsigned subcell_dim ) const 00425 { 00426 SHARDS_REQUIRE( requireCell() ); 00427 SHARDS_REQUIRE( requireDimension(subcell_dim) ); 00428 return m_cell->subcell_count[subcell_dim] ; 00429 } 00430 00431 00436 bool getSubcellHomogeneity( const unsigned subcell_dim ) const 00437 { 00438 SHARDS_REQUIRE( requireCell() ); 00439 SHARDS_REQUIRE( requireDimension(subcell_dim) ); 00440 return 0 != m_cell->subcell_homogeneity[subcell_dim] ; 00441 } 00442 00443 00450 unsigned getNodeMap( const unsigned subcell_dim , 00451 const unsigned subcell_ord , 00452 const unsigned subcell_node_ord ) const 00453 { 00454 SHARDS_REQUIRE( requireCell() ); 00455 SHARDS_REQUIRE( requireDimension(subcell_dim) ); 00456 SHARDS_REQUIRE( requireSubcell(subcell_dim,subcell_ord) ); 00457 SHARDS_REQUIRE( requireNodeMap(subcell_dim,subcell_ord,subcell_node_ord)); 00458 return m_cell->subcell[subcell_dim][subcell_ord].node[subcell_node_ord]; 00459 } 00460 00461 00463 unsigned getNodePermutationCount() const 00464 { 00465 SHARDS_REQUIRE(requireCell()); 00466 return m_cell->permutation_count ; 00467 } 00468 00473 unsigned getNodePermutation( const unsigned permutation_ord , 00474 const unsigned node_ord ) const 00475 { 00476 SHARDS_REQUIRE(requireCell()); 00477 SHARDS_REQUIRE(requireNodePermutation(permutation_ord,node_ord)); 00478 return m_cell->permutation[permutation_ord].node[node_ord]; 00479 } 00480 00485 unsigned getNodePermutationPolarity( const unsigned permutation_ord ) const 00486 { 00487 SHARDS_REQUIRE(requireCell()); 00488 SHARDS_REQUIRE(requireNodePermutation(permutation_ord,0)); 00489 return m_cell->permutation[permutation_ord].polarity; 00490 } 00491 00496 unsigned getNodePermutationInverse( const unsigned permutation_ord , 00497 const unsigned node_ord ) const 00498 { 00499 SHARDS_REQUIRE(requireCell()); 00500 SHARDS_REQUIRE(requireNodePermutation(permutation_ord,node_ord)); 00501 return m_cell->permutation_inverse[permutation_ord].node[node_ord]; 00502 } 00503 00506 /*------------------------------------------------------------------*/ 00520 CellTopology( const CellTopologyData * cell ) 00521 : m_cell( cell ), m_owned( NULL ) 00522 {} 00523 00524 00532 CellTopology( const std::string & name, 00533 const unsigned nodeCount); 00534 00535 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 CellTopologyData * base = NULL ); 00551 00552 00564 CellTopology( const std::string & name, 00565 const unsigned vertex_count, 00566 const unsigned node_count, 00567 const std::vector< const CellTopologyData * > & edges , 00568 const std::vector< unsigned > & edge_node_map , 00569 const std::vector< const CellTopologyData * > & faces , 00570 const std::vector< unsigned > & face_node_map , 00571 const CellTopologyData * base = NULL ); 00572 00573 00575 CellTopology& operator = (const CellTopology& right); 00576 00578 CellTopology( const CellTopology& right ); 00579 00581 CellTopology(); 00582 00584 ~CellTopology(); 00585 00588 }; // class CellTopology 00589 00590 /*------------------------------------------------------------------------*/ 00591 /* \brief Find the permutation from the expected nodes to the actual nodes, 00592 * 00593 * Find permutation 'p' such that: 00594 * actual_node[j] == expected_node[ top.permutation[p].node[j] ] 00595 * for all vertices. 00596 */ 00597 template< typename id_type > 00598 int findPermutation( const CellTopologyData & top , 00599 const id_type * const expected_node , 00600 const id_type * const actual_node ) 00601 { 00602 const int nv = top.vertex_count ; 00603 const int np = top.permutation_count ; 00604 int p = 0 ; 00605 for ( ; p < np ; ++p ) { 00606 const unsigned * const perm_node = top.permutation[p].node ; 00607 int j = 0 ; 00608 for ( ; j < nv && actual_node[j] == expected_node[ perm_node[j] ] ; ++j ); 00609 if ( nv == j ) break ; 00610 } 00611 if ( np == p ) p = -1 ; 00612 return p ; 00613 } 00614 00615 template< typename id_type > 00616 int findPermutation( const CellTopology & top , 00617 const id_type * const expected_node , 00618 const id_type * const actual_node ) 00619 { 00620 return findPermutation( * top.getTopology() , expected_node , actual_node ); 00621 } 00622 00623 /*------------------------------------------------------------------------*/ 00633 void badCellTopologyKey( const unsigned dimension , 00634 const unsigned face_count , 00635 const unsigned edge_count , 00636 const unsigned vertex_count , 00637 const unsigned node_count ); 00638 00639 00648 inline 00649 unsigned cellTopologyKey( const unsigned dimension , 00650 const unsigned face_count , 00651 const unsigned edge_count , 00652 const unsigned vertex_count , 00653 const unsigned node_count ) 00654 { 00655 const bool bad = ( dimension >> 3 ) || 00656 ( face_count >> 6 ) || 00657 ( edge_count >> 6 ) || 00658 ( vertex_count >> 6 ) || 00659 ( node_count >> 10 ); 00660 00661 if ( bad ) { 00662 badCellTopologyKey( dimension , 00663 face_count , 00664 edge_count , 00665 vertex_count , 00666 node_count ); 00667 } 00668 00669 const unsigned key = ( dimension << 28 ) | 00670 ( face_count << 22 ) | 00671 ( edge_count << 16 ) | 00672 ( vertex_count << 10 ) | 00673 ( node_count ) ; 00674 00675 return key ; 00676 } 00677 00678 00679 00682 } // namespace shards 00683 00684 #undef SHARDS_REQUIRE 00685 00686 #endif // Shards_CellTopology_hpp 00687