dune-alugrid  3.0.0
twists.hh
Go to the documentation of this file.
1 #ifndef DUNE_ALUGRID_COMMON_TWISTS_HH
2 #define DUNE_ALUGRID_COMMON_TWISTS_HH
3 
4 #include <iterator>
5 
6 #include <dune/common/fvector.hh>
7 
8 #include <dune/geometry/affinegeometry.hh>
9 #include <dune/geometry/referenceelements.hh>
10 #include <dune/geometry/type.hh>
11 
12 namespace Dune
13 {
14 
15  // Internal Forward Declarations
16  // -----------------------------
17 
18  template< int corners, int dim >
19  class ALUTwist;
20 
21  template< int corners, int dim >
22  class ALUTwists;
23 
24 
25 
26  // ALUTwistIterator
27  // ----------------
28 
29  template< class Twist >
31  : public std::iterator< std::input_iterator_tag, Twist, int >
32  {
33  explicit ALUTwistIterator ( Twist twist ) : twist_( twist ) {}
34 
35  const Twist &operator* () const { return twist_; }
36  const Twist *operator-> () const { return &twist_; }
37 
38  bool operator== ( const ALUTwistIterator &other ) const { return (twist_ == other.twist_); }
39  bool operator!= ( const ALUTwistIterator &other ) const { return (twist_ != other.twist_); }
40 
41  ALUTwistIterator &operator++ () { ++twist_.aluTwist_; return *this; }
42  ALUTwistIterator operator++ ( int ) { ALUTwistIterator other( *this ); ++(*this); return other; }
43 
44  private:
45  Twist twist_;
46  };
47 
48 
49 
50  // ALUTwist for dimension 2
51  // ------------------------
52 
53  template< int corners >
54  class ALUTwist< corners, 2 >
55  {
57 
58  friend struct ALUTwistIterator< Twist >;
59 
60  template< class ctype >
61  struct CoordVector
62  {
63  CoordVector ( const Twist &twist )
64  : twist_( twist ),
65  refElement_( ReferenceElements< ctype, 2 >::general( twist.type() ) )
66  {}
67 
68  const FieldVector< ctype, 2 > &operator[] ( int i ) const { return refElement().position( twist_( i ), 2 ); }
69 
70  const ReferenceElement< ctype, 2 > &refElement () const { return refElement_; }
71 
72  private:
73  const Twist &twist_;
74  const ReferenceElement< ctype, 2 > &refElement_;
75  };
76 
77  public:
79  static const int dimension = 2;
80 
87  ALUTwist () : aluTwist_( 0 ) {}
88 
89  explicit ALUTwist ( GeometryType ) : aluTwist_( 0 ) {}
90 
91  explicit ALUTwist ( int aluTwist ) : aluTwist_( aluTwist ) {}
92 
93  ALUTwist ( int origin, bool positive )
94  : aluTwist_( positive ? origin : (origin + corners - 1) % corners - corners )
95  {}
96 
105  ALUTwist ( const ALUTwist &other ) : aluTwist_( other.aluTwist_ ) {}
106 
108  ALUTwist &operator= ( const ALUTwist &other ) { aluTwist_ = other.aluTwist_; return *this; }
109 
118  ALUTwist operator* ( const ALUTwist &other ) const
119  {
120  return ALUTwist( apply( other.apply( 0 ) ), !(positive() ^ other.positive()) );
121  }
122 
124  ALUTwist operator/ ( const ALUTwist &other ) const { return (*this * other.inverse()); }
125 
127  ALUTwist &operator*= ( const ALUTwist &other ) { return (*this = (*this) * other); }
128 
130  ALUTwist &operator/= ( const ALUTwist &other ) { return (*this = (*this) / other); }
131 
133  ALUTwist inverse () const { return ALUTwist( positive() ? (corners - aluTwist_) % corners : aluTwist_ ); }
134 
143  bool operator== ( const ALUTwist &other ) const { return (aluTwist_ == other.aluTwist_); }
144 
146  bool operator!= ( const ALUTwist &other ) const { return (aluTwist_ != other.aluTwist_); }
147 
156  GeometryType type () const
157  {
158  if( corners == 3 )
159  return GeometryType( typename GenericGeometry::SimplexTopology< dimension >::type() );
160  else
161  return GeometryType( typename GenericGeometry::CubeTopology< dimension >::type() );
162  }
163 
171  int operator() ( int i ) const { return aluVertex2duneVertex( apply( duneVertex2aluVertex( i ) ) ); }
172 
173  int operator() ( int i, int codim ) const { return alu2dune( apply( dune2alu( i, codim ), codim ), codim ); }
174 
183  template< class ctype >
184  operator AffineGeometry< ctype, dimension, dimension > () const
185  {
186  const CoordVector< ctype > coordVector( *this );
187  return AffineGeometry< ctype, dimension, dimension >( coordVector.refElement(), coordVector );
188  }
189 
191  bool positive () const { return (aluTwist_ >= 0); }
192 
195  // non-interface methods
196 
197  operator int () const { return aluTwist_; }
198 
199  // apply twist in ALU numbering
200  int apply ( int i ) const { return ((positive() ? i : 2*corners + 1 - i) + aluTwist_) % corners; }
201  int apply ( int i, int codim ) const { return (codim == 0 ? i : (codim == 1 ? applyEdge( i ) : apply( i ))); }
202 
203  private:
204  int applyEdge ( int i ) const { return ((positive() ? i : 2*corners - i) + aluTwist_) % corners; }
205 
206 
207  static int aluEdge2duneEdge ( int i ) { return ((corners == 3) ? (3 - i) % 3 : (6 - swap23( i )) % 4); }
208  static int duneEdge2aluEdge ( int i ) { return ((corners == 3) ? (3 - i) % 3 : swap23( (6 - i) % 4 )); }
209 
210  static int aluVertex2duneVertex ( int i ) { return ((corners == 3) ? i : swap23( i )); }
211  static int duneVertex2aluVertex ( int i ) { return ((corners == 3) ? i : swap23( i )); }
212 
213  static int alu2dune ( int i, int codim ) { return (codim == 0 ? i : (codim == 1 ? aluEdge2duneEdge( i ) : aluVertex2duneVertex( i ))); }
214  static int dune2alu ( int i, int codim ) { return (codim == 0 ? i : (codim == 1 ? duneEdge2aluEdge( i ) : aluVertex2duneVertex( i ))); }
215 
216  static int swap23 ( int i ) { return i ^ (i >> 1); }
217 
218  int aluTwist_;
219  };
220 
221 
222 
223  // ALUTwist for dimension 1
224  // ------------------------
225 
226  template<>
227  class ALUTwist< 2, 1 >
228  {
229  typedef ALUTwist< 2, 1 > Twist;
230 
231  friend struct ALUTwistIterator< Twist >;
232 
233  template< class ctype >
234  struct CoordVector
235  {
236  CoordVector ( const Twist &twist ) : twist_( twist ) {}
237 
238  FieldVector< ctype, 1 > operator[] ( int i ) const { return FieldVector< ctype, 1 >( ctype( twist_( i ) ) ); }
239 
240  private:
241  const Twist &twist_;
242  };
243 
244  public:
246  static const int dimension = 1;
247 
254  ALUTwist () : aluTwist_( 0 ) {}
255 
256  explicit ALUTwist ( GeometryType ) : aluTwist_( 0 ) {}
257 
258  explicit ALUTwist ( int aluTwist ) : aluTwist_( aluTwist ) {}
259 
260  explicit ALUTwist ( bool positive ) : aluTwist_( positive ) {}
261 
270  ALUTwist ( const ALUTwist &other ) : aluTwist_( other.aluTwist_ ) {}
271 
273  ALUTwist &operator= ( const ALUTwist &other ) { aluTwist_ = other.aluTwist_; return *this; }
274 
283  ALUTwist operator* ( const ALUTwist &other ) const { return ALUTwist( aluTwist_ ^ other.aluTwist_ ); }
284 
286  ALUTwist operator/ ( const ALUTwist &other ) const { return (*this * other.inverse()); }
287 
289  ALUTwist &operator*= ( const ALUTwist &other ) { return (*this = (*this) * other); }
290 
292  ALUTwist &operator/= ( const ALUTwist &other ) { return (*this = (*this) / other); }
293 
295  ALUTwist inverse () const { return *this; }
296 
305  bool operator== ( const ALUTwist &other ) const { return (aluTwist_ == other.aluTwist_); }
306 
308  bool operator!= ( const ALUTwist &other ) const { return (aluTwist_ != other.aluTwist_); }
309 
318  GeometryType type () const { return GeometryType( GenericGeometry::CubeTopology< dimension >::type() ); }
319 
327  int operator() ( int i ) const { return (i ^ aluTwist_); }
328 
329  int operator() ( int i, int codim ) const { return (codim == 0 ? i : (*this)( i )); }
330 
339  template< class ctype >
340  operator AffineGeometry< ctype, dimension, dimension > () const
341  {
342  const CoordVector< ctype > coordVector( *this );
343  return AffineGeometry< ctype, dimension, dimension >( type(), coordVector );
344  }
345 
347  bool positive () const { return (aluTwist_ == 0); }
348 
351  operator int () const { return aluTwist_; }
352 
353  private:
354  int aluTwist_;
355  };
356 
357 
358 
359 
360  // ALUTwists for dimension 2
361  // -------------------------
362 
363  template< int corners >
364  class ALUTwists< corners, 2 >
365  {
366  public:
368  static const int dimension = 2;
369 
371 
373 
375  GeometryType type () const
376  {
377  if( corners == 3 )
378  return GeometryType( typename GenericGeometry::SimplexTopology< dimension >::type() );
379  else
380  return GeometryType( typename GenericGeometry::CubeTopology< dimension >::type() );
381  }
382 
384  std::size_t size () const { return 2*corners; }
385 
387  std::size_t index ( const Twist &twist ) const { return static_cast< int >( twist ) + corners; }
388 
395  Iterator begin () const { return Iterator( Twist( -corners ) ); }
396 
398  Iterator end () const { return Iterator( Twist( corners ) ); }
399 
400  template< class Permutation >
401  Iterator find ( const Permutation &permutation ) const
402  {
403  // calculate twist (if permutation is a valid twist)
404  const int origin = duneVertex2aluVertex( permutation( aluVertex2duneVertex( 0 ) ) );
405  const int next = duneVertex2aluVertex( permutation( aluVertex2duneVertex( 1 ) ) );
406  const Twist twist( origin, (origin + 1) % corners == next );
407 
408  // check twist equals permutation (i.e., permutation is valid)
409  for( int i = 0; i < corners; ++i )
410  {
411  if( twist( i ) != permutation( i ) )
412  return end();
413  }
414  return Iterator( twist );
415  }
416 
419  private:
420  static int aluVertex2duneVertex ( int i ) { return ((corners == 3) ? i : swap23( i )); }
421  static int duneVertex2aluVertex ( int i ) { return ((corners == 3) ? i : swap23( i )); }
422 
423  static int swap23 ( int i ) { return i ^ (i >> 1); }
424  };
425 
426 
427 
428  // ALUTwists for dimension 1
429  // -------------------------
430 
431  template<>
432  class ALUTwists< 2, 1 >
433  {
434  public:
436  static const int dimension = 1;
437 
439 
441 
443  GeometryType type () const { return GeometryType( GenericGeometry::CubeTopology< dimension >::type() ); }
444 
446  std::size_t size () const { return 2; }
447 
449  std::size_t index ( const Twist &twist ) const { return static_cast< int >( twist ); }
450 
457  Iterator begin () const { return Iterator( Twist( 0 ) ); }
458 
460  Iterator end () const { return Iterator( Twist( int( size() ) ) ); }
461 
462  template< class Permutation >
463  Iterator find ( const Permutation &permutation ) const { return Iterator( Twist( permutation( 0 ) ) ); }
464 
466  };
467 
468 
469 
470  // TrivialTwist
471  // ------------
472 
473  template< unsigned int topologyId, int dim >
475  {
477  static const int dimension = dim;
478 
486 
487  explicit TrivialTwist ( GeometryType ) {}
488 
497  TrivialTwist ( const TrivialTwist & ) {}
498 
500  TrivialTwist &operator= ( const TrivialTwist & ) { return *this; }
501 
510  TrivialTwist operator* ( const TrivialTwist & ) const { return *this; }
511 
513  TrivialTwist operator/ ( const TrivialTwist & ) const { return *this; }
514 
516  TrivialTwist &operator*= ( const TrivialTwist & ) const { return *this; }
517 
519  TrivialTwist &operator/= ( const TrivialTwist & ) const { return *this; }
520 
522  TrivialTwist inverse () const { return *this; }
523 
532  bool operator== ( const TrivialTwist & ) const { return true; }
533 
535  bool operator!= ( const TrivialTwist & ) const { return false; }
536 
545  GeometryType type () const { return GeometryType( topologyId, dim ); }
546 
554  int operator() ( int i ) const { return i; }
555 
556  int operator() ( int i, int codim ) const { return i; }
557 
566  template< class ctype >
567  operator AffineGeometry< ctype, dimension, dimension > () const
568  {
569  return ReferenceElements< ctype, dimension >::general( type() ).template geometry< 0 >( 0 );
570  }
571 
573  bool positive () const { return true; }
574 
577  operator int () const { return 0; }
578  };
579 
580 
581 
582  // TrivialTwists
583  // -------------
584 
585  template< unsigned int topologyId, int dim >
587  : private TrivialTwist< topologyId, dim >
588  {
590  static const int dimension = dim;
591 
593 
594  typedef const Twist *Iterator;
595 
597  explicit TrivialTwists ( GeometryType type ) {}
598 
600  GeometryType type () const { return twist().type(); }
601 
603  static std::size_t size () { return 1; }
604 
606  static std::size_t index ( const Twist & ) { return 0; }
607 
614  Iterator begin () const { return &twist(); }
615 
617  Iterator end () const { return begin() + size(); }
618 
619  template< class Permutation >
620  Iterator find ( const Permutation &permutation ) const // noexcept
621  {
622  // check whether permutation is the identity (i.e., permutation is valid)
623  const int corners = ReferenceElements< double, dimension >::general( type() ).size( dimension );
624  for( int i = 0; i < corners; ++i )
625  {
626  if( i != permutation( i ) )
627  return end();
628  }
629  return begin();
630  }
631 
634  private:
635  const Twist &twist () const { return *this; }
636  };
637 
638 } // namespace Dune
639 
640 #endif // #ifndef DUNE_ALUGRID_COMMON_TWISTS_HH
Dune::TrivialTwist::operator/=
TrivialTwist & operator/=(const TrivialTwist &) const
composition with inverse
Definition: twists.hh:519
Dune::TrivialTwist::inverse
TrivialTwist inverse() const
obtain inverse
Definition: twists.hh:522
Dune::TrivialTwists
Definition: twists.hh:586
Dune::TrivialTwist::operator!=
bool operator!=(const TrivialTwist &) const
check for inequality
Definition: twists.hh:535
Dune::ALUTwistIterator::operator!=
bool operator!=(const ALUTwistIterator &other) const
Definition: twists.hh:39
Dune::TrivialTwist::TrivialTwist
TrivialTwist()
default constructor; results in identity twist
Definition: twists.hh:485
Dune::ALUTwist< 2, 1 >
Definition: twists.hh:227
Dune::ALUTwists< 2, 1 >::Twist
ALUTwist< 2, 1 > Twist
Definition: twists.hh:438
Dune::ALUTwistIterator::operator++
ALUTwistIterator & operator++()
Definition: twists.hh:41
Dune::ALUTwists< 2, 1 >::find
Iterator find(const Permutation &permutation) const
Definition: twists.hh:463
Dune::ALUTwists< corners, 2 >::find
Iterator find(const Permutation &permutation) const
Definition: twists.hh:401
Dune::ALUTwistIterator::operator->
const Twist * operator->() const
Definition: twists.hh:36
Dune::ALUTwist< corners, 2 >
Definition: twists.hh:54
Dune::TrivialTwists::index
static std::size_t index(const Twist &)
obtain index of a given twist
Definition: twists.hh:606
Dune::ALUTwists< 2, 1 >::size
std::size_t size() const
obtain number of twists in the group
Definition: twists.hh:446
Dune::TrivialTwist::positive
bool positive() const
equivalent to
Definition: twists.hh:573
Dune::ALUTwist< 2, 1 >::ALUTwist
ALUTwist(const ALUTwist &other)
copy constructor
Definition: twists.hh:270
Dune::ALUTwist< 2, 1 >::positive
bool positive() const
equivalent to
Definition: twists.hh:347
Dune::ALUTwists< 2, 1 >::Iterator
ALUTwistIterator< Twist > Iterator
Definition: twists.hh:440
Dune::ALUTwistIterator
Definition: twists.hh:30
Dune::TrivialTwists::end
Iterator end() const
obtain end iterator
Definition: twists.hh:617
Dune::TrivialTwists::TrivialTwists
TrivialTwists()
Definition: twists.hh:596
Dune::TrivialTwist::TrivialTwist
TrivialTwist(GeometryType)
Definition: twists.hh:487
Dune::ALUTwistIterator::operator*
const Twist & operator*() const
Definition: twists.hh:35
Dune::ALUTwist< 2, 1 >::ALUTwist
ALUTwist()
default constructor; results in identity twist
Definition: twists.hh:254
Dune::ALUTwist< 2, 1 >::ALUTwist
ALUTwist(bool positive)
Definition: twists.hh:260
Dune::TrivialTwist::operator()
int operator()(int i) const
map i-th corner
Definition: twists.hh:554
Dune::TrivialTwist::TrivialTwist
TrivialTwist(const TrivialTwist &)
copy constructor
Definition: twists.hh:497
Dune::TrivialTwists::Twist
TrivialTwist< topologyId, dim > Twist
Definition: twists.hh:592
Dune::ALUTwist< corners, 2 >::type
GeometryType type() const
Topological Corner Mapping.
Definition: twists.hh:156
Dune::ALUTwist< 2, 1 >::ALUTwist
ALUTwist(int aluTwist)
Definition: twists.hh:258
Dune::ALUTwists< 2, 1 >::begin
Iterator begin() const
obtain begin iterator
Definition: twists.hh:457
Dune::ALUTwist
Definition: twists.hh:19
Dune::ALUTwist< corners, 2 >::ALUTwist
ALUTwist()
default constructor; results in identity twist
Definition: twists.hh:87
Dune::ALUTwists< corners, 2 >::Twist
ALUTwist< corners, 2 > Twist
Definition: twists.hh:370
Dune::ALUTwists< corners, 2 >::end
Iterator end() const
obtain end iterator
Definition: twists.hh:398
Dune::ALUTwists< corners, 2 >::type
GeometryType type() const
obtain type of reference element
Definition: twists.hh:375
Dune::ALUTwist< corners, 2 >::ALUTwist
ALUTwist(const ALUTwist &other)
copy constructor
Definition: twists.hh:105
Dune::ALUTwist< 2, 1 >::type
GeometryType type() const
Topological Corner Mapping.
Definition: twists.hh:318
Dune::ALUTwists< 2, 1 >::type
GeometryType type() const
obtain type of reference element
Definition: twists.hh:443
Dune::TrivialTwist::operator*
TrivialTwist operator*(const TrivialTwist &) const
composition
Definition: twists.hh:510
Dune::TrivialTwist
Definition: twists.hh:474
Dune::ALUTwist< corners, 2 >::ALUTwist
ALUTwist(GeometryType)
Definition: twists.hh:89
Dune::ALUTwist< corners, 2 >::apply
int apply(int i, int codim) const
Definition: twists.hh:201
Dune::TrivialTwists::size
static std::size_t size()
obtain number of twists in the group
Definition: twists.hh:603
Dune::ALUTwists< corners, 2 >::Iterator
ALUTwistIterator< Twist > Iterator
Definition: twists.hh:372
Dune::ALUTwists< 2, 1 >::end
Iterator end() const
obtain end iterator
Definition: twists.hh:460
Dune::ALUTwists< corners, 2 >::begin
Iterator begin() const
obtain begin iterator
Definition: twists.hh:395
Dune::TrivialTwist::operator==
bool operator==(const TrivialTwist &) const
Comparison.
Definition: twists.hh:532
Dune::ALUTwist< corners, 2 >::ALUTwist
ALUTwist(int origin, bool positive)
Definition: twists.hh:93
Dune::TrivialTwist::operator=
TrivialTwist & operator=(const TrivialTwist &)
assignment operator
Definition: twists.hh:500
Dune::ALUTwist< corners, 2 >::apply
int apply(int i) const
Definition: twists.hh:200
Dune::ALUTwists< 2, 1 >::index
std::size_t index(const Twist &twist) const
obtain index of a given twist
Definition: twists.hh:449
Dune::ALUTwists< corners, 2 >::index
std::size_t index(const Twist &twist) const
obtain index of a given twist
Definition: twists.hh:387
Dune::TrivialTwists::Iterator
const typedef Twist * Iterator
Definition: twists.hh:594
Dune::TrivialTwists::TrivialTwists
TrivialTwists(GeometryType type)
Definition: twists.hh:597
Dune::ALUTwist< corners, 2 >::ALUTwist
ALUTwist(int aluTwist)
Definition: twists.hh:91
Dune::TrivialTwists::find
Iterator find(const Permutation &permutation) const
Definition: twists.hh:620
Dune::TrivialTwist::type
GeometryType type() const
Topological Corner Mapping.
Definition: twists.hh:545
Dune::ALUTwist< 2, 1 >::inverse
ALUTwist inverse() const
obtain inverse
Definition: twists.hh:295
Dune::TrivialTwists::dimension
static const int dimension
dimension
Definition: twists.hh:590
Dune::TrivialTwist::operator*=
TrivialTwist & operator*=(const TrivialTwist &) const
composition
Definition: twists.hh:516
Dune::TrivialTwists::type
GeometryType type() const
obtain type of reference element
Definition: twists.hh:600
Dune::ALUTwistIterator::operator==
bool operator==(const ALUTwistIterator &other) const
Definition: twists.hh:38
Dune::TrivialTwist::operator/
TrivialTwist operator/(const TrivialTwist &) const
composition with inverse
Definition: twists.hh:513
Dune::ALUTwist< 2, 1 >::ALUTwist
ALUTwist(GeometryType)
Definition: twists.hh:256
Dune::ALUTwistIterator::ALUTwistIterator
ALUTwistIterator(Twist twist)
Definition: twists.hh:33
Dune::ALUTwist< corners, 2 >::inverse
ALUTwist inverse() const
obtain inverse
Definition: twists.hh:133
Dune
Definition: alu3dinclude.hh:79
Dune::TrivialTwist::dimension
static const int dimension
dimension
Definition: twists.hh:477
Dune::ALUTwists< corners, 2 >::size
std::size_t size() const
obtain number of twists in the group
Definition: twists.hh:384
Dune::ALUTwists
Definition: twists.hh:22
Dune::TrivialTwists::begin
Iterator begin() const
obtain begin iterator
Definition: twists.hh:614
Dune::ALUTwist< corners, 2 >::positive
bool positive() const
equivalent to
Definition: twists.hh:191