5#ifndef DUNE_LOCALFUNCTIONS_LAGRANGE_LAGRANGECUBE_HH
6#define DUNE_LOCALFUNCTIONS_LAGRANGE_LAGRANGECUBE_HH
23namespace Dune {
namespace Impl
26 template<
unsigned int dim,
int compileTimeOrder>
27 struct LagrangeCubeOrderTraits;
30 template<
unsigned int dim,
int compileTimeOrder>
31 requires (compileTimeOrder >= 0)
32 struct LagrangeCubeOrderTraits<dim,compileTimeOrder>
34 static constexpr bool is_static_order =
true;
36 constexpr LagrangeCubeOrderTraits(
int = compileTimeOrder) {}
43 return power(compileTimeOrder+1,
dim);
49 static constexpr unsigned int order ()
51 return compileTimeOrder;
58 for (
unsigned int j=0; j<
dim; j++)
60 alpha[j] = i % (order()+1);
68 template<
unsigned int dim>
69 struct LagrangeCubeOrderTraits<
dim,-1>
74 static constexpr bool is_static_order =
false;
79 constexpr LagrangeCubeOrderTraits (
int runTimeOrder)
80 : order_(runTimeOrder >= 0 ? (unsigned int)(runTimeOrder) : 0u)
98 constexpr unsigned int order ()
const
107 for (
unsigned int j=0; j<
dim; j++)
109 alpha[j] = i % (order()+1);
126 template<
class D,
class R,
unsigned int dim,
int compileTimeOrder>
127 class LagrangeCubeLocalBasis
128 :
private LagrangeCubeOrderTraits<dim,compileTimeOrder>
130 using OrderTraits = LagrangeCubeOrderTraits<dim,compileTimeOrder>;
133 constexpr R p (
unsigned int i, D x)
const
136 for (
unsigned int j=0; j<=order(); j++)
137 if (j!=i) result *= (order()*x-j)/((
int)i-(int)j);
142 constexpr R dp (
unsigned int i, D x)
const
146 for (
unsigned int j=0; j<=order(); j++)
150 R prod( (order()*1.0)/((
int)i-(
int)j) );
151 for (
unsigned int l=0; l<=order(); l++)
153 prod *= (order()*x-l)/((
int)i-(int)l);
162 constexpr R ddp(
unsigned int j, D x)
const
166 for (
unsigned int i=0; i<=order(); i++)
173 for (
unsigned int m=0; m<=order(); m++)
178 R prod( (order()*1.0)/((
int)j-(
int)m) );
179 for (
unsigned int l=0; l<=order(); l++)
180 if (l!=i && l!=j && l!=m)
181 prod *= (order()*x-l)/((
int)j-(int)l);
185 result += sum * ( (order()*1.0)/((
int)j-(int)i) );
191 using OrderTraits::multiindex;
194 using Traits = LocalBasisTraits<D,dim,FieldVector<D,dim>,R,1,FieldVector<R,1>,FieldMatrix<R,1,dim> >;
196 constexpr LagrangeCubeLocalBasis ()
requires (OrderTraits::is_static_order)
202 explicit constexpr LagrangeCubeLocalBasis (OrderTraits orderTraits)
203 : OrderTraits(orderTraits)
206 using OrderTraits::size;
207 using OrderTraits::order;
224 for (
size_t i=0; i<
size(); i++)
228 for (
unsigned int j=0; j<
dim; j++)
230 out[i] *= (i & (1<<j)) ? x[j] : 1-x[j];
236 for (
size_t i=0; i<
size(); i++)
245 for (
unsigned int j=0; j<
dim; j++)
246 out[i] *= p(alpha[j],x[j]);
271 for (
size_t i=0; i<
size(); i++)
274 for (
unsigned int j=0; j<
dim; j++)
278 out[i][0][j] = (i & (1<<j)) ? 1 : -1;
280 for (
unsigned int l=0; l<
dim; l++)
284 out[i][0][j] *= (i & (1<<l)) ? x[l] : 1-x[l];
294 for (
size_t i=0; i<
size(); i++)
300 for (
unsigned int j=0; j<
dim; j++)
304 out[i][0][j] = dp(alpha[j],x[j]);
307 for (
unsigned int l=0; l<
dim; l++)
309 out[i][0][j] *= p(alpha[l],x[l]);
330 out[0] = (totalOrder==0);
338 evaluateFunction(in, out);
340 else if (totalOrder == 1)
346 if (direction >=
dim)
347 DUNE_THROW(RangeError,
"Direction of partial derivative not found!");
354 out[i] = (i & (1<<direction)) ? 1 : -1;
356 for (
unsigned int j = 0; j <
dim; ++j)
360 out[i] *= (i & (1<<j)) ? in[j] : 1-in[j];
364 else if (totalOrder == 2)
367 for (
size_t i=0; i<
size(); i++)
378 switch (partialOrders[l])
381 out[i][0] *= p(alpha[l],in[l]);
385 out[i][0] *= dp(alpha[l],in[l]);
391 DUNE_THROW(NotImplemented,
"Desired derivative order is not implemented");
397 DUNE_THROW(NotImplemented,
"Partial derivative of order " << totalOrder <<
" is not implemented!");
405 for (
size_t i=0; i<
size(); i++)
416 switch (partialOrders[l])
419 out[i][0] *= p(alpha[l],in[l]);
422 out[i][0] *= dp(alpha[l],in[l]);
425 out[i][0] *= ddp(alpha[l],in[l]);
428 DUNE_THROW(NotImplemented,
"Desired derivative order is not implemented");
440 template<
unsigned int dim,
int compileTimeOrder>
441 class LagrangeCubeLocalCoefficients
442 :
private LagrangeCubeOrderTraits<dim,compileTimeOrder>
444 using OrderTraits = LagrangeCubeOrderTraits<dim,compileTimeOrder>;
446 using OrderTraits::multiindex;
451 const unsigned int k = order();
454 unsigned lastIndex=0;
461 subEntity[lastIndex++] = 0;
462 for (
unsigned i = 0; i < k - 1; ++i)
463 subEntity[lastIndex++] = 0;
465 subEntity[lastIndex++] = 1;
472 const unsigned int k = order();
475 unsigned lastIndex=0;
489 subEntity[lastIndex++] = 0;
490 for (
unsigned i = 0; i < k - 1; ++i)
491 subEntity[lastIndex++] = 2;
493 subEntity[lastIndex++] = 1;
496 for (
unsigned e = 0; e < k - 1; ++e) {
497 subEntity[lastIndex++] = 0;
498 for (
unsigned i = 0; i < k - 1; ++i)
499 subEntity[lastIndex++] = 0;
500 subEntity[lastIndex++] = 1;
504 subEntity[lastIndex++] = 2;
505 for (
unsigned i = 0; i < k - 1; ++i)
506 subEntity[lastIndex++] = 3;
508 subEntity[lastIndex++] = 3;
515 const unsigned int k = order();
518 unsigned lastIndex=0;
520 const unsigned numIndices =
power(k+1,
dim);
521 const unsigned numFaceIndices =
power(k+1,
dim-1);
523 const unsigned numInnerEdgeDofs = k-1;
544 subEntity[lastIndex++] = 0;
545 for (
unsigned i = 0; i < numInnerEdgeDofs; ++i)
546 subEntity[lastIndex++] = 6;
548 subEntity[lastIndex++] = 1;
551 for (
unsigned e = 0; e < numInnerEdgeDofs; ++e) {
552 subEntity[lastIndex++] = 4;
553 for (
unsigned i = 0; i < numInnerEdgeDofs; ++i)
554 subEntity[lastIndex++] = 4;
555 subEntity[lastIndex++] = 5;
559 subEntity[lastIndex++] = 2;
560 for (
unsigned i = 0; i < k - 1; ++i)
561 subEntity[lastIndex++] = 7;
562 subEntity[lastIndex++] = 3;
564 assert(numFaceIndices==lastIndex);
568 for(
unsigned f = 0; f < numInnerEdgeDofs; ++f) {
571 subEntity[lastIndex++] = 0;
572 for (
unsigned i = 0; i < numInnerEdgeDofs; ++i)
573 subEntity[lastIndex++] = 2;
574 subEntity[lastIndex++] = 1;
577 for (
unsigned e = 0; e < numInnerEdgeDofs; ++e) {
578 subEntity[lastIndex++] = 0;
579 for (
unsigned i = 0; i < numInnerEdgeDofs; ++i)
580 subEntity[lastIndex++] = 0;
581 subEntity[lastIndex++] = 1;
585 subEntity[lastIndex++] = 2;
586 for (
unsigned i = 0; i < numInnerEdgeDofs; ++i)
587 subEntity[lastIndex++] = 3;
588 subEntity[lastIndex++] = 3;
590 assert(lastIndex==(f+1+1)*numFaceIndices);
595 subEntity[lastIndex++] = 4;
596 for (
unsigned i = 0; i < k - 1; ++i)
597 subEntity[lastIndex++] = 10;
598 subEntity[lastIndex++] = 5;
601 for (
unsigned e = 0; e < k - 1; ++e) {
602 subEntity[lastIndex++] = 8;
603 for (
unsigned i = 0; i < k - 1; ++i)
604 subEntity[lastIndex++] = 5;
605 subEntity[lastIndex++] = 9;
609 subEntity[lastIndex++] = 6;
610 for (
unsigned i = 0; i < k - 1; ++i)
611 subEntity[lastIndex++] = 11;
612 subEntity[lastIndex++] = 7;
614 assert(numIndices==lastIndex);
621 const unsigned int k = order();
622 localKeys_.resize(
size());
626 localKeys_[0] = LocalKey(0,0,0);
633 localKeys_[i] = LocalKey(i,
dim,0);
649 for (
unsigned int j=0; j<
dim; j++)
650 if (mIdx[j]==0 or mIdx[j]==k)
667 for (
int j=
dim-1; j>=0; j--)
668 if (mIdx[j]>0 && mIdx[j]<k)
690 for (
size_t i=0; i<
size(); i++)
691 localKeys_[i] = LocalKey(subEntity[i], codim[i],
index[i]);
696 explicit LagrangeCubeLocalCoefficients (OrderTraits orderTraits)
697 : OrderTraits(orderTraits)
702 using OrderTraits::size;
703 using OrderTraits::order;
706 constexpr const LocalKey& localKey (
std::size_t i)
const
708 return localKeys_[i];
722 template<
class D,
class R,
unsigned int dim,
int compileTimeOrder>
723 class LagrangeCubeLocalInterpolation
724 :
private LagrangeCubeOrderTraits<dim, compileTimeOrder>
726 using OrderTraits = LagrangeCubeOrderTraits<dim, compileTimeOrder>;
727 using Traits =
typename LagrangeCubeLocalBasis<D,R,dim,compileTimeOrder>::Traits;
729 using OrderTraits::multiindex;
730 using OrderTraits::size;
731 using OrderTraits::order;
735 explicit constexpr LagrangeCubeLocalInterpolation (OrderTraits orderTraits)
736 : OrderTraits(orderTraits)
746 template<
typename F,
typename C>
747 constexpr void interpolate (
const F& f,
std::vector<C>& out)
const
749 const unsigned int k = order();
755 auto center = ReferenceElements<D,dim>::cube().position(0,0);
756 out[0] = Impl::rangeCast(f(center));
760 typename Traits::DomainType x;
765 for (
unsigned int i=0; i<
size(); i++)
768 for (
unsigned int j=0; j<
dim; j++)
769 x[j] = (i & (1<<j)) ? 1.0 : 0.0;
771 out[i] = Impl::rangeCast(f(x));
777 for (
unsigned int i=0; i<
size(); i++)
783 for (
unsigned int j=0; j<
dim; j++)
784 x[j] = (1.0*alpha[j])/k;
786 out[i] = Impl::rangeCast(f(x));
803 template<
class D,
class R,
int dim,
int compileTimeOrder = -1>
805 :
private Impl::LagrangeCubeOrderTraits<dim, compileTimeOrder>
807 using OrderTraits = Impl::LagrangeCubeOrderTraits<dim, compileTimeOrder>;
813 Impl::LagrangeCubeLocalBasis<D,R,dim,compileTimeOrder>,
814 Impl::LagrangeCubeLocalCoefficients<dim,compileTimeOrder>,
815 Impl::LagrangeCubeLocalInterpolation<D,R,dim,compileTimeOrder> >;
821 , coefficients_(*this)
822 , interpolation_(*this)
824 static_assert(OrderTraits::is_static_order,
"Default constructor only allowed for compile-time order >= 0");
825 static_assert(compileTimeOrder >= 0,
"Default constructor only allowed for compile-time order >= 0");
830 : OrderTraits(runTimeOrder)
832 , coefficients_(*this)
833 , interpolation_(*this)
835 if (runTimeOrder < 0)
837 if (compileTimeOrder >= 0 && compileTimeOrder != runTimeOrder)
852 return coefficients_;
859 return interpolation_;
863 using OrderTraits::size;
869 return GeometryTypes::cube(
dim);
std::ptrdiff_t index() const
#define DUNE_THROW(E,...)
constexpr Base power(Base m, Exponent p)
D DomainType
domain type
Definition common/localbasis.hh:43
traits helper struct
Definition localfiniteelementtraits.hh:13
LB LocalBasisType
Definition localfiniteelementtraits.hh:16
LC LocalCoefficientsType
Definition localfiniteelementtraits.hh:20
LI LocalInterpolationType
Definition localfiniteelementtraits.hh:24
Lagrange finite element for cubes with arbitrary compile-time dimension and polynomial order.
Definition lagrangecube.hh:806
constexpr const Traits::LocalInterpolationType & localInterpolation() const
Returns object that evaluates degrees of freedom.
Definition lagrangecube.hh:857
constexpr LagrangeCubeLocalFiniteElement(int runTimeOrder)
Constructor for dynamic order.
Definition lagrangecube.hh:829
static constexpr GeometryType type()
The reference element that the local finite element is defined on.
Definition lagrangecube.hh:867
constexpr const Traits::LocalBasisType & localBasis() const
Returns the local basis, i.e., the set of shape functions.
Definition lagrangecube.hh:843
constexpr const Traits::LocalCoefficientsType & localCoefficients() const
Returns the assignment of the degrees of freedom to the element subentities.
Definition lagrangecube.hh:850
constexpr LagrangeCubeLocalFiniteElement()
Constructor for static order.
Definition lagrangecube.hh:818