Dune Core Modules (2.9.0)

localinterpolation.hh
1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
3#ifndef DUNE_LOCALFUNCTIONS_BREZZIDOUGLASFORTINMARINI_CUBE_LOCALINTERPOLATION_HH
4#define DUNE_LOCALFUNCTIONS_BREZZIDOUGLASFORTINMARINI_CUBE_LOCALINTERPOLATION_HH
5
6#include <algorithm>
7#include <array>
8#include <bitset>
9#include <vector>
10#include <limits>
11
13#include <dune/common/math.hh>
16
18
19#include <dune/localfunctions/common/localinterpolation.hh>
20
21
22namespace Dune
23{
24
36 template<class D, class R, unsigned int dim, unsigned int order>
38 {
40 using FaceDomainType = FieldVector<D, dim-1>;
42 using DomainFieldType = D;
43 using RangeFieldType = R;
44
45 static constexpr std::size_t numFaces = 2*dim;
46
47 static constexpr unsigned int interiorDofs = dim*binomial(dim+order-2, order-2);
48 static constexpr unsigned int faceDofs = binomial(dim+order-2, order-1);
49
56 inline static auto legendre( unsigned int i, const DomainFieldType& x )
57 -> RangeFieldType
58 {
59 switch( i )
60 {
61 case 0:
62 return 1;
63 case 1:
64 return 2*x-1;
65 case 2:
66 return 6*x*x-6*x+1;
67 case 3:
68 return 20*x*x*x-30*x*x+12*x-1;
69 default:
70 return ((2*i-1)*(2*x-1)*legendre(x,i-1) - (i-1)*legendre(x,i-2)) / i;
71 }
72 }
73
84 constexpr inline static auto unrank (std::size_t i)
85 -> std::array<std::size_t, d>
86 {
87 assert( i < binomial(d+kMax, kMax));
88
89 std::array<std::size_t, d> mi{};
90 if (i == 0)
91 return mi;
92
93 std::size_t k = 0, b = 1;
94 for(;k <= kMax && b <= i; ++k, b = binomial(d+k-1, k))
95 i -= b;
96
97 std::size_t p = 0;
98 for(; p < d && i > 0; ++p)
99 {
100 std::size_t m = 0, c = 1;
101 for(; m <= k && c <= i; ++m, c = binomial(d-p+m-2, m))
102 i -= c;
103
104 mi[p] = k-m;
105 k = m;
106 }
107 mi[p] = k;
108
109 return mi;
110 }
111
118 inline static auto embed (unsigned int face, const FaceDomainType& x )
119 -> DomainType
120 {
121 DomainType y;
122
123 std::size_t j = 0;
124 for (auto i : range(dim))
125 if (i == face/2)
126 y[i] = face%2;
127 else
128 y[i] = x[j++];
129
130 return y;
131 }
132
133 public:
136 {
137 std::fill(sign_.begin(), sign_.end(), 1.0);
138 }
139
145 BDFMCubeLocalInterpolation (std::bitset<numFaces> s)
146 {
147 for (auto i : range(numFaces))
148 {
149 sign_[i] = s[i] ? -1 : 1;
150 normal_[i][i/2] = i%2 ? 1 : -1;
151 }
152 }
153
163 template<class F, class C>
164 void interpolate (const F& ff, C& out) const
165 {
166 out.resize(numFaces*faceDofs + interiorDofs);
167 std::fill(out.begin(),out.end(), 0.0);
168
169 auto&& f = Impl::makeFunctionWithCallOperator<DomainType>(ff);
170
171 for(auto i : range(numFaces))
172 trace(i, f, out);
173
174 interior(f, out);
175 }
176
188 template<class F, class C>
189 void trace (unsigned int face, const F& f, C& out) const
190 {
191 assert(out.size() >= numFaces*faceDofs + interiorDofs);
192 assert(face < numFaces);
193
194 const auto o = face*faceDofs;
195 const auto& n = normal_[face];
196 const auto& s = sign_[face];
197 const auto& c = n[face/2];
198
199 const auto& rule = QuadratureRules<DomainFieldType, dim-1>::rule(GeometryTypes::cube(dim-1), order+(order-1)+5);
200 for (const auto& qp : rule)
201 {
202 const auto& x = qp.position();
203 auto y = f(embed(face, x));
204
205 for (auto i : range(faceDofs))
206 {
207 auto mi = unrank<dim-1,order-1>(i);
208
209 RangeFieldType phi = 1.;
210 for (auto j : range(dim-1))
211 phi *= legendre(mi[j], x[j]);
212
213 out[o+i] += (y*n) * phi * qp.weight() * (i%2 ? c : s);
214 }
215 }
216 }
217
227 template<class F, class C>
228 void interior (const F& f, C& out) const
229 {
230 assert(out.size() >= numFaces*faceDofs + interiorDofs);
231
232 const auto o = numFaces*faceDofs;
233
234 const auto& rule = QuadratureRules<DomainFieldType, dim>::rule(GeometryTypes::cube(dim), order+std::max((int)order-2,(int)0)+5);
235 for(const auto& qp : rule)
236 {
237 const auto& x = qp.position();
238 auto y = f(x);
239
240 for (auto i : range(interiorDofs/dim))
241 {
242 auto mi = unrank<dim,order-2>(i);
243
244 RangeFieldType phi = 1.;
245 for (auto j : range(dim))
246 phi *= legendre(mi[j], x[j]);
247
248 for (auto j : range(dim))
249 out[o+dim*i+j] += y[j]* phi * qp.weight();
250 }
251 }
252 }
253
254 private:
255 std::array<RangeFieldType, numFaces> sign_;
256 std::array<DomainType, numFaces> normal_;
257 };
258
259
260 template<class D, class R, unsigned int dim, unsigned int order>
261 constexpr std::size_t BDFMCubeLocalInterpolation<D, R, dim, order>::numFaces;
262
263 template<class D, class R, unsigned int dim, unsigned int order>
264 constexpr unsigned int BDFMCubeLocalInterpolation<D, R, dim, order>::interiorDofs;
265
266 template<class D, class R, unsigned int dim, unsigned int order>
267 constexpr unsigned int BDFMCubeLocalInterpolation<D, R, dim, order>::faceDofs;
268
269
270#ifndef DOXYGEN
271 template<class D, class R, unsigned int dim>
272 class BDFMCubeLocalInterpolation<D, R, dim, 0>
273 {
274 static_assert(AlwaysFalse<D>::value,
275 "`BDFMCubeLocalCoefficients` not defined for order 0.");
276 };
277#endif //#ifndef DOXYGEN
278
279} // namespace Dune
280
281#endif // #ifndef DUNE_LOCALFUNCTIONS_BREZZIDOUGLASFORTINMARINI_CUBE_LOCALINTERPOLATION_HH
Interpolation for Brezzi-Douglas-Fortin-Marini shape functions on cubes.
Definition: localinterpolation.hh:38
void interpolate(const F &ff, C &out) const
Interpolate a given function with shape functions.
Definition: localinterpolation.hh:164
BDFMCubeLocalInterpolation(std::bitset< numFaces > s)
Make set number s, where 0 <= s < 2^(2*dim)
Definition: localinterpolation.hh:145
BDFMCubeLocalInterpolation()
Standard constructor.
Definition: localinterpolation.hh:135
void trace(unsigned int face, const F &f, C &out) const
Interpolate a given function with shape functions on a face of the reference element.
Definition: localinterpolation.hh:189
void interior(const F &f, C &out) const
Interpolate a given function with shape functions in the interior of the reference element.
Definition: localinterpolation.hh:228
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:266
Traits for type conversions and type information.
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
auto max(ADLTag< 0 >, const V &v1, const V &v2)
implements binary Simd::max()
Definition: defaults.hh:81
Some useful basic math stuff.
Dune namespace.
Definition: alignedallocator.hh:13
static constexpr T binomial(const T &n, const T &k) noexcept
calculate the binomial coefficient n over k as a constexpr
Definition: math.hh:131
Utilities for reduction like operations on ranges.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Dec 21, 23:30, 2024)