Dune Core Modules (2.6.0)

qklocalbasis.hh
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 
4 #ifndef DUNE_LOCALFUNCTIONS_QKLOCALBASIS_HH
5 #define DUNE_LOCALFUNCTIONS_QKLOCALBASIS_HH
6 
7 #include <numeric>
8 
9 #include <dune/common/fvector.hh>
10 #include <dune/common/fmatrix.hh>
11 #include <dune/common/power.hh>
12 
13 #include <dune/geometry/type.hh>
14 
15 #include <dune/localfunctions/common/localbasis.hh>
16 #include <dune/localfunctions/common/localfiniteelementtraits.hh>
17 
18 
19 namespace Dune
20 {
33  template<class D, class R, int k, int d>
35  {
36  // ith Lagrange polynomial of degree k in one dimension
37  static R p (int i, D x)
38  {
39  R result(1.0);
40  for (int j=0; j<=k; j++)
41  if (j!=i) result *= (k*x-j)/(i-j);
42  return result;
43  }
44 
45  // derivative of ith Lagrange polynomial of degree k in one dimension
46  static R dp (int i, D x)
47  {
48  R result(0.0);
49 
50  for (int j=0; j<=k; j++)
51  if (j!=i)
52  {
53  R prod( (k*1.0)/(i-j) );
54  for (int l=0; l<=k; l++)
55  if (l!=i && l!=j)
56  prod *= (k*x-l)/(i-l);
57  result += prod;
58  }
59  return result;
60  }
61 
62  // Second derivative of j-th Lagrange polynomial of degree k in one dimension
63  // Formula and notation taken from https://en.wikipedia.org/wiki/Lagrange_polynomial#Derivatives
64  static R ddp (int j, D x)
65  {
66  R result(0.0);
67 
68  for (int i=0; i<=k; i++)
69  {
70  if (i==j)
71  continue;
72 
73  R sum(0);
74 
75  for (int m=0; m<=k; m++)
76  {
77  if (m==i || m==j)
78  continue;
79 
80  R prod( (k*1.0)/(j-m) );
81  for (int l=0; l<=k; l++)
82  if (l!=i && l!=j && l!=m)
83  prod *= (k*x-l)/(j-l);
84  sum += prod;
85  }
86 
87  result += sum * ( (k*1.0)/(j-i) );
88  }
89 
90  return result;
91  }
92 
93  // Return i as a d-digit number in the (k+1)-nary system
94  static Dune::FieldVector<int,d> multiindex (int i)
95  {
97  for (int j=0; j<d; j++)
98  {
99  alpha[j] = i % (k+1);
100  i = i/(k+1);
101  }
102  return alpha;
103  }
104 
105  public:
107 
109  unsigned int size () const
110  {
112  }
113 
115  inline void evaluateFunction (const typename Traits::DomainType& in,
116  std::vector<typename Traits::RangeType>& out) const
117  {
118  out.resize(size());
119  for (size_t i=0; i<size(); i++)
120  {
121  // convert index i to multiindex
122  Dune::FieldVector<int,d> alpha(multiindex(i));
123 
124  // initialize product
125  out[i] = 1.0;
126 
127  // dimension by dimension
128  for (int j=0; j<d; j++)
129  out[i] *= p(alpha[j],in[j]);
130  }
131  }
132 
137  inline void
139  std::vector<typename Traits::JacobianType>& out) const
140  {
141  out.resize(size());
142 
143  // Loop over all shape functions
144  for (size_t i=0; i<size(); i++)
145  {
146  // convert index i to multiindex
147  Dune::FieldVector<int,d> alpha(multiindex(i));
148 
149  // Loop over all coordinate directions
150  for (int j=0; j<d; j++)
151  {
152  // Initialize: the overall expression is a product
153  // if j-th bit of i is set to -1, else 1
154  out[i][0][j] = dp(alpha[j],in[j]);
155 
156  // rest of the product
157  for (int l=0; l<d; l++)
158  if (l!=j)
159  out[i][0][j] *= p(alpha[l],in[l]);
160  }
161  }
162  }
163 
169  inline void partial(const std::array<unsigned int,d>& order,
170  const typename Traits::DomainType& in,
171  std::vector<typename Traits::RangeType>& out) const
172  {
173  out.resize(size());
174 
175  // Loop over all shape functions
176  for (size_t i=0; i<size(); i++)
177  {
178  // convert index i to multiindex
179  Dune::FieldVector<int,d> alpha(multiindex(i));
180 
181  // Initialize: the overall expression is a product
182  out[i][0] = 1.0;
183 
184  // rest of the product
185  for (std::size_t l=0; l<d; l++)
186  {
187  switch (order[l])
188  {
189  case 0:
190  out[i][0] *= p(alpha[l],in[l]);
191  break;
192  case 1:
193  out[i][0] *= dp(alpha[l],in[l]);
194  break;
195  case 2:
196  out[i][0] *= ddp(alpha[l],in[l]);
197  break;
198  default:
199  DUNE_THROW(NotImplemented, "Desired derivative order is not implemented");
200  }
201  }
202  }
203  }
204 
206  unsigned int order () const
207  {
208  return k;
209  }
210  };
211 }
212 
213 #endif
A dense n x m matrix.
Definition: fmatrix.hh:68
vector space out of a tensor product of fields.
Definition: fvector.hh:93
Default exception for dummy implementations.
Definition: exceptions.hh:261
Lagrange shape functions of order k on the reference cube.
Definition: qklocalbasis.hh:35
void partial(const std::array< unsigned int, d > &order, const typename Traits::DomainType &in, std::vector< typename Traits::RangeType > &out) const
Evaluate partial derivatives of any order of all shape functions.
Definition: qklocalbasis.hh:169
void evaluateFunction(const typename Traits::DomainType &in, std::vector< typename Traits::RangeType > &out) const
Evaluate all shape functions.
Definition: qklocalbasis.hh:115
unsigned int size() const
number of shape functions
Definition: qklocalbasis.hh:109
void evaluateJacobian(const typename Traits::DomainType &in, std::vector< typename Traits::JacobianType > &out) const
Evaluate Jacobian of all shape functions.
Definition: qklocalbasis.hh:138
unsigned int order() const
Polynomial order of the shape functions.
Definition: qklocalbasis.hh:206
Various implementations of the power function for run-time and static arguments.
Implements a matrix constructed from a given type representing a field and compile-time given number ...
Implements a vector constructed from a given type representing a field and a compile-time given size.
#define DUNE_THROW(E, m)
Definition: exceptions.hh:216
Dune namespace.
Definition: alignedallocator.hh:10
Type traits for LocalBasisVirtualInterface.
Definition: localbasis.hh:32
D DomainType
domain type
Definition: localbasis.hh:43
Calculates m^p at compile time.
Definition: power.hh:20
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.80.0 (May 16, 22:29, 2024)