DUNE PDELab (2.7)

equidistantpoints.hh
1#ifndef DUNE_LOCALFUNCTIONS_LAGRANGE_EQUIDISTANTPOINTS_HH
2#define DUNE_LOCALFUNCTIONS_LAGRANGE_EQUIDISTANTPOINTS_HH
3
4#include <cstddef>
5
6#include <algorithm>
7#include <vector>
8
9#include <dune/geometry/referenceelementimplementation.hh>
10#include <dune/geometry/type.hh>
11
12#include <dune/localfunctions/lagrange/emptypoints.hh>
13#include <dune/localfunctions/utility/field.hh>
14
15namespace Dune
16{
17
18 // numLagrangePoints
19 // -----------------
20
21 inline std::size_t numLagrangePoints ( unsigned int topologyId, int dim, std::size_t order )
22 {
23 assert( topologyId < Impl::numTopologies( dim ) );
24
25 if( dim > 0 )
26 {
27 const unsigned int baseId = Impl::baseTopologyId( topologyId, dim );
28 if( Impl::isPyramid( topologyId, dim ) )
29 {
30 std::size_t size = 0;
31 for( unsigned int o = 0; o <= order; ++o )
32 size += numLagrangePoints( baseId, dim-1, o );
33 return size;
34 }
35 else
36 return numLagrangePoints( baseId, dim-1, order ) * (order+1);
37 }
38 else
39 return 1;
40 }
41
42
43
44 // equidistantLagrangePoints
45 // -------------------------
46
47 template< class ct, unsigned int cdim >
48 inline static unsigned int equidistantLagrangePoints ( unsigned int topologyId, unsigned int dim, unsigned int codim, std::size_t order, unsigned int *count, LagrangePoint< ct, cdim > *points )
49 {
50 assert( (0 <= codim) && (codim <= dim) && (dim <= cdim) );
51 assert( topologyId < Impl::numTopologies( dim ) );
52
53 if( dim > 0 )
54 {
55 const unsigned int baseId = Impl::baseTopologyId( topologyId, dim );
56 const unsigned int numBaseN = (codim < dim ? Geo::Impl::size( baseId, dim-1, codim ) : 0);
57 const unsigned int numBaseM = (codim > 0 ? Geo::Impl::size( baseId, dim-1, codim-1 ) : 0);
58
59 if( Impl::isPrism( topologyId, dim ) )
60 {
61 unsigned int size = 0;
62 if( codim < dim )
63 {
64 for( unsigned int i = 1; i < order; ++i )
65 {
66 const unsigned int n = equidistantLagrangePoints( baseId, dim-1, codim, order, count, points );
67 for( unsigned int j = 0; j < n; ++j )
68 {
69 LocalKey &key = points->localKey_;
70 key = LocalKey( key.subEntity(), codim, key.index() );
71 points->point_[ dim-1 ] = ct( i ) / ct( order );
72 ++points;
73 }
74 size += n;
75 }
76 }
77
78 if( codim > 0 )
79 {
80 const unsigned int n = equidistantLagrangePoints( baseId, dim-1, codim-1, order, count+numBaseN, points );
81 for( unsigned int j = 0; j < n; ++j )
82 {
83 LocalKey &key = points[ j ].localKey_;
84 key = LocalKey( key.subEntity() + numBaseN, codim, key.index() );
85
86 points[ j + n ].point_ = points[ j ].point_;
87 points[ j + n ].point_[ dim-1 ] = ct( 1 );
88 points[ j + n ].localKey_ = LocalKey( key.subEntity() + numBaseM, codim, key.index() );
89 ++count[ key.subEntity() + numBaseM ];
90 }
91 size += 2*n;
92 }
93
94 return size;
95 }
96 else
97 {
98 unsigned int size = (codim > 0 ? equidistantLagrangePoints( baseId, dim-1, codim-1, order, count, points ) : 0);
99 LagrangePoint< ct, cdim > *const end = points + size;
100 for( ; points != end; ++points )
101 points->localKey_ = LocalKey( points->localKey_.subEntity(), codim, points->localKey_.index() );
102
103 if( codim < dim )
104 {
105 for( unsigned int i = order-1; i > 0; --i )
106 {
107 const unsigned int n = equidistantLagrangePoints( baseId, dim-1, codim, i, count+numBaseM, points );
108 LagrangePoint< ct, cdim > *const end = points + n;
109 for( ; points != end; ++points )
110 {
111 points->localKey_ = LocalKey( points->localKey_.subEntity()+numBaseM, codim, points->localKey_.index() );
112 for( unsigned int j = 0; j < dim-1; ++j )
113 points->point_[ j ] *= ct( i ) / ct( order );
114 points->point_[ dim-1 ] = ct( order - i ) / ct( order );
115 }
116 size += n;
117 }
118 }
119 else
120 {
121 points->localKey_ = LocalKey( numBaseM, dim, count[ numBaseM ]++ );
122 points->point_ = 0;
123 points->point_[ dim-1 ] = ct( 1 );
124 ++size;
125 }
126
127 return size;
128 }
129 }
130 else
131 {
132 points->localKey_ = LocalKey( 0, 0, count[ 0 ]++ );
133 points->point_ = 0;
134 return 1;
135 }
136 }
137
138
139
140 // EquidistantPointSet
141 // -------------------
142
143 template< class F, unsigned int dim >
144 class EquidistantPointSet
145 : public EmptyPointSet< F, dim >
146 {
147 typedef EmptyPointSet< F, dim > Base;
148
149 public:
150 static const unsigned int dimension = dim;
151
152 using Base::order;
153
154 EquidistantPointSet ( std::size_t order ) : Base( order ) {}
155
156 void build ( GeometryType gt )
157 {
158 assert( gt.dim() == dimension );
159 points_.resize( numLagrangePoints( gt.id(), dimension, order() ) );
160
161 typename Base::LagrangePoint *p = points_.data();
162 std::vector< unsigned int > count;
163 for( unsigned int mydim = 0; mydim <= dimension; ++mydim )
164 {
165 count.resize( Geo::Impl::size( gt.id(), dimension, dimension-mydim ) );
166 std::fill( count.begin(), count.end(), 0u );
167 p += equidistantLagrangePoints( gt.id(), dimension, dimension-mydim, order(), count.data(), p );
168 }
169 }
170
171 template< class T >
172 bool build ()
173 {
174 build( GeometryType( T() ) );
175 return true;
176 }
177
178 template< class T >
179 static bool supports ( std::size_t order ) { return true; }
180
181 private:
182 using Base::points_;
183 };
184
185} // namespace Dune
186
187#endif // #ifndef DUNE_LOCALFUNCTIONS_LAGRANGE_EQUIDISTANTPOINTS_HH
GeometryType
Type representing VTK's entity geometry types.
Definition: common.hh:180
bool gt(const T &first, const T &second, typename EpsilonType< T >::Type epsilon)
test if first greater than second
Definition: float_cmp.cc:156
Dune namespace.
Definition: alignedallocator.hh:14
A unique label for each type of element that can occur in a grid.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)