|
shards
Version of the Day
|
00001 /* 00002 //@HEADER 00003 // ************************************************************************ 00004 // 00005 // Shards : Shared Discretization Tools 00006 // Copyright 2008, 2011 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 00071 //std::ostream & operator << ( std::ostream & , const CellTopologyData & ); 00072 00073 00075 std::ostream & operator << ( std::ostream & , const CellTopology & ); 00076 00077 00081 enum ECellType { 00082 ALL_CELLS = 0, 00083 STANDARD_CELL, 00084 NONSTANDARD_CELL 00085 }; 00086 00087 inline std::string ECellTypeToString(ECellType cellType) { 00088 std::string retString; 00089 switch(cellType){ 00090 case ALL_CELLS: retString = "All"; break; 00091 case STANDARD_CELL: retString = "Standard"; break; 00092 case NONSTANDARD_CELL: retString = "Nonstandard"; break; 00093 default: retString = "Invalid Cell"; 00094 } 00095 return retString; 00096 } 00097 00098 00102 enum ETopologyType { 00103 ALL_TOPOLOGIES, 00104 BASE_TOPOLOGY, 00105 EXTENDED_TOPOLOGY 00106 }; 00107 00108 inline std::string ETopologyTypeToString(ETopologyType topologyType) { 00109 std::string retString; 00110 switch(topologyType){ 00111 case ALL_TOPOLOGIES: retString = "All"; break; 00112 case BASE_TOPOLOGY: retString = "Base"; break; 00113 case EXTENDED_TOPOLOGY: retString = "Extended"; break; 00114 default: retString = "Invalid Topology"; 00115 } 00116 return retString; 00117 } 00118 00119 00128 void getTopologies(std::vector<shards::CellTopology>& topologies, 00129 const unsigned cellDim = 4, 00130 const ECellType cellType = ALL_CELLS, 00131 const ETopologyType topologyType = ALL_TOPOLOGIES); 00132 00133 00134 00141 int isPredefinedCell(const CellTopology & cell); 00142 00143 00144 00145 /*------------------------------------------------------------------------*/ 00167 class CellTopology { 00168 private: 00169 00173 void requireCell() const ; 00174 00175 00180 void requireDimension( const unsigned subcellDim ) const ; 00181 00182 00188 void requireSubcell( const unsigned subcellDim , 00189 const unsigned subcellOrd ) const ; 00190 00191 00198 void requireNodeMap( const unsigned subcellDim , 00199 const unsigned subcellOrd , 00200 const unsigned nodeOrd ) const ; 00201 00202 void requireNodePermutation( const unsigned permutationOrd , 00203 const unsigned nodeOrd ) const ; 00204 00205 const CellTopologyData * m_cell ; 00206 00207 public: 00208 00209 /*------------------------------------------------------------------*/ 00216 unsigned getDimension() const 00217 { 00218 SHARDS_REQUIRE( requireCell() ); 00219 return m_cell->dimension ; 00220 } 00221 00222 00228 unsigned getKey() const 00229 { 00230 SHARDS_REQUIRE( requireCell() ); 00231 return m_cell->key ; 00232 } 00233 00234 00240 unsigned getBaseKey() const 00241 { 00242 SHARDS_REQUIRE( requireCell() ); 00243 return m_cell->base->key ; 00244 } 00245 00246 00247 00253 const char* getName() const 00254 { 00255 SHARDS_REQUIRE( requireCell() ); 00256 return m_cell->name ; 00257 } 00258 00259 00263 const char* getBaseName() const 00264 { 00265 SHARDS_REQUIRE( requireCell() ); 00266 return m_cell->base->name ; 00267 } 00268 00269 00271 unsigned getNodeCount() const 00272 { 00273 SHARDS_REQUIRE( requireCell() ); 00274 return m_cell->node_count ; 00275 } 00276 00277 00279 unsigned getVertexCount() const 00280 { 00281 SHARDS_REQUIRE( requireCell() ); 00282 return m_cell->vertex_count ; 00283 } 00284 00285 00287 unsigned getEdgeCount() const 00288 { 00289 SHARDS_REQUIRE( requireCell() ); 00290 return m_cell->edge_count ; 00291 } 00292 00294 unsigned getFaceCount() const 00295 { 00296 SHARDS_REQUIRE( requireCell() ); 00297 return m_cell->dimension == 3 ? m_cell->side_count : 0 ; 00298 } 00299 00300 00302 unsigned getSideCount() const 00303 { 00304 SHARDS_REQUIRE( requireCell() ); 00305 return m_cell->side_count ; 00306 } 00307 00308 00310 bool isValid() const 00311 { return m_cell != 0 ; } 00312 00313 00315 const CellTopologyData * getCellTopologyData() const 00316 { return m_cell ; } 00317 00318 00320 const CellTopologyData * getBaseCellTopologyData() const 00321 { 00322 SHARDS_REQUIRE( requireCell() ); 00323 return m_cell->base ; 00324 } 00325 00326 00332 const CellTopologyData * getCellTopologyData( 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 * getBaseCellTopologyData( const unsigned subcell_dim , 00348 const unsigned subcell_ord ) const 00349 { 00350 return getCellTopologyData(subcell_dim,subcell_ord)->base ; 00351 } 00352 00353 00358 unsigned getKey( const unsigned subcell_dim , 00359 const unsigned subcell_ord ) const 00360 { 00361 return getCellTopologyData(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 getCellTopologyData(subcell_dim,subcell_ord) -> name; 00374 } 00375 00376 00381 unsigned getNodeCount( const unsigned subcell_dim , 00382 const unsigned subcell_ord ) const 00383 { 00384 return getCellTopologyData(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 getCellTopologyData(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 getCellTopologyData(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 getCellTopologyData(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 ) 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.getCellTopologyData() , 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 inline 00679 bool operator==(const CellTopology &left, const CellTopology &right) 00680 { 00681 return left.getCellTopologyData() == right.getCellTopologyData(); 00682 } 00683 00684 inline 00685 bool operator<(const CellTopology &left, const CellTopology &right) 00686 { 00687 return left.getCellTopologyData() < right.getCellTopologyData(); 00688 // FIXME: Should is be this? 00689 // return left.getKey() < right.getKey(); 00690 } 00691 00692 inline 00693 bool operator!=(const CellTopology &left, const CellTopology &right) { 00694 return !(left == right); 00695 } 00696 00697 00700 } // namespace shards 00701 00702 #undef SHARDS_REQUIRE 00703 00704 #endif // Shards_CellTopology_hpp 00705