DUNE-FEM (unstable)

quadratureinterpolation.hh
1#ifndef DUNE_LOBATTOBASIS_HH
2#define DUNE_LOBATTOBASIS_HH
3
4#include <fstream>
5
7#include <dune/geometry/topologyfactory.hh>
9#include <dune/geometry/referenceelements.hh>
10
11#include <dune/fem/common/forloop.hh>
12
13#if HAVE_DUNE_LOCALFUNCTIONS
14#include <dune/localfunctions/utility/field.hh>
15#include <dune/localfunctions/lagrange/lagrangecoefficients.hh>
16#include <dune/localfunctions/lagrange/emptypoints.hh>
17#include <dune/localfunctions/lagrange/equidistantpoints.hh>
18
19
20namespace Dune
21{
22 namespace Impl
23 {
24 template <class Field>
25 struct Builder
26 {
27 template <class Points1DType>
28 static int size(const GeometryType gt, const Points1DType &points1D)
29 {
30 if (gt.dim()==0) return 1;
31 else if (gt.isPrismatic())
32 return Builder<Field>::size(Impl::getBase(gt),points1D)*points1D.size(); // (order-1);
33 else
34 {
35 std::cout << "Not implemented for pyramid geometries still missing!\n";
36 std::abort();
37 }
38 }
39 template <unsigned int dim, class Points1DType>
40 static void setup(const GeometryType gt, const Points1DType &points1D,
41 LagrangePoint< Field, dim > *points )
42 {
43 if (dim==0)
44 {
45 points->weight_ = 1.;
46 return;
47 }
48 if (gt.dim()==0)
49 {
50 points->point_[0] = Zero<Field>();
51 points->weight_ = 1.;
52 }
53 else if (gt.isPrismatic())
54 {
55 GeometryType baseGt = Impl::getBase(gt);
56 assert(dim>=gt.dim());
57 Builder<Field>::template setup<dim>(baseGt,points1D,points);
58 const unsigned int baseSize = Builder::size(baseGt,points1D);
59 for (unsigned int i=0;i<baseSize;++i)
60 {
61 Field weight = points[i].weight_;
62 for (unsigned int q=0;q<points1D.size();q++)
63 {
64 const unsigned int pos = q*baseSize+i;
65 for (unsigned int d=0;d<gt.dim()-1;++d)
66 points[pos].point_[d] = points[i].point_[d];
67 points[pos].point_[gt.dim()-1]=points1D[q].first;
68 points[pos].weight_ = weight*points1D[q].second;
69 }
70 }
71 }
72 else
73 {
74 std::cout << "Not implemented for pyramid geometries still missing!\n";
75 std::abort();
76 }
77 }
78 };
79 } // namespace Impl
80
81 template< class F, unsigned int dim >
82 struct PointSetFromQuadrature : public EmptyPointSet<F,dim>
83 {
84 static const unsigned int dimension = dim;
85 typedef F Field;
86 typedef EmptyPointSet<F,dim> Base;
87 typedef typename Base::LagrangePoint Point;
88 typedef std::vector<std::pair<Field,Field>> Points1DType;
89 PointSetFromQuadrature(unsigned int order)
90 : Base(order), quadOrder_(-1)
91 {}
92
93 template <GeometryType::Id geometryId, class Quad>
94 bool build (const Quad& quadFactory)
95 {
96 constexpr GeometryType gt(geometryId);
97 unsigned int order = Base::order();
98 const auto &quad = quadFactory(order);
99 quadOrder_ = quad.order();
100 assert( quad.size() == order+1 );
101 bool withEndPoints = false;
102 Points1DType points1D;
103 Field vertexWeight = 1;
104 for (unsigned int i=0;i<=order;++i)
105 {
106 // remove corner points if part of the quadrature - are added in by
107 // topology construction of points
108 Field p = field_cast<Field>(quad[i].position());
109 Field q = p-1.;
110 if (std::abs(p)<1e-12 || std::abs(q)<1e-12)
111 {
112 withEndPoints = true;
113 vertexWeight = quad[i].weight(); // assuming weight is identical for both end points
114 }
115 else
116 points1D.push_back(std::make_pair(p,quad[i].weight()));
117 }
118 if (withEndPoints)
119 Dune::Fem::ForLoop<Setup::template InitCodim,0,dimension>::
120 apply(gt,order,points1D,vertexWeight,points_);
121 else
122 Setup::template InitCodim<dimension>::
123 apply(gt,order,points1D,vertexWeight,points_);
124 return true;
125 }
126 static bool supports ( GeometryType gt, int order )
127 {
128 return gt.isCube();
129 }
130 template< GeometryType::Id geometryId>
131 static bool supports ( std::size_t order ) {
132 return supports( GeometryType( geometryId ), order );
133 }
134 unsigned int quadOrder() const
135 {
136 return quadOrder_;
137 }
138 protected:
139 using Base::points_;
140 unsigned int quadOrder_;
141 private:
142 struct Setup
143 {
144 template <int pdim>
145 struct InitCodim
146 {
147 static const unsigned int codim = dimension-pdim;
148 static void apply(GeometryType gt, const unsigned int order,
149 const Points1DType &points1D,
150 const Field &vertexWeight,
151 std::vector<Point> &points)
152 {
153 const unsigned int subEntities = Dune::Geo::Impl::size(gt.id(),gt.dim(),codim);
154 for (unsigned int subEntity=0;subEntity<subEntities;++subEntity)
155 {
156 GeometryType subGt(Impl::baseTopologyId(gt.id(),gt.dim(),codim),gt.dim()-codim);
157 unsigned int oldSize = points.size();
158 unsigned int size = Impl::Builder<Field>::size(subGt,points1D);
159 if (size==0) continue;
160 points.resize(oldSize+size);
161 std::vector< LagrangePoint<Field,dimension-codim> > subPoints(size);
162 Impl::Builder<Field>::template setup<dimension-codim>( subGt, points1D, &(subPoints[0]) );
163
164 const auto &refElement = referenceElement<Field,dimension>(gt);
165 const auto &mapping = refElement.template geometry< codim >( subEntity );
166
167 LagrangePoint<Field,dimension> *p = &(points[oldSize]);
168 for ( unsigned int nr = 0; nr<size; ++nr, ++p)
169 {
170 p->point_ = mapping.global( subPoints[nr].point_ );
171 p->weight_ = subPoints[nr].weight_ * std::pow(vertexWeight,codim)*refElement.volume();
172 p->localKey_ = LocalKey( subEntity, codim, nr );
173 }
174 }
175 }
176 };
177 };
178 };
179
181 // a point set from dune-localfunctions
183 template< class F, unsigned int dim >
184 struct EquidistantPointSetDerived : public Dune::EquidistantPointSet< F, dim >
185 {
186 typedef Dune::EquidistantPointSet< F, dim > Base;
187
188 EquidistantPointSetDerived(unsigned int order)
189 : Base(order)
190 {}
191
192 // needed for InterpolationQuadrature
193 static const int pointSetId = Dune::QuadratureType::size;
194
195 static unsigned int quad2PolOrder(int order) { return order; }
196 unsigned int quadOrder() const { return Base::order(); }
197
198 static auto buildCubeQuadrature(unsigned int quadOrder)
199 {
200 using namespace Impl;
201 EquidistantPointSetDerived ps(quad2PolOrder(quadOrder));
202 ps.template build<GeometryTypes::cube(dim)>();
203 return ps;
204 }
205 };
206
207
209 // Some point sets from dune-geometry
211 template< class F, unsigned int dim >
212 struct GaussLobattoPointSet : public PointSetFromQuadrature<F,dim>
213 {
214 static const unsigned int dimension = dim;
215 typedef F Field;
216 typedef PointSetFromQuadrature<F,dim> Base;
217 typedef typename Base::LagrangePoint Point;
218
219 // enum identifier from dune-geometry QuadratureRules
220 static const int pointSetId = Dune::QuadratureType::GaussLobatto;
221
222 GaussLobattoPointSet(unsigned int order)
223 : Base(order)
224 {}
225 template< GeometryType::Id geometryId >
226 bool build ()
227 {
228 // get LobattoQuad with order+1 points
229 auto quadFactory = [](int order)
231 Dune::GeometryTypes::line, pol2QuadOrder(order),
233 };
234 return Base::template build<geometryId>(quadFactory);
235 }
236 static unsigned int pol2QuadOrder(int order)
237 {
238 return (order>0)? 2*order-1 : 0;
239 }
240 static unsigned int quad2PolOrder(int order)
241 {
242 return order/2 + 1;
243 }
244
245 static auto buildCubeQuadrature(unsigned int quadOrder)
246 {
247 using namespace Impl;
248 GaussLobattoPointSet ps(quad2PolOrder(quadOrder));
249 ps.template build<GeometryTypes::cube(dim)>();
250 return ps;
251 }
252 };
253
254
255 template< class F, unsigned int dim >
256 struct GaussLegendrePointSet : public PointSetFromQuadrature<F,dim>
257 {
258 static const unsigned int dimension = dim;
259 typedef F Field;
260 typedef PointSetFromQuadrature<F,dim> Base;
261 typedef typename Base::LagrangePoint Point;
262
263 // enum identifier from dune-geometry QuadratureRules
264 static const int pointSetId = Dune::QuadratureType::GaussLegendre;
265
266 GaussLegendrePointSet(unsigned int order)
267 : Base(order)
268 {}
269 template< GeometryType::Id geometryId >
270 bool build ()
271 {
272 // get LobattoQuad with order+1 points
273 auto quadFactory = [](int order)
276 };
277 return Base::template build<GeometryType(geometryId)>(quadFactory);
278 }
279
280 static unsigned int pol2QuadOrder(int order)
281 {
282 return 2*order+1;
283 }
284 static unsigned int quad2PolOrder(int order)
285 {
286 return order/2;
287 }
288
289 static auto buildCubeQuadrature(unsigned int quadOrder)
290 {
291 using namespace Impl;
292 GaussLegendrePointSet ps(quad2PolOrder(quadOrder));
293 ps.template build<GeometryTypes::cube(dim)>();
294 return ps;
295 }
296 };
297
299 // Some point sets for preconditioning providing
300 // interpolation based on cell centers of refined cells
302 template< class F, unsigned int dim >
303 struct CellCentersPointSet : public PointSetFromQuadrature<F,dim>
304 {
305 typedef PointSetFromQuadrature<F,dim> Base;
306 static const unsigned int dimension = dim;
307 typedef F Field;
308
309 // needed for InterpolationQuadrature
310 static const int pointSetId = Dune::QuadratureType::size+1;
311
312 CellCentersPointSet(unsigned int order)
313 : Base(order)
314 {}
315
319 template<typename ct>
320 class CellCenters : public Dune::QuadratureRule<ct,1>
321 {
322 public:
324 enum { highest_order=7 };
325
326 friend class QuadratureRuleFactory<ct,1>;
327 CellCenters(int p)
328 {
329 this->delivered_order = p;
330
331 const int n = p+1; // we have p+1 intervals
332 const Field h = 1./Field(n);
333 // compute cell centers of the interval
334 for( int i=0; i<n; ++i )
335 {
336 const Field x = 0.5*h + h*i;
337 assert( x > 0.0 && x < 1.0 );
338 this->push_back(QuadraturePoint<ct,1>(x, h));
339 }
340 }
341 };
342
343 static unsigned int quad2PolOrder(int order) { return order; }
344
345 unsigned int quadOrder() const { return Base::order(); }
346
347 template< GeometryType::Id geometryId >
348 bool build ()
349 {
350 // get FV centers as points
351 auto quadFactory = [](int order)
352 {
353 return CellCenters<Field>(order);
354 };
355 return Base::template build<geometryId>(quadFactory);
356 }
357 static auto buildCubeQuadrature(unsigned int quadOrder)
358 {
359 using namespace Impl;
360 CellCentersPointSet ps(quad2PolOrder(quadOrder));
361 ps.template build<GeometryTypes::cube(dim)>();
362 return ps;
363 }
364 };
365
366} // namespace DUNE
367
368#endif // HAVE_DUNE_LOCALFUNCTIONS
369
370#endif // DUNE_LOBATTOBASIS_HH
Abstract base class for quadrature rules.
Definition: quadraturerules.hh:214
static const QuadratureRule & rule(const GeometryType &t, int p, QuadratureType::Enum qt=QuadratureType::GaussLegendre)
select the appropriate QuadratureRule for GeometryType t and order p
Definition: quadraturerules.hh:326
GeometryType
Type representing VTK's entity geometry types.
Definition: common.hh:132
bool gt(const T &first, const T &second, typename EpsilonType< T >::Type epsilon)
test if first greater than second
Definition: float_cmp.cc:158
constexpr GeometryType line
GeometryType representing a line.
Definition: type.hh:498
@ GaussLobatto
Gauss-Lobatto rules.
Definition: quadraturerules.hh:176
@ GaussLegendre
Gauss-Legendre rules (default)
Definition: quadraturerules.hh:141
Dune namespace.
Definition: alignedallocator.hh:13
constexpr std::integer_sequence< T, II..., T(IN)> push_back(std::integer_sequence< T, II... >, std::integral_constant< T, IN >={})
Append an index IN to the back of the sequence.
Definition: integersequence.hh:69
constexpr std::integral_constant< std::size_t, sizeof...(II)> size(std::integer_sequence< T, II... >)
Return the size of the sequence.
Definition: integersequence.hh:75
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 27, 22:29, 2024)