shards Version of the Day
Loading...
Searching...
No Matches
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
60namespace shards {
61
66/*------------------------------------------------------------------------*/
67
68class CellTopology ;
69
71//std::ostream & operator << ( std::ostream & , const CellTopologyData & );
72
73
75std::ostream & operator << ( std::ostream & , const CellTopology & );
76
77
81enum ECellType {
82 ALL_CELLS = 0,
83 STANDARD_CELL,
84 NONSTANDARD_CELL
85};
86
87inline 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
102enum ETopologyType {
103 ALL_TOPOLOGIES,
104 BASE_TOPOLOGY,
105 EXTENDED_TOPOLOGY
106};
107
108inline 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
128void 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
142
143
144
145/*------------------------------------------------------------------------*/
168private:
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
207public:
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
576
578 CellTopology( const CellTopology& right );
579
582
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 */
597template< typename id_type >
598int 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
615template< typename id_type >
616int 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/*------------------------------------------------------------------------*/
633void 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
648inline
649unsigned 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
678inline
679bool operator==(const CellTopology &left, const CellTopology &right)
680{
681 return left.getCellTopologyData() == right.getCellTopologyData();
682}
683
684inline
685bool 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
692inline
693bool 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
Provide input checked access (in debug mode) to cell topology data and a procedure to create custom c...
const CellTopologyData * getCellTopologyData() const
This cell's raw topology data.
unsigned getNodeCount(const unsigned subcell_dim, const unsigned subcell_ord) const
Node count 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's raw topology data.
const char * getName() const
Unique name for this cell topology;.
unsigned getBaseKey() const
Unique key for this cell's base topology; under certain subcell uniformity conditions.
unsigned getSideCount(const unsigned subcell_dim, const unsigned subcell_ord) const
Side count of a subcell of the given dimension and ordinal.
unsigned getSubcellCount(const unsigned subcell_dim) const
Subcell count of subcells of the given dimension.
unsigned getEdgeCount() const
Edge boundary subcell count of this cell topology.
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.
unsigned getNodePermutationCount() const
Number of node permutations defined for this cell.
CellTopology(const std::string &name, const unsigned vertex_count, const unsigned node_count, const std::vector< const CellTopologyData * > &edges, const std::vector< unsigned > &edge_node_map, const CellTopologyData *base=NULL)
Construct custom 2-cell (polygon) from a list of edges. The default base topology is the specified cu...
~CellTopology()
Destructor.
CellTopology(const CellTopology &right)
Copy constructor.
const CellTopologyData * getBaseCellTopologyData() const
This cell's base cell topology's raw topology data.
unsigned getNodePermutationPolarity(const unsigned permutation_ord) const
Permutation of a cell's node ordinals.
unsigned getNodeCount() const
Node count of this cell topology.
unsigned getNodeMap(const unsigned subcell_dim, const unsigned subcell_ord, const unsigned subcell_node_ord) const
Mapping from a subcell's node ordinal to a node ordinal of this parent cell topology.
CellTopology(const std::string &name, const unsigned vertex_count, const unsigned node_count, const std::vector< const CellTopologyData * > &edges, const std::vector< unsigned > &edge_node_map, const std::vector< const CellTopologyData * > &faces, const std::vector< unsigned > &face_node_map, const CellTopologyData *base=NULL)
Construct custom 3-cell (polyhedron) from a list of edges and sides. The default base topology is the...
unsigned getKey(const unsigned subcell_dim, const unsigned subcell_ord) const
Key of a subcell of the given dimension and ordinal.
CellTopology()
Default constructor initializes to NULL.
unsigned getVertexCount(const unsigned subcell_dim, const unsigned subcell_ord) const
Vertex count of a subcell of the given dimension and ordinal.
CellTopology(const CellTopologyData *cell)
Wrapper for safe access to a raw cell topology data.
CellTopology(const std::string &name, const unsigned nodeCount)
Constructs custom 1-cell (line) with base topology Line<>. Example use: the statement.
bool getSubcellHomogeneity(const unsigned subcell_dim) const
Query if all subcells of the given dimension have the same 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 getNodePermutationInverse(const unsigned permutation_ord, const unsigned node_ord) const
Inverse permutation of a cell's node ordinals.
unsigned getKey() const
Unique key for this cell topology; under certain subcell uniformity conditions.
unsigned getFaceCount() const
Face boundary subcell count of this cell topology.
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.
unsigned getVertexCount() const
Vertex count of this cell topology.
const char * getBaseName() const
Unique name for this cell's base topology.
unsigned getEdgeCount(const unsigned subcell_dim, const unsigned subcell_ord) const
Edge count of a subcell of the given dimension and ordinal.
unsigned getNodePermutation(const unsigned permutation_ord, const unsigned node_ord) const
Permutation of a cell's node ordinals.
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.
std::ostream & operator<<(std::ostream &, const CellTopology &)
Overloaded << operator for CellTopologyData objects.
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.
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.
int isPredefinedCell(const CellTopology &cell)
Checks if the cell topology is predefined in shards.
const struct CellTopologyData * topology
Subcell topology.
const unsigned * node
Subcell indexing of with respect to parent cell.
A simple 'C' struct of cell topology attributes.
const char * name
Intuitive name for this topology.
unsigned node_count
Number of nodes (a.k.a. subcells).
unsigned side_count
Number of sides (a.k.a. boundary subcells).
const struct CellTopologyData * base
Base, a.k.a. not-extended, version of this topology where vertex_count == node_count.
unsigned key
Unique key for this topology.
unsigned edge_count
Number of edges (a.k.a. boundary subcells).
unsigned vertex_count
Number of vertices.
unsigned permutation_count
Number of defined permutations.
unsigned subcell_homogeneity[4]
Flag if the subcells of a given dimension are homogeneous.
const struct CellTopologyData_Subcell * subcell[4]
Array of subcells of each dimension.
const struct CellTopologyData_Permutation * permutation
Array of node permutations.
unsigned dimension
Topological dimension.
unsigned subcell_count[4]
Number of subcells of each dimension.