dune-localfunctions  2.11
enriched/cubeq1bubble/localbasis.hh
Go to the documentation of this file.
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 // SPDX-FileCopyrightInfo: Copyright © DUNE Project contributors, see file LICENSE.md in module root
4 // SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
5 #ifndef DUNE_LOCALFUNCTIONS_ENRICHED_CUBEQ1BUBBLE_LOCALBASIS_HH
6 #define DUNE_LOCALFUNCTIONS_ENRICHED_CUBEQ1BUBBLE_LOCALBASIS_HH
7 
8 #include <numeric>
9 #include <stdexcept>
10 #include <vector>
11 
12 #include <dune/common/fvector.hh>
13 #include <dune/common/fmatrix.hh>
14 #include <dune/common/math.hh>
15 
17 
18 namespace Dune
19 {
34  template<class D, class R, int dim>
36  {
37  template<class> friend class CubeQ1BubbleLocalInterpolation;
38 
40  using DomainType = FieldVector<D,dim>;
41 
43  using RangeType = FieldVector<R,1>;
44 
46  using JacobianType = FieldMatrix<R,1,dim>;
47 
48  static constexpr int dimension = dim;
49  static constexpr int numVertices = power(2, dim);
50 
51  // scaling factor of bubble basis function for normalization
52  static constexpr int scaling = power(2, 2*dim);
53 
54  public:
57 
59  static constexpr std::size_t size () noexcept
60  {
61  return numVertices+1;
62  }
63 
65  static constexpr void evaluateFunction (const DomainType& x, std::vector<RangeType>& out)
66  {
67  out.resize(size());
68 
69  for (int i = 0; i < numVertices; ++i) {
70  out[i] = 1;
71  for (int j = 0; j < dimension; ++j) {
72  // if j-th bit of i is set multiply with x[j], else with 1-x[j]
73  out[i] *= (i & (1<<j)) ? x[j] : 1-x[j];
74  }
75  }
76 
77  out.back() = scaling;
78  for (int j = 0; j < dimension; ++j) {
79  out.back() *= (1-x[j]) * x[j];
80  }
81  }
82 
84  static constexpr void evaluateJacobian (const DomainType& x, std::vector<JacobianType>& out)
85  {
86  out.resize(size());
87 
88  // Loop over all linear shape functions
89  for (int i = 0; i < numVertices; ++i) {
90  // Loop over all coordinate directions
91  for (int j = 0; j < dimension; ++j) {
92  // Initialize: the overall expression as a product
93  // if j-th bit of i is set to 1, else -11
94  out[i][0][j] = (i & (1<<j)) ? 1 : -1;
95 
96  for (int k = 0; k < dimension; ++k) {
97  if (j != k)
98  // if k-th bit of i is set multiply with x[k], else with 1-x[k]
99  out[i][0][j] *= (i & (1<<k)) ? x[k] : 1-x[k];
100  }
101  }
102  }
103 
104  for (int j = 0; j < dimension; ++j) {
105  out.back()[0][j] = scaling;
106  for (int k = 0; k < dimension; ++k)
107  out.back()[0][j] *= (j == k) ? (1-2*x[k]) : (1-x[k])*x[k];
108  }
109  }
110 
112  static constexpr void partial (const std::array<unsigned int, dim>& order,
113  const DomainType& x,
114  std::vector<RangeType>& out)
115  {
116  unsigned int totalOrder = 0;
117  for (int i = 0; i < dimension; ++i)
118  totalOrder += order[i];
119 
120  switch (totalOrder) {
121  case 0:
122  evaluateFunction(x,out);
123  break;
124  case 1: {
125  out.resize(size());
126  int d = 0; // the direction of differentiation
127  for (int i = 0; i < dimension; ++i)
128  d += i * order[i];
129 
130  if (d >= dimension)
131  throw std::invalid_argument("Direction of partial derivative not found!");
132 
133  // Loop over all shape functions
134  for (int i = 0; i < numVertices; ++i) {
135  // Initialize: the overall expression is a product
136  // if j-th bit of i is set to 1, otherwise to -1
137  out[i] = (i & (1<<d)) ? 1 : -1;
138 
139  for (int j = 0; j < dimension; ++j) {
140  if (d != j)
141  // if j-th bit of i is set multiply with in[j], else with 1-in[j]
142  out[i] *= (i & (1<<j)) ? x[j] : 1-x[j];
143  }
144  }
145 
146  out.back() = scaling;
147  for (int k = 0; k < dimension; ++k)
148  out.back() *= (d == k) ? (1-2*x[k]) : (1-x[k])*x[k];
149 
150  } break;
151  default:
152  throw std::runtime_error("Desired derivative order is not implemented");
153  }
154  }
155 
157  static constexpr unsigned int order () noexcept
158  {
159  return 2;
160  }
161  };
162 
163 } // end namespace Dune
164 
165 #endif // DUNE_LOCALFUNCTIONS_ENRICHED_CUBEQ1BUBBLE_LOCALBASIS_HH
static constexpr std::size_t size() noexcept
Returns number of shape functions.
Definition: enriched/cubeq1bubble/localbasis.hh:59
static constexpr void evaluateJacobian(const DomainType &x, std::vector< JacobianType > &out)
Evaluate Jacobian of all shape functions.
Definition: enriched/cubeq1bubble/localbasis.hh:84
Definition: bdfmcube.hh:17
static constexpr void partial(const std::array< unsigned int, dim > &order, const DomainType &x, std::vector< RangeType > &out)
Evaluate partial derivatives of all shape functions.
Definition: enriched/cubeq1bubble/localbasis.hh:112
Q1 basis in dim-d enriched by an (order 2) element bubble function.
Definition: enriched/cubeq1bubble/localbasis.hh:35
static constexpr unsigned int order() noexcept
Returns maximal polynomial order of the basis functions.
Definition: enriched/cubeq1bubble/localbasis.hh:157
static constexpr void evaluateFunction(const DomainType &x, std::vector< RangeType > &out)
Evaluate all shape functions.
Definition: enriched/cubeq1bubble/localbasis.hh:65
Type traits for LocalBasisVirtualInterface.
Definition: common/localbasis.hh:34
Interpolation into the CubeQ1BubbleLocalBasis.
Definition: enriched/cubeq1bubble/localinterpolation.hh:33