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
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
19namespace 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.111.3 (Jul 15, 22:36, 2024)