Dune Core Modules (unstable)

localinterpolation.hh
1 // SPDX-FileCopyrightText: Copyright © 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 
20 namespace Dune
21 {
22 
34  template<class D, class R, unsigned int dim, unsigned int order>
36  {
38  using FaceDomainType = FieldVector<D, dim-1>;
40  using DomainFieldType = D;
41  using RangeFieldType = R;
42 
43  static constexpr std::size_t numFaces = 2*dim;
44 
45  static constexpr unsigned int interiorDofs = dim*binomial(dim+order-2, order-2);
46  static constexpr unsigned int faceDofs = binomial(dim+order-2, order-1);
47 
54  inline static auto legendre( unsigned int i, const DomainFieldType& x )
55  -> RangeFieldType
56  {
57  switch( i )
58  {
59  case 0:
60  return 1;
61  case 1:
62  return 2*x-1;
63  case 2:
64  return 6*x*x-6*x+1;
65  case 3:
66  return 20*x*x*x-30*x*x+12*x-1;
67  default:
68  return ((2*i-1)*(2*x-1)*legendre(x,i-1) - (i-1)*legendre(x,i-2)) / i;
69  }
70  }
71 
82  constexpr inline static auto unrank (std::size_t i)
83  -> std::array<std::size_t, d>
84  {
85  assert( i < binomial(d+kMax, kMax));
86 
87  std::array<std::size_t, d> mi{};
88  if (i == 0)
89  return mi;
90 
91  std::size_t k = 0, b = 1;
92  for(;k <= kMax && b <= i; ++k, b = binomial(d+k-1, k))
93  i -= b;
94 
95  std::size_t p = 0;
96  for(; p < d && i > 0; ++p)
97  {
98  std::size_t m = 0, c = 1;
99  for(; m <= k && c <= i; ++m, c = binomial(d-p+m-2, m))
100  i -= c;
101 
102  mi[p] = k-m;
103  k = m;
104  }
105  mi[p] = k;
106 
107  return mi;
108  }
109 
116  inline static auto embed (unsigned int face, const FaceDomainType& x )
117  -> DomainType
118  {
119  DomainType y;
120 
121  std::size_t j = 0;
122  for (auto i : range(dim))
123  if (i == face/2)
124  y[i] = face%2;
125  else
126  y[i] = x[j++];
127 
128  return y;
129  }
130 
131  public:
134  {
135  std::fill(sign_.begin(), sign_.end(), 1.0);
136  }
137 
143  BDFMCubeLocalInterpolation (std::bitset<numFaces> s)
144  {
145  for (auto i : range(numFaces))
146  {
147  sign_[i] = s[i] ? -1 : 1;
148  normal_[i][i/2] = i%2 ? 1 : -1;
149  }
150  }
151 
161  template<class F, class C>
162  void interpolate (const F& f, C& out) const
163  {
164  out.resize(numFaces*faceDofs + interiorDofs);
165  std::fill(out.begin(),out.end(), 0.0);
166 
167  for(auto i : range(numFaces))
168  trace(i, f, out);
169 
170  interior(f, out);
171  }
172 
184  template<class F, class C>
185  void trace (unsigned int face, const F& f, C& out) const
186  {
187  assert(out.size() >= numFaces*faceDofs + interiorDofs);
188  assert(face < numFaces);
189 
190  const auto o = face*faceDofs;
191  const auto& n = normal_[face];
192  const auto& s = sign_[face];
193  const auto& c = n[face/2];
194 
195  const auto& rule = QuadratureRules<DomainFieldType, dim-1>::rule(GeometryTypes::cube(dim-1), order+(order-1)+5);
196  for (const auto& qp : rule)
197  {
198  const auto& x = qp.position();
199  auto y = f(embed(face, x));
200 
201  for (auto i : range(faceDofs))
202  {
203  auto mi = unrank<dim-1,order-1>(i);
204 
205  RangeFieldType phi = 1.;
206  for (auto j : range(dim-1))
207  phi *= legendre(mi[j], x[j]);
208 
209  out[o+i] += (y*n) * phi * qp.weight() * (i%2 ? c : s);
210  }
211  }
212  }
213 
223  template<class F, class C>
224  void interior (const F& f, C& out) const
225  {
226  assert(out.size() >= numFaces*faceDofs + interiorDofs);
227 
228  const auto o = numFaces*faceDofs;
229 
230  const auto& rule = QuadratureRules<DomainFieldType, dim>::rule(GeometryTypes::cube(dim), order+std::max((int)order-2,(int)0)+5);
231  for(const auto& qp : rule)
232  {
233  const auto& x = qp.position();
234  auto y = f(x);
235 
236  for (auto i : range(interiorDofs/dim))
237  {
238  auto mi = unrank<dim,order-2>(i);
239 
240  RangeFieldType phi = 1.;
241  for (auto j : range(dim))
242  phi *= legendre(mi[j], x[j]);
243 
244  for (auto j : range(dim))
245  out[o+dim*i+j] += y[j]* phi * qp.weight();
246  }
247  }
248  }
249 
250  private:
251  std::array<RangeFieldType, numFaces> sign_;
252  std::array<DomainType, numFaces> normal_;
253  };
254 
255 
256  template<class D, class R, unsigned int dim, unsigned int order>
257  constexpr std::size_t BDFMCubeLocalInterpolation<D, R, dim, order>::numFaces;
258 
259  template<class D, class R, unsigned int dim, unsigned int order>
260  constexpr unsigned int BDFMCubeLocalInterpolation<D, R, dim, order>::interiorDofs;
261 
262  template<class D, class R, unsigned int dim, unsigned int order>
263  constexpr unsigned int BDFMCubeLocalInterpolation<D, R, dim, order>::faceDofs;
264 
265 
266 #ifndef DOXYGEN
267  template<class D, class R, unsigned int dim>
268  class BDFMCubeLocalInterpolation<D, R, dim, 0>
269  {
270  static_assert(AlwaysFalse<D>::value,
271  "`BDFMCubeLocalCoefficients` not defined for order 0.");
272  };
273 #endif //#ifndef DOXYGEN
274 
275 } // namespace Dune
276 
277 #endif // #ifndef DUNE_LOCALFUNCTIONS_BREZZIDOUGLASFORTINMARINI_CUBE_LOCALINTERPOLATION_HH
Interpolation for Brezzi-Douglas-Fortin-Marini shape functions on cubes.
Definition: localinterpolation.hh:36
BDFMCubeLocalInterpolation(std::bitset< numFaces > s)
Make set number s, where 0 <= s < 2^(2*dim)
Definition: localinterpolation.hh:143
BDFMCubeLocalInterpolation()
Standard constructor.
Definition: localinterpolation.hh:133
void interpolate(const F &f, C &out) const
Interpolate a given function with shape functions.
Definition: localinterpolation.hh:162
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:185
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:224
vector space out of a tensor product of fields.
Definition: fvector.hh:95
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:324
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:462
constexpr auto max
Function object that returns the greater of the given values.
Definition: hybridutilities.hh:484
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.
Traits for type conversions and type information.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (Apr 27, 22:29, 2024)