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 
12 #include <dune/common/fvector.hh>
13 #include <dune/common/math.hh>
16 
18 
19 #include <dune/localfunctions/common/localinterpolation.hh>
20 
21 
22 namespace 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
constexpr static 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.80.0 (May 4, 22:30, 2024)