Dune Core Modules (2.5.0)

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
18namespace 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.111.3 (Nov 23, 23:29, 2024)