Dune Core Modules (2.9.0)

twists.hh
1#ifndef DUNE_ALUGRID_COMMON_TWISTS_HH
2#define DUNE_ALUGRID_COMMON_TWISTS_HH
3
5
7#include <dune/geometry/referenceelements.hh>
8
10
11namespace Dune
12{
13
14 // Internal Forward Declarations
15 // -----------------------------
16
17 template< int corners, int dim >
18 class ALUTwist;
19
20 template< int corners, int dim >
21 class ALUTwists;
22
23
24
25 // ALUTwistIterator
26 // ----------------
27
28 template< class Twist >
29 struct ALUTwistIterator
30 {
31 typedef std::input_iterator_tag iterator_category;
32 typedef Twist value_type;
33 typedef int difference_type;
34 typedef Twist* pointer;
35 typedef Twist& reference;
36
37 explicit ALUTwistIterator ( Twist twist ) : twist_( twist ) {}
38
39 const Twist &operator* () const { return twist_; }
40 const Twist *operator-> () const { return &twist_; }
41
42 bool operator== ( const ALUTwistIterator &other ) const { return (twist_ == other.twist_); }
43 bool operator!= ( const ALUTwistIterator &other ) const { return (twist_ != other.twist_); }
44
45 ALUTwistIterator &operator++ () { ++twist_.aluTwist_; return *this; }
46 ALUTwistIterator operator++ ( int ) { ALUTwistIterator other( *this ); ++(*this); return other; }
47
48 private:
49 Twist twist_;
50 };
51
52
53
54 // ALUTwist for dimension 2
55 // ------------------------
56
57 template< int corners >
58 class ALUTwist< corners, 2 >
59 {
60 typedef ALUTwist< corners, 2 > Twist;
61
62 friend struct ALUTwistIterator< Twist >;
63
64 template< class ctype >
65 struct CoordVector
66 {
67 // type of container for reference elements
68 typedef ReferenceElements< ctype, 2 > ReferenceElementContainerType;
69
70 // type of reference element
71 typedef std::decay_t< decltype( ReferenceElementContainerType::general( std::declval< const Dune::GeometryType & >() ) ) > ReferenceElementType;
72
73 CoordVector ( const Twist &twist )
74 : twist_( twist ),
75 refElement_( ReferenceElements< ctype, 2 >::general( twist.type() ) )
76 {}
77
78 const FieldVector< ctype, 2 > operator[] ( int i ) const { return refElement().position( twist_( i ), 2 ); }
79
80 const ReferenceElementType& refElement () const { return refElement_; }
81
82 private:
83 const Twist &twist_;
84 const ReferenceElementType& refElement_;
85 };
86
87 public:
89 static const int dimension = 2;
90
97 ALUTwist () : aluTwist_( 0 ) {}
98
99 explicit ALUTwist ( GeometryType ) : aluTwist_( 0 ) {}
100
101 explicit ALUTwist ( int aluTwist ) : aluTwist_( aluTwist ) {}
102
103 ALUTwist ( int origin, bool positive )
104 : aluTwist_( positive ? origin : (origin + corners - 1) % corners - corners )
105 {}
106
115 ALUTwist ( const ALUTwist &other ) : aluTwist_( other.aluTwist_ ) {}
116
118 ALUTwist &operator= ( const ALUTwist &other ) { aluTwist_ = other.aluTwist_; return *this; }
119
128 ALUTwist operator* ( const ALUTwist &other ) const
129 {
130 return ALUTwist( apply( other.apply( 0 ) ), !(positive() ^ other.positive()) );
131 }
132
134 ALUTwist operator/ ( const ALUTwist &other ) const { return (*this * other.inverse()); }
135
137 ALUTwist &operator*= ( const ALUTwist &other ) { return (*this = (*this) * other); }
138
140 ALUTwist &operator/= ( const ALUTwist &other ) { return (*this = (*this) / other); }
141
143 ALUTwist inverse () const { return ALUTwist( positive() ? (corners - aluTwist_) % corners : aluTwist_ ); }
144
153 bool operator== ( const ALUTwist &other ) const { return (aluTwist_ == other.aluTwist_); }
154
156 bool operator!= ( const ALUTwist &other ) const { return (aluTwist_ != other.aluTwist_); }
157
166 GeometryType type () const
167 {
168 if( corners == 3 )
169 return GeometryTypes::simplex(dimension);
170 else
171 return GeometryTypes::cube(dimension);
172 }
173
181 int operator() ( int i ) const { return aluVertex2duneVertex( apply( duneVertex2aluVertex( i ) ) ); }
182
183 int operator() ( int i, int codim ) const { return alu2dune( apply( dune2alu( i, codim ), codim ), codim ); }
184
193 template< class ctype >
194 operator AffineGeometry< ctype, dimension, dimension > () const
195 {
196 const CoordVector< ctype > coordVector( *this );
197 return AffineGeometry< ctype, dimension, dimension >( coordVector.refElement(), coordVector );
198 }
199
201 bool positive () const { return (aluTwist_ >= 0); }
202
205 // non-interface methods
206
207 operator int () const { return aluTwist_; }
208
209 // apply twist in ALU numbering
210 int apply ( int i ) const { return ((positive() ? i : 2*corners + 1 - i) + aluTwist_) % corners; }
211 int apply ( int i, int codim ) const { return (codim == 0 ? i : (codim == 1 ? applyEdge( i ) : apply( i ))); }
212
213 private:
214 int applyEdge ( int i ) const { return ((positive() ? i : 2*corners - i) + aluTwist_) % corners; }
215
216
217 static int aluEdge2duneEdge ( int i ) { return ((corners == 3) ? (3 - i) % 3 : (6 - swap23( i )) % 4); }
218 static int duneEdge2aluEdge ( int i ) { return ((corners == 3) ? (3 - i) % 3 : swap23( (6 - i) % 4 )); }
219
220 static int aluVertex2duneVertex ( int i ) { return ((corners == 3) ? i : swap23( i )); }
221 static int duneVertex2aluVertex ( int i ) { return ((corners == 3) ? i : swap23( i )); }
222
223 static int alu2dune ( int i, int codim ) { return (codim == 0 ? i : (codim == 1 ? aluEdge2duneEdge( i ) : aluVertex2duneVertex( i ))); }
224 static int dune2alu ( int i, int codim ) { return (codim == 0 ? i : (codim == 1 ? duneEdge2aluEdge( i ) : aluVertex2duneVertex( i ))); }
225
226 static int swap23 ( int i ) { return i ^ (i >> 1); }
227
228 int aluTwist_;
229 };
230
231
232
233 // ALUTwist for dimension 1
234 // ------------------------
235
236 template<>
237 class ALUTwist< 2, 1 >
238 {
239 typedef ALUTwist< 2, 1 > Twist;
240
241 friend struct ALUTwistIterator< Twist >;
242
243 template< class ctype >
244 struct CoordVector
245 {
246 CoordVector ( const Twist &twist ) : twist_( twist ) {}
247
248 FieldVector< ctype, 1 > operator[] ( int i ) const { return FieldVector< ctype, 1 >( ctype( twist_( i ) ) ); }
249
250 private:
251 const Twist &twist_;
252 };
253
254 public:
256 static const int dimension = 1;
257
264 ALUTwist () : aluTwist_( 0 ) {}
265
266 explicit ALUTwist ( GeometryType ) : aluTwist_( 0 ) {}
267
268 explicit ALUTwist ( int aluTwist ) : aluTwist_( aluTwist ) {}
269
270 explicit ALUTwist ( bool positive ) : aluTwist_( positive ) {}
271
280 ALUTwist ( const ALUTwist &other ) : aluTwist_( other.aluTwist_ ) {}
281
283 ALUTwist &operator= ( const ALUTwist &other ) { aluTwist_ = other.aluTwist_; return *this; }
284
293 ALUTwist operator* ( const ALUTwist &other ) const { return ALUTwist( aluTwist_ ^ other.aluTwist_ ); }
294
296 ALUTwist operator/ ( const ALUTwist &other ) const { return (*this * other.inverse()); }
297
299 ALUTwist &operator*= ( const ALUTwist &other ) { return (*this = (*this) * other); }
300
302 ALUTwist &operator/= ( const ALUTwist &other ) { return (*this = (*this) / other); }
303
305 ALUTwist inverse () const { return *this; }
306
315 bool operator== ( const ALUTwist &other ) const { return (aluTwist_ == other.aluTwist_); }
316
318 bool operator!= ( const ALUTwist &other ) const { return (aluTwist_ != other.aluTwist_); }
319
328 GeometryType type () const { return GeometryTypes::cube(dimension); }
329
337 int operator() ( int i ) const { return (i ^ aluTwist_); }
338
339 int operator() ( int i, int codim ) const { return (codim == 0 ? i : (*this)( i )); }
340
349 template< class ctype >
350 operator AffineGeometry< ctype, dimension, dimension > () const
351 {
352 const CoordVector< ctype > coordVector( *this );
353 return AffineGeometry< ctype, dimension, dimension >( type(), coordVector );
354 }
355
357 bool positive () const { return (aluTwist_ == 0); }
358
361 operator int () const { return aluTwist_; }
362
363 private:
364 int aluTwist_;
365 };
366
367
368
369
370 // ALUTwists for dimension 2
371 // -------------------------
372
373 template< int corners >
374 class ALUTwists< corners, 2 >
375 {
376 public:
378 static const int dimension = 2;
379
380 typedef ALUTwist< corners, 2 > Twist;
381
382 typedef ALUTwistIterator< Twist > Iterator;
383
385 GeometryType type () const
386 {
387 if( corners == 3 )
388 return GeometryTypes::simplex(dimension);
389 else
390 return GeometryTypes::cube(dimension);
391 }
392
394 std::size_t size () const { return 2*corners; }
395
397 std::size_t index ( const Twist &twist ) const { return static_cast< int >( twist ) + corners; }
398
405 Iterator begin () const { return Iterator( Twist( -corners ) ); }
406
408 Iterator end () const { return Iterator( Twist( corners ) ); }
409
410 template< class Permutation >
411 Iterator find ( const Permutation &permutation ) const
412 {
413 // calculate twist (if permutation is a valid twist)
414 const int origin = duneVertex2aluVertex( permutation( aluVertex2duneVertex( 0 ) ) );
415 const int next = duneVertex2aluVertex( permutation( aluVertex2duneVertex( 1 ) ) );
416 const Twist twist( origin, (origin + 1) % corners == next );
417
418 // check twist equals permutation (i.e., permutation is valid)
419 for( int i = 0; i < corners; ++i )
420 {
421 if( twist( i ) != permutation( i ) )
422 return end();
423 }
424 return Iterator( twist );
425 }
426
429 private:
430 static int aluVertex2duneVertex ( int i ) { return ((corners == 3) ? i : swap23( i )); }
431 static int duneVertex2aluVertex ( int i ) { return ((corners == 3) ? i : swap23( i )); }
432
433 static int swap23 ( int i ) { return i ^ (i >> 1); }
434 };
435
436
437
438 // ALUTwists for dimension 1
439 // -------------------------
440
441 template<>
442 class ALUTwists< 2, 1 >
443 {
444 public:
446 static const int dimension = 1;
447
448 typedef ALUTwist< 2, 1 > Twist;
449
450 typedef ALUTwistIterator< Twist > Iterator;
451
453 GeometryType type () const { return GeometryTypes::cube(dimension); }
454
456 std::size_t size () const { return 2; }
457
459 std::size_t index ( const Twist &twist ) const { return static_cast< int >( twist ); }
460
467 Iterator begin () const { return Iterator( Twist( 0 ) ); }
468
470 Iterator end () const { return Iterator( Twist( int( size() ) ) ); }
471
472 template< class Permutation >
473 Iterator find ( const Permutation &permutation ) const { return Iterator( Twist( permutation( 0 ) ) ); }
474
476 };
477
478
479
480 // TrivialTwist
481 // ------------
482
483 template< unsigned int topologyId, int dim >
484 struct TrivialTwist
485 {
487 static const int dimension = dim;
488
495 TrivialTwist () {}
496
497 explicit TrivialTwist ( GeometryType ) {}
498
507 TrivialTwist ( const TrivialTwist & ) {}
508
510 TrivialTwist &operator= ( const TrivialTwist & ) { return *this; }
511
520 TrivialTwist operator* ( const TrivialTwist & ) const { return *this; }
521
523 TrivialTwist operator/ ( const TrivialTwist & ) const { return *this; }
524
526 TrivialTwist &operator*= ( const TrivialTwist & ) const { return *this; }
527
529 TrivialTwist &operator/= ( const TrivialTwist & ) const { return *this; }
530
532 TrivialTwist inverse () const { return *this; }
533
542 bool operator== ( const TrivialTwist & ) const { return true; }
543
545 bool operator!= ( const TrivialTwist & ) const { return false; }
546
555 GeometryType type () const { return GeometryType( topologyId, dim ); }
556
564 int operator() ( int i ) const { return i; }
565
566 int operator() ( int i, int codim ) const { return i; }
567
576 template< class ctype >
577 operator AffineGeometry< ctype, dimension, dimension > () const
578 {
579 return ReferenceElements< ctype, dimension >::general( type() ).template geometry< 0 >( 0 );
580 }
581
583 bool positive () const { return true; }
584
587 operator int () const { return 0; }
588 };
589
590
591
592 // TrivialTwists
593 // -------------
594
595 template< unsigned int topologyId, int dim >
596 struct TrivialTwists
597 : private TrivialTwist< topologyId, dim >
598 {
600 static const int dimension = dim;
601
602 typedef TrivialTwist< topologyId, dim > Twist;
603
604 typedef const Twist *Iterator;
605
606 TrivialTwists () {}
607 explicit TrivialTwists ( GeometryType type ) {}
608
610 GeometryType type () const { return twist().type(); }
611
613 static std::size_t size () { return 1; }
614
616 static std::size_t index ( const Twist & ) { return 0; }
617
624 Iterator begin () const { return &twist(); }
625
627 Iterator end () const { return begin() + size(); }
628
629 template< class Permutation >
630 Iterator find ( const Permutation &permutation ) const // noexcept
631 {
632 // check whether permutation is the identity (i.e., permutation is valid)
633 const int corners = ReferenceElements< double, dimension >::general( type() ).size( dimension );
634 for( int i = 0; i < corners; ++i )
635 {
636 if( i != permutation( i ) )
637 return end();
638 }
639 return begin();
640 }
641
644 private:
645 const Twist &twist () const { return *this; }
646 };
647
648} // namespace Dune
649
650#endif // #ifndef DUNE_ALUGRID_COMMON_TWISTS_HH
An implementation of the Geometry interface for affine geometries.
Capabilities for ALUGrid.
GeometryType
Type representing VTK's entity geometry types.
Definition: common.hh:132
Implements a vector constructed from a given type representing a field and a compile-time given size.
constexpr GeometryType cube(unsigned int dim)
Returns a GeometryType representing a hypercube of dimension dim.
Definition: type.hh:472
constexpr GeometryType simplex(unsigned int dim)
Returns a GeometryType representing a simplex of dimension dim.
Definition: type.hh:463
EnableIfInterOperable< T1, T2, bool >::type operator==(const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for equality.
Definition: iteratorfacades.hh:237
EnableIfInterOperable< T1, T2, bool >::type operator!=(const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for inequality.
Definition: iteratorfacades.hh:259
Dune namespace.
Definition: alignedallocator.hh:13
static const ReferenceElement & general(const GeometryType &type)
get general reference elements
Definition: referenceelements.hh:198
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Dec 21, 23:30, 2024)