6#ifndef DUNE_FUNCTIONS_FUNCTIONSPACEBASES_ARGYRISBASIS_HH
7#define DUNE_FUNCTIONS_FUNCTIONSPACEBASES_ARGYRISBASIS_HH
12#include <dune/common/exceptions.hh>
13#include <dune/common/fmatrix.hh>
14#include <dune/common/fvector.hh>
15#include <dune/common/rangeutilities.hh>
17#include <dune/grid/common/mcmgmapper.hh>
19#include <dune/localfunctions/common/localbasis.hh>
20#include <dune/localfunctions/common/localfiniteelementtraits.hh>
21#include <dune/localfunctions/common/localkey.hh>
23#include <dune/functions/analyticfunctions/monomialset.hh>
24#include <dune/functions/common/mapperutilities.hh>
26#include <dune/functions/functionspacebases/defaultglobalbasis.hh>
27#include <dune/functions/functionspacebases/functionaldescriptor.hh>
28#include <dune/functions/functionspacebases/leafprebasismappermixin.hh>
29#include <dune/functions/functionspacebases/nodes.hh>
30#include <dune/functions/functionspacebases/transformedfiniteelementmixin.hh>
45namespace Dune::Functions
48 template<
class GV,
class R>
49 class ArgyrisPreBasis;
68 template<
class GV,
class R =
double>
76 class ArgyrisLocalCoefficients
79 using size_type = std::size_t;
80 static constexpr int dim = 2;
82 ArgyrisLocalCoefficients()
84 for (
unsigned int i = 0; i < 3; i++)
85 for (
unsigned int k = 0; k < 6; k++)
87 = LocalKey(i, dim, k);
88 for (
unsigned int i = 0; i < 3; ++i)
89 localKeys_[18 + i] = LocalKey(i, dim - 1, 0);
94 static constexpr size_type size()
101 LocalKey
const &localKey(size_type i)
const
103 return localKeys_[i];
107 std::array<Dune::LocalKey, 21> localKeys_;
116 template<
class D,
class R>
117 class ArgyrisReferenceLocalBasis
119 static constexpr int dim = 2;
121 using Traits = H2LocalBasisTraits<D, dim, FieldVector<D, dim>, R, 1, FieldVector<R, 1>,
122 FieldMatrix<R, 1, dim>, FieldMatrix<R, dim, dim> >;
139 static constexpr auto getArgyrisCoefficients()
143 D sqrt2 = -8. * 1.414213562373095;
144 return Dune::FieldMatrix<D, 21,21>{
152 -6, 0, 30, 30, 0, -6},
159 -3, 0, 1, -10, -8, 0},
167 0, -8, -10, 1, 0, -3},
175 -0.5, 0, 1.5, 1, 0, 0},
183 0, -2, -6, -6, -2, 0},
191 0, 0, 1, 1.5, 0, -0.5},
198 6, 0, -15, -15, 0, 0},
205 -3, 0, 3.5, 3.5, 0, 0},
212 0, -8, -18.5, -13.5, 0, 0},
220 0.5, 0, -0.25, -0.25, 0, 0},
228 0, 2, 3.5, 2.5, 0, 0},
236 0, 0, -0.75, -1.25, 0, 0},
244 0, 0, -15, -15, 0, 6},
252 0, 0, -13.5, -18.5, -8, 0},
260 0, 0, 3.5, 3.5, 0, -3},
268 0, 0, -1.25, -0.75, 0, 0},
276 0, 0, 2.5, 3.5, 2, 0},
284 0, 0, -0.25, -0.25, 0, 0.5},
293 0, 16, 32, 16, 0, 0},
301 0, 0, -16, -32, -16, 0},
308 0, 0, -1. * sqrt2, 0, 0,
309 0, 0, sqrt2, sqrt2, 0, 0}};
313 static constexpr auto referenceBasisCoefficients = getArgyrisCoefficients();
320 static constexpr unsigned int size()
322 return ArgyrisLocalCoefficients::size();
327 static constexpr unsigned int order()
337 void evaluateFunction(
const typename Traits::DomainType &in,
338 std::vector<typename Traits::RangeType> &out)
const
341 auto monomialValues = monomials(in);
342 multiplyWithCoefficentMatrix(referenceBasisCoefficients, monomialValues, out);
350 void evaluateJacobian(
const typename Traits::DomainType &in,
351 std::vector<typename Traits::JacobianType> &out)
const
354 auto monomialValues =
derivative(monomials)(in);
355 multiplyWithCoefficentMatrix(referenceBasisCoefficients, monomialValues, out);
363 void evaluateHessian(
const typename Traits::DomainType &in,
364 std::vector<typename Traits::HessianType> &out)
const
368 multiplyWithCoefficentMatrix(referenceBasisCoefficients, monomialValues, out);
377 void partial(std::array<unsigned int, dim> order,
const typename Traits::DomainType &in,
378 std::vector<typename Traits::RangeType> &out)
const
381 auto totalOrder = std::accumulate(order.begin(), order.end(), 0);
383 evaluateFunction(in, out);
384 else if (totalOrder == 1)
386 evaluateJacobian(in,jacobiansBuffer_);
387 std::size_t which = std::max_element(order.begin(), order.end()) - order.begin();
388 for (
auto i : Dune::range(size()))
389 out[i] = jacobiansBuffer_[i][0][which];
391 else if (totalOrder == 2)
393 evaluateHessian(in, hessianBuffer_);
394 std::size_t first, second;
395 first = std::max_element(order.begin(), order.end()) - order.begin();
396 if (order[first] == 2)
401 second = std::max_element(order.begin(), order.end()) - order.begin();
403 for (
auto i : Dune::range(size()))
404 out[i] = hessianBuffer_[i][first][second];
407 DUNE_THROW(RangeError,
"partial() not implemented for given order");
411 mutable std::vector<typename Traits::JacobianType> jacobiansBuffer_;
412 mutable std::vector<typename Traits::HessianType> hessianBuffer_;
422 class ArgyrisLocalInterpolation
424 using size_type = std::size_t;
425 static constexpr int dim = 2;
427 static constexpr unsigned int size()
429 return ArgyrisLocalCoefficients::size();
432 using FunctionalDescriptor = Dune::Functions::Impl::FunctionalDescriptor<dim>;
436 ArgyrisLocalInterpolation()
440 descriptors_[0] = FunctionalDescriptor();
442 descriptors_[1] = FunctionalDescriptor({1,0});
443 descriptors_[2] = FunctionalDescriptor({0,1});
445 descriptors_[3] = FunctionalDescriptor({2,0});
446 descriptors_[4] = FunctionalDescriptor({1,1});
447 descriptors_[5] = FunctionalDescriptor({0,2});
449 descriptors_[6] = FunctionalDescriptor();
450 descriptors_[7] = FunctionalDescriptor({1,0});
451 descriptors_[8] = FunctionalDescriptor({0,1});
452 descriptors_[9] = FunctionalDescriptor({2,0});
453 descriptors_[10] = FunctionalDescriptor({1,1});
454 descriptors_[11] = FunctionalDescriptor({0,2});
456 descriptors_[12] = FunctionalDescriptor();
457 descriptors_[13] = FunctionalDescriptor({1,0});
458 descriptors_[14] = FunctionalDescriptor({0,1});
459 descriptors_[15] = FunctionalDescriptor({2,0});
460 descriptors_[16] = FunctionalDescriptor({1,1});
461 descriptors_[17] = FunctionalDescriptor({0,2});
463 descriptors_[18] = FunctionalDescriptor(1);
464 descriptors_[19] = FunctionalDescriptor(1);
465 descriptors_[20] = FunctionalDescriptor(1);
470 template<
class Element>
471 void bind( Element
const& element, std::array<D, 3>
const& averageVertexMeshSize, std::bitset<3>
const& edgeOrientation)
473 averageVertexMeshSize_ = &averageVertexMeshSize;
475 auto geometry = element.geometry();
478 auto refElement = Dune::referenceElement<D, 2>(geometry.type());
479 for (std::size_t i = 0; i < 3; ++i)
481 localVertices_[i] = refElement.position(i, 2);
483 localMidpoints_[i] = refElement.position(i, 1);
484 std::size_t lower = (i == 2) ? 1 : 0;
485 std::size_t upper = (i == 0) ? 1 : 2;
487 auto edge = geometry.global(refElement.position(upper, 2))
488 - geometry.global(refElement.position(lower, 2));
490 edge /= edge.two_norm() * (edgeOrientation[i] ? -1. : 1.);
492 globalNormals_[i] = {-edge[1], edge[0]};
503 template<
class F,
class C>
504 void interpolate(F
const& f, std::vector<C>& out)
const
512 for (
int i = 0; i < 3; i++, offset += 6)
514 auto&& x = localVertices_[i];
515 auto derivativeValue = squeezeTensor(df(x));
516 auto hessianValue = squeezeTensor(Hf(x));
517 auto && h = (*averageVertexMeshSize_)[i];
521 out[offset + 1] = derivativeValue[0] * h;
522 out[offset + 2] = derivativeValue[1] * h;
524 out[offset + 3] = hessianValue[0][0] * h*h;
525 out[offset + 4] = hessianValue[0][1] * h*h;
526 out[offset + 5] = hessianValue[1][1] * h*h;
529 for (
int i = 0; i < 3; i++)
530 out[18 + i] = squeezeTensor(df(localMidpoints_[i])).dot(globalNormals_[i]);
537 const FunctionalDescriptor& functionalDescriptor(size_type i)
const
539 return descriptors_[i];
543 std::array<Dune::FieldVector<D, 2>, 3> globalNormals_;
544 std::array<Dune::FieldVector<D, 2>, 3> localMidpoints_;
545 std::array<Dune::FieldVector<D, 2>, 3> localVertices_;
546 std::array<D, 3>
const* averageVertexMeshSize_;
547 std::array<FunctionalDescriptor, size()> descriptors_;
551 template<
class D,
class R>
552 struct ArgyrisLocalBasisTraits
553 :
public H2LocalBasisTraits<D, 2, Dune::FieldVector<D,2>, R, 1,
554 Dune::FieldVector<R,1>, Dune::FieldMatrix<R,1,2>, Dune::FieldMatrix<R,2,2> >
566 template<
class D,
class R>
567 class ArgyrisLocalFiniteElement
568 :
public Impl::TransformedFiniteElementMixin<ArgyrisLocalFiniteElement<D,R>, ArgyrisLocalBasisTraits<D, R> >
570 using Base = Impl::TransformedFiniteElementMixin< ArgyrisLocalFiniteElement<D,R>, ArgyrisLocalBasisTraits<D, R> >;
571 friend class Impl::TransformedLocalBasis<ArgyrisLocalFiniteElement<D,R>, ArgyrisLocalBasisTraits<D, R> >;
572 static constexpr int dim = 2;
577 using size_type = std::size_t;
578 using Traits = LocalFiniteElementTraits<
579 Impl::TransformedLocalBasis<ArgyrisLocalFiniteElement<D,R>, ArgyrisLocalBasisTraits<D, R> >,
580 Impl::ArgyrisLocalCoefficients,
581 Impl::ArgyrisLocalInterpolation<D> >;
586 const typename Traits::LocalCoefficientsType &localCoefficients()
const
588 return coefficients_;
593 const typename Traits::LocalInterpolationType &localInterpolation()
const
595 return interpolation_;
600 static constexpr GeometryType type()
602 return GeometryTypes::simplex(dim);
607 static constexpr size_type size()
609 return Impl::ArgyrisLocalCoefficients::size();
614 template<
class VertexMapper,
class ElementMapper,
class Element>
615 void bind(VertexMapper
const& vertexMapper, std::vector<D>
const& globalAverageVertexMeshSize,
616 ElementMapper
const& elementMapper, std::vector<std::bitset<3> >
const& edgeOrientations, Element
const &e)
619 for (
auto i : range(dim+1))
620 averageVertexMeshSize_[i] = globalAverageVertexMeshSize[vertexMapper.subIndex(e, i, dim)];
623 edgeOrientation_ = edgeOrientations[elementMapper.index(e)];
626 interpolation_.bind(e, averageVertexMeshSize_, edgeOrientation_);
629 const auto& geometry = e.geometry();
630 const auto& refElement = ReferenceElements<typename Element::Geometry::ctype, dim>::simplex();
631 for (
auto i : range(dim+1))
633 vertexJacobians_[i] = geometry.jacobian(refElement.position(i, dim));
637 std::array<FieldVector<R, 2>, 3> referenceTangents;
640 for (std::size_t i = 0; i < 3; ++i)
642 std::size_t lower = (i == 2) ? 1 : 0;
643 std::size_t upper = (i == 0) ? 1 : 2;
644 auto edge = refElement.position(upper, 2) - refElement.position(lower, 2);
647 referenceTangents[i] = edge / edge.two_norm();
649 auto globalEdge = geometry.global(refElement.position(upper, 2))
650 - geometry.global(refElement.position(lower, 2));
653 l[i] = globalEdge.two_norm();
654 globalTangents[i] = globalEdge / l[i];
656 tau[i] = FieldVector<R, 3>{
657 globalTangents[i][0] * globalTangents[i][0],
658 2. * globalTangents[i][0] * globalTangents[i][1],
659 globalTangents[i][1] * globalTangents[i][1]
664 auto&& referenceG = FieldMatrix<R, 2, 2>{
665 {-referenceTangents[i][1], referenceTangents[i][0]},
666 {referenceTangents[i][0], referenceTangents[i][1]}
669 auto&& globalG = FieldMatrix<R, 2, 2>{
670 {-globalTangents[i][1], globalTangents[i][0]},
671 {globalTangents[i][0], globalTangents[i][1]}
675 b[i] = globalG * geometry.jacobian(refElement.position(i, 2)) * referenceG;
677 theta[i][0][0] = vertexJacobians_[i][0][0] * vertexJacobians_[i][0][0];
678 theta[i][0][1] = vertexJacobians_[i][0][0] * vertexJacobians_[i][0][1];
679 theta[i][0][2] = vertexJacobians_[i][0][1] * vertexJacobians_[i][0][1];
681 theta[i][1][0] = 2. * vertexJacobians_[i][0][0] * vertexJacobians_[i][1][0];
682 theta[i][1][1] = vertexJacobians_[i][0][0] * vertexJacobians_[i][1][1] + vertexJacobians_[i][0][1] * vertexJacobians_[i][1][0];
683 theta[i][1][2] = 2. * vertexJacobians_[i][0][1] * vertexJacobians_[i][1][1];
685 theta[i][2][0] = vertexJacobians_[i][1][0] * vertexJacobians_[i][1][0];
686 theta[i][2][1] = vertexJacobians_[i][1][0] * vertexJacobians_[i][1][1];
687 theta[i][2][2] = vertexJacobians_[i][1][1] * vertexJacobians_[i][1][1];
695 Impl::ArgyrisReferenceLocalBasis<D, R>
const& referenceLocalBasis()
const
704 template<
class InputValues,
class OutputValues>
705 void transform(InputValues
const &inValues, OutputValues &outValues)
const
708 assert(inValues.size() == size());
709 assert(outValues.size() == inValues.size());
711 auto &[b_0, b_1, b_2] = b;
712 auto &[J_0, J_1, J_2] = vertexJacobians_;
713 auto &[theta_0, theta_1, theta_2] = theta;
714 auto & h = averageVertexMeshSize_;
715 auto & o = edgeOrientation_;
716 std::array<Dune::FieldVector<R, 2>, 3>
const &t = globalTangents;
719 outValues[0] = -15.0/8.0*b_0[1][0]*inValues[18]/l[0] - 15.0/8.0*b_1[1][0]*inValues[19]/l[1] + inValues[0];
720 outValues[1] = (J_0[0][0]*inValues[1] + J_0[0][1]*inValues[2] - 0.4375*b_0[1][0]*inValues[18]*t[0][0] - 0.4375*b_1[1][0]*inValues[19]*t[1][0])/h[0];
721 outValues[2] = (J_0[1][0]*inValues[1] + J_0[1][1]*inValues[2] - 0.4375*b_0[1][0]*inValues[18]*t[0][1] - 0.4375*b_1[1][0]*inValues[19]*t[1][1])/h[0];
722 outValues[3] = (-1.0/32.0*b_0[1][0]*inValues[18]*l[0]*tau[0][0] - 1.0/32.0*b_1[1][0]*inValues[19]*l[1]*tau[1][0] + inValues[3]*theta_0[0][0] + inValues[4]*theta_0[0][1] + inValues[5]*theta_0[0][2])/h[0] /h[0];
723 outValues[4] = (-1.0/32.0*b_0[1][0]*inValues[18]*l[0]*tau[0][1] - 1.0/32.0*b_1[1][0]*inValues[19]*l[1]*tau[1][1] + inValues[3]*theta_0[1][0] + inValues[4]*theta_0[1][1] + inValues[5]*theta_0[1][2])/h[0] /h[0];
724 outValues[5] = (-1.0/32.0*b_0[1][0]*inValues[18]*l[0]*tau[0][2] - 1.0/32.0*b_1[1][0]*inValues[19]*l[1]*tau[1][2] + inValues[3]*theta_0[2][0] + inValues[4]*theta_0[2][1] + inValues[5]*theta_0[2][2])/h[0] /h[0];
725 outValues[6] = (15.0/8.0)*b_0[1][0]*inValues[18]/l[0] - 15.0/8.0*b_2[1][0]*inValues[20]/l[2] + inValues[6];
726 outValues[7] = (J_1[0][0]*inValues[7] + J_1[0][1]*inValues[8] - 0.4375*b_0[1][0]*inValues[18]*t[0][0] - 0.4375*b_2[1][0]*inValues[20]*t[2][0])/h[1];
727 outValues[8] = (J_1[1][0]*inValues[7] + J_1[1][1]*inValues[8] - 0.4375*b_0[1][0]*inValues[18]*t[0][1] - 0.4375*b_2[1][0]*inValues[20]*t[2][1])/h[1];
728 outValues[9] = ((1.0/32.0)*b_0[1][0]*inValues[18]*l[0]*tau[0][0] - 1.0/32.0*b_2[1][0]*inValues[20]*l[2]*tau[2][0] + inValues[9]*theta_1[0][0] + inValues[10]*theta_1[0][1] + inValues[11]*theta_1[0][2])/h[1] /h[1];
729 outValues[10] = ((1.0/32.0)*b_0[1][0]*inValues[18]*l[0]*tau[0][1] - 1.0/32.0*b_2[1][0]*inValues[20]*l[2]*tau[2][1] + inValues[9]*theta_1[1][0] + inValues[10]*theta_1[1][1] + inValues[11]*theta_1[1][2])/h[1] /h[1];
730 outValues[11] = ((1.0/32.0)*b_0[1][0]*inValues[18]*l[0]*tau[0][2] - 1.0/32.0*b_2[1][0]*inValues[20]*l[2]*tau[2][2] + inValues[9]*theta_1[2][0] + inValues[10]*theta_1[2][1] + inValues[11]*theta_1[2][2])/h[1] /h[1];
731 outValues[12] = (15.0/8.0)*b_1[1][0]*inValues[19]/l[1] + (15.0/8.0)*b_2[1][0]*inValues[20]/l[2] + inValues[12];
732 outValues[13] = (J_2[0][0]*inValues[13] + J_2[0][1]*inValues[14] - 0.4375*b_1[1][0]*inValues[19]*t[1][0] - 0.4375*b_2[1][0]*inValues[20]*t[2][0])/h[2];
733 outValues[14] = (J_2[1][0]*inValues[13] + J_2[1][1]*inValues[14] - 0.4375*b_1[1][0]*inValues[19]*t[1][1] - 0.4375*b_2[1][0]*inValues[20]*t[2][1])/h[2];
734 outValues[15] = ((1.0/32.0)*b_1[1][0]*inValues[19]*l[1]*tau[1][0] + (1.0/32.0)*b_2[1][0]*inValues[20]*l[2]*tau[2][0] + inValues[15]*theta_2[0][0] + inValues[16]*theta_2[0][1] + inValues[17]*theta_2[0][2])/h[2] /h[2];
735 outValues[16] = ((1.0/32.0)*b_1[1][0]*inValues[19]*l[1]*tau[1][1] + (1.0/32.0)*b_2[1][0]*inValues[20]*l[2]*tau[2][1] + inValues[15]*theta_2[1][0] + inValues[16]*theta_2[1][1] + inValues[17]*theta_2[1][2])/h[2] /h[2];
736 outValues[17] = ((1.0/32.0)*b_1[1][0]*inValues[19]*l[1]*tau[1][2] + (1.0/32.0)*b_2[1][0]*inValues[20]*l[2]*tau[2][2] + inValues[15]*theta_2[2][0] + inValues[16]*theta_2[2][1] + inValues[17]*theta_2[2][2])/h[2] /h[2];
737 outValues[18] = b_0[0][0]*inValues[18]*(o[0] ? -1 : 1);
738 outValues[19] = b_1[0][0]*inValues[19]*(o[1] ? -1 : 1);
739 outValues[20] = b_2[0][0]*inValues[20]*(o[2] ? -1 : 1);
743 typename Impl::ArgyrisReferenceLocalBasis<D, R> basis_;
744 typename Traits::LocalCoefficientsType coefficients_;
745 typename Traits::LocalInterpolationType interpolation_;
751 std::array<Dune::FieldMatrix<R, dim, dim>, dim+1> vertexJacobians_;
753 std::array<FieldMatrix<R, 3, 3>, 3> theta;
757 std::array<FieldVector<R, 2>, 3> globalTangents;
759 std::array<FieldVector<R, 3>, 3> tau;
760 std::array<FieldMatrix<R, 2, 2>, 3> b;
763 std::array<D, dim+1> averageVertexMeshSize_;
764 std::bitset<3> edgeOrientation_;
783 template<
class GV,
class R>
785 :
public LeafBasisNode
787 using Mapper = Dune::MultipleCodimMultipleGeomTypeMapper<GV>;
790 using size_type = std::size_t;
791 using Element =
typename GV::template Codim<0>::Entity;
792 using FiniteElement =
typename Impl::ArgyrisLocalFiniteElement<typename GV::ctype, R>;
794 ArgyrisNode(Mapper
const& vertexMapper, Mapper
const& elementMapper,
795 std::vector<typename GV::ctype>
const& averageVertexMeshSize,
796 std::vector<std::bitset<3> >
const& edgeOrientation)
798 , vertexMapper_(&vertexMapper)
799 , elementMapper_(&elementMapper)
800 , averageVertexMeshSize_(&averageVertexMeshSize)
801 , edgeOrientation_(&edgeOrientation)
805 Element
const &element()
const
815 FiniteElement
const &finiteElement()
const
817 return finiteElement_;
821 void bind(Element
const &e)
824 finiteElement_.bind(*vertexMapper_, *averageVertexMeshSize_,
825 *elementMapper_,* edgeOrientation_,
827 this->setSize(finiteElement_.size());
832 unsigned int order()
const {
return finiteElement_.localBasis().order(); }
835 FiniteElement finiteElement_;
836 Element
const* element_;
837 Mapper
const* vertexMapper_;
838 Mapper
const* elementMapper_;
839 std::vector<typename GV::ctype>
const* averageVertexMeshSize_;
840 std::vector<std::bitset<3> >
const* edgeOrientation_;
853 template<
class GV,
class R>
858 using SubEntityMapper = Dune::MultipleCodimMultipleGeomTypeMapper<GV>;
859 using Element =
typename GV::template Codim<0>::Entity;
860 using D =
typename GV::ctype;
861 static const std::size_t dim = GV::dimension;
864 static constexpr auto ArgyrisMapperLayout(Dune::GeometryType type,
int gridDim)
866 assert(gridDim == 2);
869 else if (type.isLine())
871 else if (type.isTriangle())
874 DUNE_THROW(Dune::Exception,
"Invalid Geometry type for Argyris Element!");
886 using Node = ArgyrisNode<GridView, R>;
892 :
Base(gv, ArgyrisMapperLayout)
893 , vertexMapper_({gv, mcmgVertexLayout()})
894 , elementMapper_({gv, mcmgElementLayout()})
896 averageVertexMeshSize_ = Impl::computeAverageSubEntityMeshSize<D>(vertexMapper_);
897 edgeOrientations_ = Impl::computeEdgeOrientations(elementMapper_);
904 vertexMapper_.update(this->
gridView());
905 elementMapper_.update(this->
gridView());
906 averageVertexMeshSize_ = Impl::computeAverageSubEntityMeshSize<D>(vertexMapper_);
907 edgeOrientations_ = Impl::computeEdgeOrientations(elementMapper_);
913 return Node{vertexMapper_, elementMapper_, averageVertexMeshSize_, edgeOrientations_};
918 SubEntityMapper vertexMapper_;
919 std::vector<D> averageVertexMeshSize_;
920 SubEntityMapper elementMapper_;
921 std::vector<std::bitset<3> > edgeOrientations_;
925 namespace BasisFactory
935 template<
class R =
double>
938 return [=](
auto const &gridView) {
939 return ArgyrisPreBasis<std::decay_t<
decltype(gridView)>, R>(gridView);
A pre-basis for a Argyrisbasis.
Definition: argyrisbasis.hh:856
Node makeNode() const
Create tree node.
Definition: argyrisbasis.hh:911
GV GridView
The grid view that the FE basis is defined on.
Definition: argyrisbasis.hh:880
ArgyrisNode< GridView, R > Node
Template mapping root tree path to type of created tree node.
Definition: argyrisbasis.hh:886
void update(GridView const &gv)
Update the stored grid view, to be called if the grid has changed.
Definition: argyrisbasis.hh:901
ArgyrisPreBasis(const GV &gv)
Constructor for a given grid view object.
Definition: argyrisbasis.hh:891
std::size_t size_type
Type used for indices and size information.
Definition: argyrisbasis.hh:883
Global basis for given pre-basis.
Definition: defaultglobalbasis.hh:53
A generic MixIn class for PreBasis with flat indices computed from a mapper.
Definition: leafprebasismappermixin.hh:62
const GridView & gridView() const
Export the stored GridView.
Definition: leafprebasismappermixin.hh:95
void update(const GridView &gv)
Update the stored GridView.
Definition: leafprebasismappermixin.hh:101
This file provides an implementation of the cubic Hermite finite element in 1 to 3 dimensions.
TrigonometricFunction< K, -cosFactor, sinFactor > derivative(const TrigonometricFunction< K, sinFactor, cosFactor > &f)
Obtain derivative of TrigonometricFunction function.
Definition: trigonometricfunction.hh:43
Function, which evaluates all monomials up to degree maxDegree in a given coordinate.
Definition: monomialset.hh:64