5#ifndef DUNE_HIERARCHICAL_SIMPLEX_P2_WITH_ELEMENT_BUBBLE_LOCALBASIS_HH
6#define DUNE_HIERARCHICAL_SIMPLEX_P2_WITH_ELEMENT_BUBBLE_LOCALBASIS_HH
45 template<
class D,
class R,
int dim>
60 static constexpr int numVertices =
dim+1;
63 static constexpr int numEdges = (
dim > 1 ? ((
dim+1)*
dim / 2) : 0);
67 static constexpr It evaluateVertexFunctions (
const DomainType& in, It outIt)
70 for (
int i = 0; i <
dim; ++i)
73 for (
int i = 0; i <
dim; ++i)
80 static constexpr It evaluateAllFunctions (
const DomainType& in, It outIt)
82 It vertexValues = outIt;
83 outIt = evaluateVertexFunctions(in, outIt);
85 if constexpr(
dim > 1) {
86 auto refElem = referenceElement<D,dim>(GeometryTypes::simplex(
dim));
87 for (
int i = 0; i < numEdges; ++i) {
88 const int v0 = refElem.subEntity(i,
dim-1,0,
dim);
89 const int v1 = refElem.subEntity(i,
dim-1,1,
dim);
90 *outIt++ = 4 * vertexValues[v0] * vertexValues[v1];
96 for (
int i = 0; i < numVertices; ++i)
97 *outIt *= Impl::rangeCast(vertexValues[i]);
108 return numVertices + numEdges + 1;
116 evaluateAllFunctions(in,out.
begin());
127 for (
int i = 0; i <
dim; ++i) {
129 for (
int j = 0; j <
dim; ++j)
130 out[j+1][0][i] = (i == j);
136 evaluateVertexFunctions(in, shapeValues.
begin());
139 if constexpr(
dim > 1) {
140 auto refElem = referenceElement<D,dim>(GeometryTypes::simplex(
dim));
141 for (
int i = 0; i < numEdges; ++i,++n) {
142 const int v0 = refElem.subEntity(i,
dim-1,0,
dim);
143 const int v1 = refElem.subEntity(i,
dim-1,1,
dim);
144 for (
int j = 0; j <
dim; ++j)
145 out[n][0][j] = 4 * (out[v0][0][j] * shapeValues[v1][0] + shapeValues[v0][0] * out[v1][0][j]);
150 for (
int i = 0; i <
dim; ++i) {
151 out[n][0][i] =
power(
dim+1,
dim+1) * (tmp - in[i]);
152 for (
int j = i+1; j <
dim+i; ++j)
153 out[n][0][i] *= in[j %
dim];
162 unsigned int totalOrder = 0;
163 for (
int i = 0; i <
dim; ++i)
164 totalOrder +=
order[i];
166 switch (totalOrder) {
173 for (
int i = 0; i <
dim; ++i)
178 for (
int i = 0; i <
dim; ++i) {
180 for (
int j = 0; j <
dim; ++j)
181 out[j+1] = (
dim == j);
187 evaluateVertexFunctions(in, shapeValues.
begin());
190 if constexpr(
dim > 1) {
191 auto refElem = referenceElement<D,dim>(GeometryTypes::simplex(
dim));
192 for (
int i = 0; i < numEdges; ++i,++n) {
193 const int v0 = refElem.subEntity(i,
dim-1,0,
dim);
194 const int v1 = refElem.subEntity(i,
dim-1,1,
dim);
195 out[n] = 4 * (out[v0] * shapeValues[v1] + shapeValues[v0] * out[v1]);
201 for (
int j = d+1; j <
dim+d; ++j)
202 out[n] *= in[j %
dim];
210 static constexpr unsigned int order () noexcept
232 static constexpr int numVertices =
dim+1;
235 static constexpr int numEdges = (
dim > 1 ? ((
dim+1)*
dim / 2) : 0);
242 for (
int i = 0; i < numVertices; ++i)
244 if constexpr(
dim > 1) {
245 for (
int i = 0; i < numEdges; ++i)
254 return numVertices + numEdges + 1;
270 template<
class LB,
int dim>
273 using LocalBasis = LB;
274 using DomainType =
typename LB::Traits::DomainType;
275 using RangeType =
typename LB::Traits::RangeType;
278 static constexpr int numVertices =
dim+1;
281 static constexpr int numEdges = (
dim > 1 ? ((
dim+1)*
dim / 2) : 0);
291 template<
class F,
class C>
292 requires (
requires (
const F& f,
const DomainType& x, C& y){ y = Impl::rangeCast(f(x)); } )
295 auto refElem = referenceElement<typename LB::Traits::DomainFieldType,dim>(GeometryTypes::simplex(
dim));
301 assert(numVertices == refElem.size(
dim));
302 for (
int i = 0; i < numVertices; ++i)
303 out[n++] = Impl::rangeCast(f(refElem.position(i,
dim)));
308 if constexpr(
dim > 1) {
309 assert(numEdges == refElem.size(
dim-1));
310 for (
int i = 0; i < numEdges; ++i) {
311 auto y = Impl::rangeCast(f(refElem.position(i,
dim-1)));
312 LB::evaluateVertexFunctions(refElem.position(i,
dim-1), shapeValues.
begin());
313 for (
int j = 0; j < numVertices; ++j)
314 y -= out[j]*shapeValues[j][0];
320 auto y = Impl::rangeCast(f(refElem.position(0,0)));
321 LB::evaluateAllFunctions(refElem.position(0,0), shapeValues.
begin());
322 for (
int j = 0; j < numVertices+numEdges; ++j)
323 y -= out[j]*shapeValues[j][0];
constexpr Base power(Base m, Exponent p)
Type traits for LocalBasisVirtualInterface.
Definition common/localbasis.hh:35
Describe position of one degree of freedom.
Definition localkey.hh:24
P1 basis in dim-d enriched by quadratic edge bubble functions and an element bubble function of order...
Definition hierarchicalsimplexp2withelementbubble.hh:47
static constexpr void evaluateFunction(const DomainType &in, std::vector< RangeType > &out)
Evaluate all shape functions.
Definition hierarchicalsimplexp2withelementbubble.hh:112
static constexpr void partial(const std::array< unsigned int, dim > &order, const DomainType &in, std::vector< RangeType > &out)
Evaluate partial derivatives of all shape functions.
Definition hierarchicalsimplexp2withelementbubble.hh:158
static constexpr unsigned int order() noexcept
Polynomial order of the shape functions (4 in this case)
Definition hierarchicalsimplexp2withelementbubble.hh:210
static constexpr void evaluateJacobian(const DomainType &in, std::vector< JacobianType > &out)
Evaluate Jacobian of all shape functions.
Definition hierarchicalsimplexp2withelementbubble.hh:120
static constexpr std::size_t size() noexcept
Returns number of shape functions.
Definition hierarchicalsimplexp2withelementbubble.hh:106
The local keys of the hierarchical basis functions with element bubble.
Definition hierarchicalsimplexp2withelementbubble.hh:230
HierarchicalSimplexP2WithElementBubbleLocalCoefficients() noexcept
Default constructor, initializes the local keys.
Definition hierarchicalsimplexp2withelementbubble.hh:239
static constexpr std::size_t size() noexcept
Returns number of coefficients.
Definition hierarchicalsimplexp2withelementbubble.hh:252
const LocalKey & localKey(std::size_t i) const noexcept
Returns the i'th local key.
Definition hierarchicalsimplexp2withelementbubble.hh:258
Definition hierarchicalsimplexp2withelementbubble.hh:272
static constexpr void interpolate(const F &f, std::vector< C > &out)
Local interpolation of the function f.
Definition hierarchicalsimplexp2withelementbubble.hh:293