Dune Core Modules (2.5.2)

type.hh
Go to the documentation of this file.
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 #ifndef DUNE_GEOMETRY_TYPE_HH
4 #define DUNE_GEOMETRY_TYPE_HH
5 
10 #include <cassert>
11 
12 #include <string>
13 
16 #include <dune/common/unused.hh>
17 
18 namespace Dune
19 {
20 
21  namespace Impl
22  {
23 
24  enum TopologyConstruction { pyramidConstruction = 0, prismConstruction = 1 };
25 
26 
27 
28  // Basic Topology Types
29  // --------------------
30 
31  struct Point
32  {
33  static const unsigned int dimension = 0;
34  static const unsigned int numCorners = 1;
35 
36  static const unsigned int id = 0;
37 
38  static std::string name () { return "p"; }
39  };
40 
41 
42  template< class BaseTopology >
43  struct Prism
44  {
45  static const unsigned int dimension = BaseTopology::dimension + 1;
46  static const unsigned int numCorners = 2 * BaseTopology::numCorners;
47 
48  static const unsigned int id = BaseTopology::id | ((unsigned int)prismConstruction << (dimension-1));
49 
50  static std::string name () { return BaseTopology::name() + "l"; }
51  };
52 
53 
54  template< class BaseTopology >
55  struct Pyramid
56  {
57  static const unsigned int dimension = BaseTopology::dimension + 1;
58  static const unsigned int numCorners = BaseTopology::numCorners + 1;
59 
60  static const unsigned int id = BaseTopology::id | ((unsigned int)pyramidConstruction << (dimension-1));
61 
62  static std::string name () { return BaseTopology::name() + "o"; }
63  };
64 
65 
66 
67  // Properties of Topologies
68  // ------------------------
69 
70  template< class Topology >
71  struct IsSimplex
72  : public std::integral_constant< bool, (Topology::id >> 1) == 0 >
73  {};
74 
75  template< class Topology >
76  struct IsCube
77  : public std::integral_constant< bool, (Topology::id | 1) == (1 << Topology::dimension) - 1 >
78  {};
79 
80 
81 
82  // Dynamic Topology Properties
83  // ---------------------------
84 
93  inline static unsigned int numTopologies ( int dim ) noexcept
94  {
95  return (1u << dim);
96  }
97 
109  inline bool static isPyramid ( unsigned int topologyId, int dim, int codim = 0 ) noexcept
110  {
111  assert( (dim > 0) && (topologyId < numTopologies( dim )) );
112  assert( (0 <= codim) && (codim < dim) );
113  return (((topologyId & ~1) & (1u << (dim-codim-1))) == 0);
114  }
115 
127  inline static bool isPrism ( unsigned int topologyId, int dim, int codim = 0 ) noexcept
128  {
129  assert( (dim > 0) && (topologyId < numTopologies( dim )) );
130  assert( (0 <= codim) && (codim < dim) );
131  return (( (topologyId | 1) & (1u << (dim-codim-1))) != 0);
132  }
133 
146  inline static bool isTopology ( TopologyConstruction construction, unsigned int topologyId, int dim, int codim = 0 ) noexcept
147  {
148  assert( (dim > 0) && (topologyId < numTopologies( dim )) );
149  assert( (0 <= codim) && (codim <= dim) );
150  return (codim >= (dim-1)) || (((topologyId >> (dim-codim-1)) & 1) == (unsigned int)construction);
151  }
152 
160  inline static unsigned int baseTopologyId ( unsigned int topologyId, int dim, int codim = 1 ) noexcept
161  {
162  assert( (dim >= 0) && (topologyId < numTopologies( dim )) );
163  assert( (0 <= codim) && (codim <= dim) );
164  return topologyId & ((1u << (dim-codim)) - 1);
165  }
166 
167 
168 
169  // SimplexTopology
170  // ---------------
171 
172  template< unsigned int dim >
173  struct SimplexTopology
174  {
175  typedef Pyramid< typename SimplexTopology< dim-1 >::type > type;
176  };
177 
178  template<>
179  struct SimplexTopology< 0 >
180  {
181  typedef Point type;
182  };
183 
184 
185 
186  // CubeTopology
187  // ------------
188 
189  template< unsigned int dim >
190  struct CubeTopology
191  {
192  typedef Prism< typename CubeTopology< dim-1 >::type > type;
193  };
194 
195  template<>
196  struct CubeTopology< 0 >
197  {
198  typedef Point type;
199  };
200 
201 
202 
203  // PyramidTopology
204  // ---------------
205 
206  template< unsigned int dim >
207  struct PyramidTopology
208  {
209  typedef Pyramid< typename CubeTopology< dim-1 >::type > type;
210  };
211 
212 
213 
214  // PrismTopology
215  // -------------
216 
217  template< unsigned int dim >
218  struct PrismTopology
219  {
220  typedef Prism< typename SimplexTopology< dim-1 >::type > type;
221  };
222 
223 
224 
225 
226  // IfTopology
227  // ----------
228 
229  template< template< class > class Operation, int dim, class Topology = Point >
230  struct IfTopology
231  {
232  template< class... Args >
233  static auto apply ( unsigned int topologyId, Args &&... args )
234  {
235  if( topologyId & 1 )
236  return IfTopology< Operation, dim-1, Prism< Topology > >::apply( topologyId >> 1, std::forward< Args >( args )... );
237  else
238  return IfTopology< Operation, dim-1, Pyramid< Topology > >::apply( topologyId >> 1, std::forward< Args >( args )... );
239  }
240  };
241 
242  template< template< class > class Operation, class Topology >
243  struct IfTopology< Operation, 0, Topology >
244  {
245  template< class... Args >
246  static auto apply ( unsigned int topologyId, Args &&... args )
247  {
248  DUNE_UNUSED_PARAMETER( topologyId );
249  return Operation< Topology >::apply( std::forward< Args >( args )... );
250  }
251  };
252 
253  } // namespace Impl
254 
255 
256 
257  // GeometryType
258  // -------------
259 
267  class GeometryType
268  {
269  public:
272  enum BasicType {
273  simplex,
274  cube,
275  pyramid,
276  prism,
277  extended,
278  none
279  };
280 
282  enum Binary {
283  b0001 = 1,
284  b0011 = 3,
285  b0101 = 5,
286  b0111 = 7
287  };
288  private:
289 
291  unsigned int topologyId_;
292 
294  unsigned char dim_ : 7;
295 
297  bool none_ : 1;
298 
299  public:
301  GeometryType ()
302  : topologyId_(0), dim_(0), none_(true)
303  {}
304 
306  GeometryType(BasicType basicType, unsigned int dim)
307  : topologyId_(0), dim_(dim), none_((basicType == GeometryType::none) ? true : false)
308  {
309  if (dim < 2)
310  return;
311  switch( basicType )
312  {
313  case GeometryType::simplex :
314  makeSimplex(dim);
315  break;
316  case GeometryType::cube :
317  makeCube(dim);
318  break;
319  case GeometryType::pyramid :
320  if (dim == 3)
321  makePyramid();
322  else
323  DUNE_THROW( RangeError,
324  "Invalid basic geometry type: no pyramids for dimension " << dim << "." );
325  break;
326  case GeometryType::prism :
327  if (dim == 3)
328  makePrism();
329  else
330  DUNE_THROW( RangeError,
331  "Invalid basic geometry type: no prisms for dimension " << dim << "." );
332  break;
333  case GeometryType::none :
334  break;
335  default :
336  DUNE_THROW( RangeError,
337  "Invalid basic geometry type: " << basicType << " for dimension " << dim << "." );
338  }
339  }
340 
346  GeometryType(unsigned int topologyId, unsigned int dim)
347  : topologyId_(topologyId), dim_(dim), none_(false)
348  {}
349 
360  template<class TopologyType,
361  class = Dune::void_t<decltype(TopologyType::dimension), decltype(TopologyType::id)>>
362  explicit GeometryType(TopologyType t)
363  : topologyId_(TopologyType::id), dim_(TopologyType::dimension), none_(false)
364  {
365  DUNE_UNUSED_PARAMETER(t);
366  }
367 
369  explicit GeometryType(unsigned int dim)
370  : topologyId_(0), dim_(dim), none_(false)
371  {
372  assert(dim < 2);
373  }
374 
376  // We need this constructor for "int" and "unsigned int",
377  // because otherwise GeometryType(int) would try to call the
378  // generic GeometryType(TopologyType) constructor
379  explicit GeometryType(int dim)
380  : topologyId_(0), dim_(dim), none_(false)
381  {
382  assert(dim < 2);
383  }
384 
387 
389  void makeVertex() {
390  none_ = false;
391  dim_ = 0;
392  topologyId_ = 0;
393  }
394 
396  void makeLine() {
397  none_ = false;
398  dim_ = 1;
399  topologyId_ = 0;
400  }
401 
403  void makeTriangle() {
404  makeSimplex(2);
405  }
406 
408  void makeQuadrilateral() {
409  makeCube(2);
410  }
411 
413  void makeTetrahedron() {
414  makeSimplex(3);
415  }
416 
418  void makePyramid() {
419  none_ = false;
420  dim_ = 3;
421  topologyId_ = b0011;
422  }
423 
425  void makePrism() {
426  none_ = false;
427  dim_ = 3;
428  topologyId_ = b0101; // (1 << (dim_-1)) - 1;
429  }
430 
432  void makeHexahedron() {
433  makeCube(3);
434  }
435 
437  void makeSimplex(unsigned int dim) {
438  none_ = false;
439  dim_ = dim;
440  topologyId_ = 0;
441  }
442 
444  void makeCube(unsigned int dim) {
445  none_ = false;
446  dim_ = dim;
447  topologyId_ = ((dim>1) ? ((1 << dim) - 1) : 0);
448  }
449 
451  void makeNone(unsigned int dim) {
452  none_ = true;
453  dim_ = dim;
454  topologyId_ = 0;
455  }
456 
461  void makeFromVertices(unsigned int dim, unsigned int vertices)
462  {
463  switch (dim)
464  {
465  case 0 :
466  makeVertex();
467  return;
468  case 1 :
469  makeLine();
470  return;
471  case 2 :
472  switch (vertices) {
473  case 3 :
474  makeSimplex(2);
475  return;
476  case 4 :
477  makeCube(2);
478  return;
479  default :
480  DUNE_THROW(NotImplemented, "2d elements with " << vertices << " corners are not supported!");
481  }
482  case 3 :
483  switch (vertices) {
484  case 4 :
485  makeSimplex(3);
486  return;
487  case 5 :
488  makePyramid();
489  return;
490  case 6 :
491  makePrism();
492  return;
493  case 8 :
494  makeCube(3);
495  return;
496  default :
497  DUNE_THROW(NotImplemented, "3d elements with " << vertices << " corners are not supported!");
498  }
499  default :
500  DUNE_THROW(NotImplemented, "makeFromVertices only implemented up to 3d");
501  }
502  }
503 
510  bool isVertex() const {
511  return dim_==0;
512  }
513 
515  bool isLine() const {
516  return dim_==1;
517  }
518 
520  bool isTriangle() const {
521  return ! none_ && dim_==2 && (topologyId_ | 1) == b0001;
522  }
523 
525  bool isQuadrilateral() const {
526  return ! none_ && dim_==2 && (topologyId_ | 1) == b0011;
527  }
528 
530  bool isTetrahedron() const {
531  return ! none_ && dim_==3 && (topologyId_ | 1) == b0001;
532  }
533 
535  bool isPyramid() const {
536  return ! none_ && dim_==3 && (topologyId_ | 1) == b0011;
537  }
538 
540  bool isPrism() const {
541  return ! none_ && dim_==3 && (topologyId_ | 1) == b0101;
542  }
543 
545  bool isHexahedron() const {
546  return ! none_ && dim_==3 && (topologyId_ | 1) == b0111;
547  }
548 
550  bool isSimplex() const {
551  return ! none_ && (topologyId_ | 1) == 1;
552  }
553 
555  bool isCube() const {
556  return ! none_ && ((topologyId_ ^ ((1 << dim_)-1)) >> 1 == 0);
557  }
558 
560  bool isNone() const {
561  return none_;
562  }
563 
565  unsigned int dim() const {
566  return dim_;
567  }
568 
570  unsigned int id() const {
571  return topologyId_;
572  }
573 
579  bool operator==(const GeometryType& other) const {
580  return ( ( none_ == other.none_ )
581  && ( ( none_ == true )
582  || ( ( dim_ == other.dim_ )
583  && ( (topologyId_ >> 1) == (other.topologyId_ >> 1) )
584  )
585  )
586  );
587  }
588 
590  bool operator!=(const GeometryType& other) const {
591  return ! ((*this)==other);
592  }
593 
595  bool operator < (const GeometryType& other) const {
596  return ( ( none_ < other.none_ )
597  || ( !( other.none_ < none_ )
598  && ( ( dim_ < other.dim_ )
599  || ( (other.dim_ == dim_)
600  && ((topologyId_ >> 1) < (other.topologyId_ >> 1) )
601  )
602  )
603  )
604  );
605  }
606  };
607 
609  inline std::ostream& operator<< (std::ostream& s, const GeometryType& a)
610  {
611  if (a.isSimplex())
612  {
613  s << "(simplex, " << a.dim() << ")";
614  return s;
615  }
616  if (a.isCube())
617  {
618  s << "(cube, " << a.dim() << ")";
619  return s;
620  }
621  if (a.isPyramid())
622  {
623  s << "(pyramid, 3)";
624  return s;
625  }
626  if (a.isPrism())
627  {
628  s << "(prism, 3)";
629  return s;
630  }
631  if (a.isNone())
632  {
633  s << "(none, " << a.dim() << ")";
634  return s;
635  }
636  s << "(other [" << a.id() << "], " << a.dim() << ")";
637  return s;
638  }
639 
641  inline std::ostream& operator<< (std::ostream& s, GeometryType::BasicType type)
642  {
643  switch (type) {
644  case GeometryType::simplex :
645  s << "simplex";
646  break;
647  case GeometryType::cube :
648  s << "cube";
649  break;
650  case GeometryType::pyramid :
651  s << "pyramid";
652  break;
653  case GeometryType::prism :
654  s << "prism";
655  break;
656  case GeometryType::extended :
657  s << "other";
658  case GeometryType::none :
659  s << "none";
660  break;
661  default :
662  DUNE_THROW(Exception, "invalid GeometryType::BasicType");
663  }
664  return s;
665  }
666 
667 } // namespace Dune
668 
669 #endif // DUNE_GEOMETRY_TYPE_HH
A few common exception classes.
Dune namespace.
Definition: alignment.hh:11
Traits for type conversions and type information.
Definition of the DUNE_UNUSED macro for the case that config.h is not available.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 8, 22:30, 2024)