shards Version of the Day
Loading...
Searching...
No Matches
Shards_CellTopology.hpp
1// @HEADER
2// *****************************************************************************
3// Shards : Shared Discretization Tools
4//
5// Copyright 2008-2011 NTESS and the Shards contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#ifndef Shards_CellTopology_hpp
11#define Shards_CellTopology_hpp
12
13#ifdef HAVE_SHARDS_DEBUG
14#define SHARDS_REQUIRE( S ) S
15#else
16#define SHARDS_REQUIRE( S ) /* empty */
17#endif
18
19#include <string>
20#include <vector>
21#include <Shards_CellTopologyData.h>
22#include <Shards_BasicTopologies.hpp>
23
24namespace shards {
25
29
30/*------------------------------------------------------------------------*/
31
32class CellTopology ;
33
35//std::ostream & operator << ( std::ostream & , const CellTopologyData & );
36
37
39std::ostream & operator << ( std::ostream & , const CellTopology & );
40
41
46 ALL_CELLS = 0,
47 STANDARD_CELL,
48 NONSTANDARD_CELL
49};
50
51inline std::string ECellTypeToString(ECellType cellType) {
52 std::string retString;
53 switch(cellType){
54 case ALL_CELLS: retString = "All"; break;
55 case STANDARD_CELL: retString = "Standard"; break;
56 case NONSTANDARD_CELL: retString = "Nonstandard"; break;
57 default: retString = "Invalid Cell";
58 }
59 return retString;
60}
61
62
67 ALL_TOPOLOGIES,
68 BASE_TOPOLOGY,
69 EXTENDED_TOPOLOGY
70};
71
72inline std::string ETopologyTypeToString(ETopologyType topologyType) {
73 std::string retString;
74 switch(topologyType){
75 case ALL_TOPOLOGIES: retString = "All"; break;
76 case BASE_TOPOLOGY: retString = "Base"; break;
77 case EXTENDED_TOPOLOGY: retString = "Extended"; break;
78 default: retString = "Invalid Topology";
79 }
80 return retString;
81}
82
83
92void getTopologies(std::vector<shards::CellTopology>& topologies,
93 const unsigned cellDim = 4,
94 const ECellType cellType = ALL_CELLS,
95 const ETopologyType topologyType = ALL_TOPOLOGIES);
96
97
98
106
107
108
109/*------------------------------------------------------------------------*/
132private:
133
137 void requireCell() const ;
138
139
144 void requireDimension( const unsigned subcellDim ) const ;
145
146
152 void requireSubcell( const unsigned subcellDim ,
153 const unsigned subcellOrd ) const ;
154
155
162 void requireNodeMap( const unsigned subcellDim ,
163 const unsigned subcellOrd ,
164 const unsigned nodeOrd ) const ;
165
166 void requireNodePermutation( const unsigned permutationOrd ,
167 const unsigned nodeOrd ) const ;
168
169 const CellTopologyData * m_cell ;
170
171public:
172
173 /*------------------------------------------------------------------*/
177
178
180 unsigned getDimension() const
181 {
182 SHARDS_REQUIRE( requireCell() );
183 return m_cell->dimension ;
184 }
185
186
192 unsigned getKey() const
193 {
194 SHARDS_REQUIRE( requireCell() );
195 return m_cell->key ;
196 }
197
198
204 unsigned getBaseKey() const
205 {
206 SHARDS_REQUIRE( requireCell() );
207 return m_cell->base->key ;
208 }
209
210
211
217 const char* getName() const
218 {
219 SHARDS_REQUIRE( requireCell() );
220 return m_cell->name ;
221 }
222
223
227 const char* getBaseName() const
228 {
229 SHARDS_REQUIRE( requireCell() );
230 return m_cell->base->name ;
231 }
232
233
235 unsigned getNodeCount() const
236 {
237 SHARDS_REQUIRE( requireCell() );
238 return m_cell->node_count ;
239 }
240
241
243 unsigned getVertexCount() const
244 {
245 SHARDS_REQUIRE( requireCell() );
246 return m_cell->vertex_count ;
247 }
248
249
251 unsigned getEdgeCount() const
252 {
253 SHARDS_REQUIRE( requireCell() );
254 return m_cell->edge_count ;
255 }
256
258 unsigned getFaceCount() const
259 {
260 SHARDS_REQUIRE( requireCell() );
261 return m_cell->dimension == 3 ? m_cell->side_count : 0 ;
262 }
263
264
266 unsigned getSideCount() const
267 {
268 SHARDS_REQUIRE( requireCell() );
269 return m_cell->side_count ;
270 }
271
272
274 bool isValid() const
275 { return m_cell != 0 ; }
276
277
280 { return m_cell ; }
281
282
285 {
286 SHARDS_REQUIRE( requireCell() );
287 return m_cell->base ;
288 }
289
290
296 const CellTopologyData * getCellTopologyData( const unsigned subcell_dim ,
297 const unsigned subcell_ord ) const
298 {
299 SHARDS_REQUIRE( requireCell() );
300 SHARDS_REQUIRE( requireDimension(subcell_dim) );
301 SHARDS_REQUIRE( requireSubcell(subcell_dim,subcell_ord) );
302 return m_cell->subcell[subcell_dim][subcell_ord].topology ;
303 }
304
305
311 const CellTopologyData * getBaseCellTopologyData( const unsigned subcell_dim ,
312 const unsigned subcell_ord ) const
313 {
314 return getCellTopologyData(subcell_dim,subcell_ord)->base ;
315 }
316
317
322 unsigned getKey( const unsigned subcell_dim ,
323 const unsigned subcell_ord ) const
324 {
325 return getCellTopologyData(subcell_dim,subcell_ord)->key ;
326 }
327
328
329
334 const char * getName(const unsigned subcell_dim,
335 const unsigned subcell_ord) const
336 {
337 return getCellTopologyData(subcell_dim,subcell_ord) -> name;
338 }
339
340
345 unsigned getNodeCount( const unsigned subcell_dim ,
346 const unsigned subcell_ord ) const
347 {
348 return getCellTopologyData(subcell_dim,subcell_ord)->node_count ;
349 }
350
351
356 unsigned getVertexCount( const unsigned subcell_dim ,
357 const unsigned subcell_ord ) const
358 {
359 return getCellTopologyData(subcell_dim,subcell_ord)->vertex_count ;
360 }
361
362
367 unsigned getEdgeCount( const unsigned subcell_dim ,
368 const unsigned subcell_ord ) const
369 {
370 return getCellTopologyData(subcell_dim,subcell_ord)->edge_count ;
371 }
372
373
378 unsigned getSideCount( const unsigned subcell_dim ,
379 const unsigned subcell_ord ) const
380 {
381 return getCellTopologyData(subcell_dim,subcell_ord)->side_count ;
382 }
383
384
388 unsigned getSubcellCount( const unsigned subcell_dim ) const
389 {
390 SHARDS_REQUIRE( requireCell() );
391 SHARDS_REQUIRE( requireDimension(subcell_dim) );
392 return m_cell->subcell_count[subcell_dim] ;
393 }
394
395
400 bool getSubcellHomogeneity( const unsigned subcell_dim ) const
401 {
402 SHARDS_REQUIRE( requireCell() );
403 SHARDS_REQUIRE( requireDimension(subcell_dim) );
404 return 0 != m_cell->subcell_homogeneity[subcell_dim] ;
405 }
406
407
414 unsigned getNodeMap( const unsigned subcell_dim ,
415 const unsigned subcell_ord ,
416 const unsigned subcell_node_ord ) const
417 {
418 SHARDS_REQUIRE( requireCell() );
419 SHARDS_REQUIRE( requireDimension(subcell_dim) );
420 SHARDS_REQUIRE( requireSubcell(subcell_dim,subcell_ord) );
421 SHARDS_REQUIRE( requireNodeMap(subcell_dim,subcell_ord,subcell_node_ord));
422 return m_cell->subcell[subcell_dim][subcell_ord].node[subcell_node_ord];
423 }
424
425
427 unsigned getNodePermutationCount() const
428 {
429 SHARDS_REQUIRE(requireCell());
430 return m_cell->permutation_count ;
431 }
432
437 unsigned getNodePermutation( const unsigned permutation_ord ,
438 const unsigned node_ord ) const
439 {
440 SHARDS_REQUIRE(requireCell());
441 SHARDS_REQUIRE(requireNodePermutation(permutation_ord,node_ord));
442 return m_cell->permutation[permutation_ord].node[node_ord];
443 }
444
449 unsigned getNodePermutationPolarity( const unsigned permutation_ord ) const
450 {
451 SHARDS_REQUIRE(requireCell());
452 SHARDS_REQUIRE(requireNodePermutation(permutation_ord,0));
453 return m_cell->permutation[permutation_ord].polarity;
454 }
455
460 unsigned getNodePermutationInverse( const unsigned permutation_ord ,
461 const unsigned node_ord ) const
462 {
463 SHARDS_REQUIRE(requireCell());
464 SHARDS_REQUIRE(requireNodePermutation(permutation_ord,node_ord));
465 return m_cell->permutation_inverse[permutation_ord].node[node_ord];
466 }
467
469
470 /*------------------------------------------------------------------*/
474
485 : m_cell( cell )
486 {}
487
499 CellTopology( const std::string & name,
500 const unsigned vertex_count,
501 const unsigned node_count,
502 const std::vector< const CellTopologyData * > & edges ,
503 const std::vector< unsigned > & edge_node_map ,
504 const std::vector< const CellTopologyData * > & faces ,
505 const std::vector< unsigned > & face_node_map ,
506 const CellTopologyData * base = NULL );
507
508
511
513 CellTopology( const CellTopology& right );
514
517
520
522
523}; // class CellTopology
524
525/*------------------------------------------------------------------------*/
526/* \brief Find the permutation from the expected nodes to the actual nodes,
527 *
528 * Find permutation 'p' such that:
529 * actual_node[j] == expected_node[ top.permutation[p].node[j] ]
530 * for all vertices.
531 */
532template< typename id_type >
533int findPermutation( const CellTopologyData & top ,
534 const id_type * const expected_node ,
535 const id_type * const actual_node )
536{
537 const int nv = top.vertex_count ;
538 const int np = top.permutation_count ;
539 int p = 0 ;
540 for ( ; p < np ; ++p ) {
541 const unsigned * const perm_node = top.permutation[p].node ;
542 int j = 0 ;
543 for ( ; j < nv && actual_node[j] == expected_node[ perm_node[j] ] ; ++j );
544 if ( nv == j ) break ;
545 }
546 if ( np == p ) p = -1 ;
547 return p ;
548}
549
550template< typename id_type >
551int findPermutation( const CellTopology & top ,
552 const id_type * const expected_node ,
553 const id_type * const actual_node )
554{
555 return findPermutation( * top.getCellTopologyData() , expected_node , actual_node );
556}
557
558/*------------------------------------------------------------------------*/
568void badCellTopologyKey( const unsigned dimension ,
569 const unsigned face_count ,
570 const unsigned edge_count ,
571 const unsigned vertex_count ,
572 const unsigned node_count );
573
574
583inline
584unsigned cellTopologyKey( const unsigned dimension ,
585 const unsigned face_count ,
586 const unsigned edge_count ,
587 const unsigned vertex_count ,
588 const unsigned node_count )
589{
590 const bool bad = ( dimension >> 3 ) ||
591 ( face_count >> 6 ) ||
592 ( edge_count >> 6 ) ||
593 ( vertex_count >> 6 ) ||
594 ( node_count >> 10 );
595
596 if ( bad ) {
597 badCellTopologyKey( dimension ,
598 face_count ,
599 edge_count ,
600 vertex_count ,
601 node_count );
602 }
603
604 const unsigned key = ( dimension << 28 ) |
605 ( face_count << 22 ) |
606 ( edge_count << 16 ) |
607 ( vertex_count << 10 ) |
608 ( node_count ) ;
609
610 return key ;
611}
612
613inline
614bool operator==(const CellTopology &left, const CellTopology &right)
615{
616 return left.getCellTopologyData() == right.getCellTopologyData();
617}
618
619inline
620bool operator<(const CellTopology &left, const CellTopology &right)
621{
622 return left.getCellTopologyData() < right.getCellTopologyData();
623// FIXME: Should is be this?
624// return left.getKey() < right.getKey();
625}
626
627inline
628bool operator!=(const CellTopology &left, const CellTopology &right) {
629 return !(left == right);
630}
631
632
634
635} // namespace shards
636
637#undef SHARDS_REQUIRE
638
639#endif // Shards_CellTopology_hpp
640
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()
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.
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.
ETopologyType
Enumeration of topology types in Shards.
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.
ECellType
Enumeration of cell types in Shards.
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.
A simple 'C' struct of cell topology attributes.
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.
const struct CellTopologyData_Permutation * permutation
Array of node permutations.