shards  Version of the Day
 All Classes Functions Variables Typedefs Enumerations Enumerator Groups
Shards_CellTopology.hpp
1 /*
2 //@HEADER
3 // ************************************************************************
4 //
5 // Shards : Shared Discretization Tools
6 // Copyright 2008, 2011 Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact Carter Edwards (hcedwar@sandia.gov),
39 // Pavel Bochev (pbboche@sandia.gov), or
40 // Denis Ridzal (dridzal@sandia.gov).
41 //
42 // ************************************************************************
43 //@HEADER
44 */
45 
46 #ifndef Shards_CellTopology_hpp
47 #define Shards_CellTopology_hpp
48 
49 #ifdef HAVE_SHARDS_DEBUG
50 #define SHARDS_REQUIRE( S ) S
51 #else
52 #define SHARDS_REQUIRE( S ) /* empty */
53 #endif
54 
55 #include <string>
56 #include <vector>
57 #include <Shards_CellTopologyData.h>
58 #include <Shards_BasicTopologies.hpp>
59 
60 namespace shards {
61 
66 /*------------------------------------------------------------------------*/
67 
68 class CellTopology ;
69 
71 //std::ostream & operator << ( std::ostream & , const CellTopologyData & );
72 
73 
75 std::ostream & operator << ( std::ostream & , const CellTopology & );
76 
77 
81 enum ECellType {
82  ALL_CELLS = 0,
83  STANDARD_CELL,
84  NONSTANDARD_CELL
85 };
86 
87 inline std::string ECellTypeToString(ECellType cellType) {
88  std::string retString;
89  switch(cellType){
90  case ALL_CELLS: retString = "All"; break;
91  case STANDARD_CELL: retString = "Standard"; break;
92  case NONSTANDARD_CELL: retString = "Nonstandard"; break;
93  default: retString = "Invalid Cell";
94  }
95  return retString;
96 }
97 
98 
103  ALL_TOPOLOGIES,
104  BASE_TOPOLOGY,
105  EXTENDED_TOPOLOGY
106 };
107 
108 inline std::string ETopologyTypeToString(ETopologyType topologyType) {
109  std::string retString;
110  switch(topologyType){
111  case ALL_TOPOLOGIES: retString = "All"; break;
112  case BASE_TOPOLOGY: retString = "Base"; break;
113  case EXTENDED_TOPOLOGY: retString = "Extended"; break;
114  default: retString = "Invalid Topology";
115  }
116  return retString;
117 }
118 
119 
128 void getTopologies(std::vector<shards::CellTopology>& topologies,
129  const unsigned cellDim = 4,
130  const ECellType cellType = ALL_CELLS,
131  const ETopologyType topologyType = ALL_TOPOLOGIES);
132 
133 
134 
141 int isPredefinedCell(const CellTopology & cell);
142 
143 
144 
145 /*------------------------------------------------------------------------*/
168 private:
169 
173  void requireCell() const ;
174 
175 
180  void requireDimension( const unsigned subcellDim ) const ;
181 
182 
188  void requireSubcell( const unsigned subcellDim ,
189  const unsigned subcellOrd ) const ;
190 
191 
198  void requireNodeMap( const unsigned subcellDim ,
199  const unsigned subcellOrd ,
200  const unsigned nodeOrd ) const ;
201 
202  void requireNodePermutation( const unsigned permutationOrd ,
203  const unsigned nodeOrd ) const ;
204 
205  const CellTopologyData * m_cell ;
206 
207 public:
208 
209  /*------------------------------------------------------------------*/
216  unsigned getDimension() const
217  {
218  SHARDS_REQUIRE( requireCell() );
219  return m_cell->dimension ;
220  }
221 
222 
228  unsigned getKey() const
229  {
230  SHARDS_REQUIRE( requireCell() );
231  return m_cell->key ;
232  }
233 
234 
240  unsigned getBaseKey() const
241  {
242  SHARDS_REQUIRE( requireCell() );
243  return m_cell->base->key ;
244  }
245 
246 
247 
253  const char* getName() const
254  {
255  SHARDS_REQUIRE( requireCell() );
256  return m_cell->name ;
257  }
258 
259 
263  const char* getBaseName() const
264  {
265  SHARDS_REQUIRE( requireCell() );
266  return m_cell->base->name ;
267  }
268 
269 
271  unsigned getNodeCount() const
272  {
273  SHARDS_REQUIRE( requireCell() );
274  return m_cell->node_count ;
275  }
276 
277 
279  unsigned getVertexCount() const
280  {
281  SHARDS_REQUIRE( requireCell() );
282  return m_cell->vertex_count ;
283  }
284 
285 
287  unsigned getEdgeCount() const
288  {
289  SHARDS_REQUIRE( requireCell() );
290  return m_cell->edge_count ;
291  }
292 
294  unsigned getFaceCount() const
295  {
296  SHARDS_REQUIRE( requireCell() );
297  return m_cell->dimension == 3 ? m_cell->side_count : 0 ;
298  }
299 
300 
302  unsigned getSideCount() const
303  {
304  SHARDS_REQUIRE( requireCell() );
305  return m_cell->side_count ;
306  }
307 
308 
310  bool isValid() const
311  { return m_cell != 0 ; }
312 
313 
316  { return m_cell ; }
317 
318 
321  {
322  SHARDS_REQUIRE( requireCell() );
323  return m_cell->base ;
324  }
325 
326 
332  const CellTopologyData * getCellTopologyData( const unsigned subcell_dim ,
333  const unsigned subcell_ord ) const
334  {
335  SHARDS_REQUIRE( requireCell() );
336  SHARDS_REQUIRE( requireDimension(subcell_dim) );
337  SHARDS_REQUIRE( requireSubcell(subcell_dim,subcell_ord) );
338  return m_cell->subcell[subcell_dim][subcell_ord].topology ;
339  }
340 
341 
347  const CellTopologyData * getBaseCellTopologyData( const unsigned subcell_dim ,
348  const unsigned subcell_ord ) const
349  {
350  return getCellTopologyData(subcell_dim,subcell_ord)->base ;
351  }
352 
353 
358  unsigned getKey( const unsigned subcell_dim ,
359  const unsigned subcell_ord ) const
360  {
361  return getCellTopologyData(subcell_dim,subcell_ord)->key ;
362  }
363 
364 
365 
370  const char * getName(const unsigned subcell_dim,
371  const unsigned subcell_ord) const
372  {
373  return getCellTopologyData(subcell_dim,subcell_ord) -> name;
374  }
375 
376 
381  unsigned getNodeCount( const unsigned subcell_dim ,
382  const unsigned subcell_ord ) const
383  {
384  return getCellTopologyData(subcell_dim,subcell_ord)->node_count ;
385  }
386 
387 
392  unsigned getVertexCount( const unsigned subcell_dim ,
393  const unsigned subcell_ord ) const
394  {
395  return getCellTopologyData(subcell_dim,subcell_ord)->vertex_count ;
396  }
397 
398 
403  unsigned getEdgeCount( const unsigned subcell_dim ,
404  const unsigned subcell_ord ) const
405  {
406  return getCellTopologyData(subcell_dim,subcell_ord)->edge_count ;
407  }
408 
409 
414  unsigned getSideCount( const unsigned subcell_dim ,
415  const unsigned subcell_ord ) const
416  {
417  return getCellTopologyData(subcell_dim,subcell_ord)->side_count ;
418  }
419 
420 
424  unsigned getSubcellCount( const unsigned subcell_dim ) const
425  {
426  SHARDS_REQUIRE( requireCell() );
427  SHARDS_REQUIRE( requireDimension(subcell_dim) );
428  return m_cell->subcell_count[subcell_dim] ;
429  }
430 
431 
436  bool getSubcellHomogeneity( const unsigned subcell_dim ) const
437  {
438  SHARDS_REQUIRE( requireCell() );
439  SHARDS_REQUIRE( requireDimension(subcell_dim) );
440  return 0 != m_cell->subcell_homogeneity[subcell_dim] ;
441  }
442 
443 
450  unsigned getNodeMap( const unsigned subcell_dim ,
451  const unsigned subcell_ord ,
452  const unsigned subcell_node_ord ) const
453  {
454  SHARDS_REQUIRE( requireCell() );
455  SHARDS_REQUIRE( requireDimension(subcell_dim) );
456  SHARDS_REQUIRE( requireSubcell(subcell_dim,subcell_ord) );
457  SHARDS_REQUIRE( requireNodeMap(subcell_dim,subcell_ord,subcell_node_ord));
458  return m_cell->subcell[subcell_dim][subcell_ord].node[subcell_node_ord];
459  }
460 
461 
463  unsigned getNodePermutationCount() const
464  {
465  SHARDS_REQUIRE(requireCell());
466  return m_cell->permutation_count ;
467  }
468 
473  unsigned getNodePermutation( const unsigned permutation_ord ,
474  const unsigned node_ord ) const
475  {
476  SHARDS_REQUIRE(requireCell());
477  SHARDS_REQUIRE(requireNodePermutation(permutation_ord,node_ord));
478  return m_cell->permutation[permutation_ord].node[node_ord];
479  }
480 
485  unsigned getNodePermutationPolarity( const unsigned permutation_ord ) const
486  {
487  SHARDS_REQUIRE(requireCell());
488  SHARDS_REQUIRE(requireNodePermutation(permutation_ord,0));
489  return m_cell->permutation[permutation_ord].polarity;
490  }
491 
496  unsigned getNodePermutationInverse( const unsigned permutation_ord ,
497  const unsigned node_ord ) const
498  {
499  SHARDS_REQUIRE(requireCell());
500  SHARDS_REQUIRE(requireNodePermutation(permutation_ord,node_ord));
501  return m_cell->permutation_inverse[permutation_ord].node[node_ord];
502  }
503 
506  /*------------------------------------------------------------------*/
521  : m_cell( cell )
522  {}
523 
524 
532  CellTopology( const std::string & name,
533  const unsigned nodeCount);
534 
535 
545  CellTopology( const std::string & name,
546  const unsigned vertex_count,
547  const unsigned node_count,
548  const std::vector< const CellTopologyData * > & edges ,
549  const std::vector< unsigned > & edge_node_map ,
550  const CellTopologyData * base = NULL );
551 
552 
564  CellTopology( const std::string & name,
565  const unsigned vertex_count,
566  const unsigned node_count,
567  const std::vector< const CellTopologyData * > & edges ,
568  const std::vector< unsigned > & edge_node_map ,
569  const std::vector< const CellTopologyData * > & faces ,
570  const std::vector< unsigned > & face_node_map ,
571  const CellTopologyData * base = NULL );
572 
573 
575  CellTopology& operator = (const CellTopology& right);
576 
578  CellTopology( const CellTopology& right );
579 
581  CellTopology();
582 
584  ~CellTopology();
585 
588 }; // class CellTopology
589 
590 /*------------------------------------------------------------------------*/
591 /* \brief Find the permutation from the expected nodes to the actual nodes,
592  *
593  * Find permutation 'p' such that:
594  * actual_node[j] == expected_node[ top.permutation[p].node[j] ]
595  * for all vertices.
596  */
597 template< typename id_type >
598 int findPermutation( const CellTopologyData & top ,
599  const id_type * const expected_node ,
600  const id_type * const actual_node )
601 {
602  const int nv = top.vertex_count ;
603  const int np = top.permutation_count ;
604  int p = 0 ;
605  for ( ; p < np ; ++p ) {
606  const unsigned * const perm_node = top.permutation[p].node ;
607  int j = 0 ;
608  for ( ; j < nv && actual_node[j] == expected_node[ perm_node[j] ] ; ++j );
609  if ( nv == j ) break ;
610  }
611  if ( np == p ) p = -1 ;
612  return p ;
613 }
614 
615 template< typename id_type >
616 int findPermutation( const CellTopology & top ,
617  const id_type * const expected_node ,
618  const id_type * const actual_node )
619 {
620  return findPermutation( * top.getCellTopologyData() , expected_node , actual_node );
621 }
622 
623 /*------------------------------------------------------------------------*/
633 void badCellTopologyKey( const unsigned dimension ,
634  const unsigned face_count ,
635  const unsigned edge_count ,
636  const unsigned vertex_count ,
637  const unsigned node_count );
638 
639 
648 inline
649 unsigned cellTopologyKey( const unsigned dimension ,
650  const unsigned face_count ,
651  const unsigned edge_count ,
652  const unsigned vertex_count ,
653  const unsigned node_count )
654 {
655  const bool bad = ( dimension >> 3 ) ||
656  ( face_count >> 6 ) ||
657  ( edge_count >> 6 ) ||
658  ( vertex_count >> 6 ) ||
659  ( node_count >> 10 );
660 
661  if ( bad ) {
662  badCellTopologyKey( dimension ,
663  face_count ,
664  edge_count ,
665  vertex_count ,
666  node_count );
667  }
668 
669  const unsigned key = ( dimension << 28 ) |
670  ( face_count << 22 ) |
671  ( edge_count << 16 ) |
672  ( vertex_count << 10 ) |
673  ( node_count ) ;
674 
675  return key ;
676 }
677 
678 inline
679 bool operator==(const CellTopology &left, const CellTopology &right)
680 {
681  return left.getCellTopologyData() == right.getCellTopologyData();
682 }
683 
684 inline
685 bool operator<(const CellTopology &left, const CellTopology &right)
686 {
687  return left.getCellTopologyData() < right.getCellTopologyData();
688 // FIXME: Should is be this?
689 // return left.getKey() < right.getKey();
690 }
691 
692 inline
693 bool operator!=(const CellTopology &left, const CellTopology &right) {
694  return !(left == right);
695 }
696 
697 
700 } // namespace shards
701 
702 #undef SHARDS_REQUIRE
703 
704 #endif // Shards_CellTopology_hpp
705 
~CellTopology()
Destructor.
unsigned getVertexCount(const unsigned subcell_dim, const unsigned subcell_ord) const
Vertex count of a subcell of the given dimension and ordinal.
unsigned getNodeMap(const unsigned subcell_dim, const unsigned subcell_ord, const unsigned subcell_node_ord) const
Mapping from a subcell&#39;s node ordinal to a node ordinal of this parent cell topology.
unsigned getNodePermutation(const unsigned permutation_ord, const unsigned node_ord) const
Permutation of a cell&#39;s node ordinals.
ETopologyType
Enumeration of topology types in Shards.
unsigned getNodeCount() const
Node count of this cell topology.
struct CellTopologyData * base
Base, a.k.a. not-extended, version of this topology where vertex_count == node_count.
unsigned subcell_homogeneity[4]
Flag if the subcells of a given dimension are homogeneous.
unsigned key
Unique key for this topology.
unsigned getKey() const
Unique key for this cell topology; under certain subcell uniformity conditions.
void getTopologies(std::vector< shards::CellTopology > &topologies, const unsigned cellDim=4, const ECellType cellType=ALL_CELLS, const ETopologyType topologyType=ALL_TOPOLOGIES)
Returns an std::vector with all cell topologies that meet the specified selection flags...
unsigned getNodePermutationPolarity(const unsigned permutation_ord) const
Permutation of a cell&#39;s node ordinals.
unsigned getNodeCount(const unsigned subcell_dim, const unsigned subcell_ord) const
Node count of a subcell of the given dimension and ordinal.
const CellTopologyData * getCellTopologyData() const
This cell&#39;s raw topology data.
unsigned vertex_count
Number of vertices.
const CellTopologyData * getBaseCellTopologyData(const unsigned subcell_dim, const unsigned subcell_ord) const
Raw cell topology data for the base topology of a subcell of the given dimension and ordinal...
ECellType
Enumeration of cell types in Shards.
CellTopology()
Default constructor initializes to NULL.
const char * getName() const
Unique name for this cell topology;.
unsigned subcell_count[4]
Number of subcells of each dimension.
unsigned edge_count
Number of edges (a.k.a. boundary subcells).
unsigned getEdgeCount(const unsigned subcell_dim, const unsigned subcell_ord) const
Edge count of a subcell of the given dimension and ordinal.
unsigned dimension
Topological dimension.
const CellTopologyData * getBaseCellTopologyData() const
This cell&#39;s base cell topology&#39;s raw topology data.
bool getSubcellHomogeneity(const unsigned subcell_dim) const
Query if all subcells of the given dimension have the same cell topology.
unsigned node_count
Number of nodes (a.k.a. subcells).
unsigned cellTopologyKey(const unsigned dimension, const unsigned face_count, const unsigned edge_count, const unsigned vertex_count, const unsigned node_count)
Generate integer key from topological dimensions.
const unsigned * node
Subcell indexing of with respect to parent cell.
const char * name
Intuitive name for this topology.
struct CellTopologyData * topology
Subcell topology.
unsigned side_count
Number of sides (a.k.a. boundary subcells).
unsigned getSideCount(const unsigned subcell_dim, const unsigned subcell_ord) const
Side count of a subcell of the given dimension and ordinal.
unsigned getNodePermutationCount() const
Number of node permutations defined for this cell.
unsigned getKey(const unsigned subcell_dim, const unsigned subcell_ord) const
Key of a subcell of the given dimension and ordinal.
struct CellTopologyData_Subcell * subcell[4]
Array of subcells of each dimension.
unsigned getBaseKey() const
Unique key for this cell&#39;s base topology; under certain subcell uniformity conditions.
int isPredefinedCell(const CellTopology &cell)
Checks if the cell topology is predefined in shards.
unsigned getDimension() const
Dimension of this cell topology.
const CellTopologyData * getCellTopologyData(const unsigned subcell_dim, const unsigned subcell_ord) const
Raw cell topology data for a subcell of the given dimension and ordinal.
A simple &#39;C&#39; struct of cell topology attributes.
unsigned getNodePermutationInverse(const unsigned permutation_ord, const unsigned node_ord) const
Inverse permutation of a cell&#39;s node ordinals.
struct CellTopologyData_Permutation * permutation
Array of node permutations.
unsigned getFaceCount() const
Face boundary subcell count of this cell topology.
const char * getBaseName() const
Unique name for this cell&#39;s base topology.
std::ostream & operator<<(std::ostream &, const CellTopology &)
Overloaded &lt;&lt; operator for CellTopologyData objects.
CellTopology(const CellTopologyData *cell)
Wrapper for safe access to a raw cell topology data.
Provide input checked access (in debug mode) to cell topology data and a procedure to create custom c...
unsigned getEdgeCount() const
Edge boundary subcell count of this cell topology.
const char * getName(const unsigned subcell_dim, const unsigned subcell_ord) const
Name of a subcell of the given dimension and ordinal.
unsigned getSideCount() const
Side boundary subcell count of this cell topology.
CellTopology & operator=(const CellTopology &right)
Assignment operator *this = right.
bool isValid() const
This cell&#39;s raw topology data.
unsigned getSubcellCount(const unsigned subcell_dim) const
Subcell count of subcells of the given dimension.
unsigned permutation_count
Number of defined permutations.
unsigned getVertexCount() const
Vertex count of this cell topology.
void badCellTopologyKey(const unsigned dimension, const unsigned face_count, const unsigned edge_count, const unsigned vertex_count, const unsigned node_count)
Generates detailed message if one or more input parameters are out of their admissible bounds...