6#ifndef DUNE_FUNCTIONS_FUNCTIONSPACEBASES_CUBICHERMITEBASIS_HH
7#define DUNE_FUNCTIONS_FUNCTIONSPACEBASES_CUBICHERMITEBASIS_HH
22#include <dune/localfunctions/common/localbasis.hh>
56 template<
class GV,
class R,
bool reduced>
57 class CubicHermitePreBasis;
78 template<
class GV,
bool reduced = false,
class R =
double>
81 template<
class DF,
int n,
class D,
class RF,
int m,
class R,
class J,
class H>
109 template<
class KCoeff,
int sizePolynom,
int sizeMonom,
class In,
class Out>
111 In
const& monomialValues,
112 Out& polynomialValues)
114 for (
int i = 0; i < sizePolynom; ++i)
116 squeezeTensor(polynomialValues[i]) = 0;
117 for (
int j = 0; j < sizeMonom; ++j)
118 squeezeTensor(polynomialValues[i]) += coefficients[i][j]*monomialValues[j];
127 template<
int dim,
bool reduced>
128 class CubicHermiteLocalCoefficients
133 CubicHermiteLocalCoefficients()
136 static_assert((
dim > 0) and (
dim <= 3),
"CubicHermiteLocalCoefficients only implemented for dim=1,2,3");
137 static_assert((not reduced) or (
dim == 2),
"Reduced version of CubicHermiteLocalCoefficients only implemented for dim=2");
138 for (size_type i = 0; i < (
dim +1); ++i)
141 for (size_type k = 0; k < (
dim +1); ++k)
144 if constexpr (not reduced)
147 for (size_type i = 0; i < (
dim - 1) * (
dim - 1); ++i)
148 localKeys_[(
dim +1) * (
dim +1) + i] = LocalKey(i, (
dim == 2) ? 0 : 1, 0);
156 if constexpr (
dim==1)
158 if constexpr ((
dim==2) and (reduced))
160 if constexpr ((
dim==2) and (not reduced))
162 if constexpr (
dim==3)
169 LocalKey
const &localKey(size_type i)
const
171 return localKeys_[i];
184 template<
class D,
class R,
int dim,
bool reduced>
185 class CubicHermiteReferenceLocalBasis
188 using Traits = H2LocalBasisTraits<D, dim, FieldVector<D, dim>, R, 1, FieldVector<R, 1>,
189 FieldMatrix<R, 1, dim>, FieldMatrix<R, dim, dim>>;
205 static constexpr auto getCubicHermiteCoefficients()
207 if constexpr (
dim == 1)
208 return Dune::FieldMatrix<D, 4, 4>({{1, 0, -3, 2}, {0, 1, -2, 1}, {0, 0, 3, -2}, {0, 0, -1, 1}});
209 else if constexpr (
dim == 2)
211 if constexpr (reduced) {
213 1. / 18, 1. / 3, 1. / 18, -1. / 9};
215 {1, 0, 0, -3, -13 + w[0] * 27, -3, 2, 13 - w[0] * 27, 13 - w[0] * 27, 2},
216 {0, 1, 0, -2, -3 + w[1] * 27, 0, 1, 3 - w[1] * 27, 2 - w[1] * 27, 0},
217 {0, 0, 1, 0, -3 + w[2] * 27, -2, 0, 2 - w[2] * 27, 3 - w[2] * 27, 1},
218 {0, 0, 0, 3, -7 + w[3] * 27, 0, -2, 7 - w[3] * 27, 7 - w[3] * 27, 0},
219 {0, 0, 0, -1, 2 + w[4] * 27, 0, 1, -2 - w[4] * 27, -2 - w[4] * 27, 0},
220 {0, 0, 0, 0, -1 + w[5] * 27, 0, 0, 2 - w[5] * 27, 1 - w[5] * 27, 0},
221 {0, 0, 0, 0, -7 + w[6] * 27, 3, 0, 7 - w[6] * 27, 7 - w[6] * 27, -2},
222 {0, 0, 0, 0, -1 + w[7] * 27, 0, 0, 1 - w[7] * 27, 2 - w[7] * 27, 0},
223 {0, 0, 0, 0, 2 + w[8] * 27, -1, 0, -2 - w[8] * 27, -2 - w[8] * 27, 1},
228 {1, 0, 0, -3, -13, -3, 2, 13, 13, 2},
229 {0, 1, 0, -2, -3, 0, 1, 3, 2, 0},
230 {0, 0, 1, 0, -3, -2, 0, 2, 3, 1},
231 {0, 0, 0, 3, -7, 0, -2, 7, 7, 0},
232 {0, 0, 0, -1, 2, 0, 1, -2, -2, 0},
233 {0, 0, 0, 0, -1, 0, 0, 2, 1, 0},
234 {0, 0, 0, 0, -7, 3, 0, 7, 7, -2},
235 {0, 0, 0, 0, -1, 0, 0, 1, 2, 0},
236 {0, 0, 0, 0, 2, -1, 0, -2, -2, 1},
237 {0, 0, 0, 0, 27, 0, 0, -27, -27, 0}});
239 else if constexpr (
dim == 3)
241 return Dune::FieldMatrix<D, 20,20>({{1, 0, 0, 0, -3, -13, -3, -13, -13, -3,
242 2, 13, 13, 2, 13, 33, 13, 13, 13, 2},
243 {0, 1, 0, 0, -2, -3, 0, -3, 0, 0, 1, 3, 2, 0, 3, 4, 0, 2, 0, 0},
244 {0, 0, 1, 0, 0, -3, -2, 0, -3, 0, 0, 2, 3, 1, 0, 4, 3, 0, 2, 0},
245 {0, 0, 0, 1, 0, 0, 0, -3, -3, -2, 0, 0, 0, 0, 2, 4, 2, 3, 3, 1},
246 {0, 0, 0, 0, 3, -7, 0, -7, 0, 0,
247 -2, 7, 7, 0, 7, 7, 0, 7, 0, 0},
248 {0, 0, 0, 0, -1, 2, 0, 2, 0, 0, 1, -2, -2, 0, -2, -2, 0, -2, 0, 0},
249 {0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0},
250 {0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 0, 0},
251 {0, 0, 0, 0, 0, -7, 3, 0, -7, 0,
252 0, 7, 7, -2, 0, 7, 7, 0, 7, 0},
253 {0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0},
254 {0, 0, 0, 0, 0, 2, -1, 0, 2, 0, 0, -2, -2, 1, 0, -2, -2, 0, -2, 0},
255 {0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0},
256 {0, 0, 0, 0, 0, 0, 0, -7, -7, 3,
257 0, 0, 0, 0, 7, 7, 7, 7, 7, -2},
258 {0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0},
259 {0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0},
260 {0, 0, 0, 0, 0, 0, 0, 2, 2, -1, 0, 0, 0, 0, -2, -2, -2, -2, -2, 1},
262 {0, 0, 0, 0, 0, 27, 0, 0, 0, 0,
263 0, -27, -27, 0, 0, -27, 0, 0, 0, 0},
264 {0, 0, 0, 0, 0, 0, 0, 27, 0, 0,
265 0, 0, 0, 0, -27, -27, 0, -27, 0, 0},
266 {0, 0, 0, 0, 0, 0, 0, 0, 27, 0,
267 0, 0, 0, 0, 0, -27, -27, 0, -27, 0},
268 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
269 0, 0, 0, 0, 0, 27, 0, 0, 0, 0}});
273 static constexpr auto referenceBasisCoefficients = getCubicHermiteCoefficients();
274 static constexpr MonomialSet<typename Traits::RangeFieldType, dim, 3> monomials = {};
278 CubicHermiteReferenceLocalBasis()
280 static_assert((
dim > 0) and (
dim <= 3),
"CubicHermiteReferenceLocalBasis only implemented for dim=1,2,3");
281 static_assert((not reduced) or (
dim == 2),
"Reduced version of CubicHermiteReferenceLocalBasis only implemented for dim=2");
286 static constexpr unsigned int size()
288 return CubicHermiteLocalCoefficients<dim,reduced>::size();
293 unsigned int order()
const
307 auto monomialValues = monomials(in);
308 multiplyWithCoefficentMatrix(referenceBasisCoefficients, monomialValues, out);
320 auto monomialValues =
derivative(monomials)(in);
321 multiplyWithCoefficentMatrix(referenceBasisCoefficients, monomialValues, out);
334 multiplyWithCoefficentMatrix(referenceBasisCoefficients, monomialValues, out);
349 evaluateFunction(in, out);
350 else if (totalOrder == 1)
352 evaluateJacobian(in,jacobiansBuffer_);
355 out[i] = jacobiansBuffer_[i][0][which];
357 else if (totalOrder == 2)
359 evaluateHessian(in, hessianBuffer_);
362 if (order[first] == 2)
370 out[i] = hessianBuffer_[i][first][second];
373 DUNE_THROW(RangeError,
"partial() not implemented for given order");
387 template<
class D,
int dim,
bool reduced = false>
388 class CubicHermiteLocalInterpolation
392 static constexpr unsigned int size()
394 return CubicHermiteLocalCoefficients<dim,reduced>::size();
397 using FunctionalDescriptor = Dune::Functions::Impl::FunctionalDescriptor<dim>;
401 CubicHermiteLocalInterpolation()
403 static_assert((
dim > 0) and (
dim <= 3),
"CubicHermiteLocalInterpolation only implemented for dim=1,2,3");
404 static_assert((not reduced) or (
dim == 2),
"Reduced version of CubicHermiteLocalInterpolation only implemented for dim=2");
405 if constexpr (
dim==1)
407 descriptors_[0] = FunctionalDescriptor();
408 descriptors_[1] = FunctionalDescriptor({1});
409 descriptors_[2] = FunctionalDescriptor();
410 descriptors_[3] = FunctionalDescriptor({1});
412 if constexpr (
dim==2)
414 descriptors_[0] = FunctionalDescriptor();
415 descriptors_[1] = FunctionalDescriptor({1,0});
416 descriptors_[2] = FunctionalDescriptor({0,1});
417 descriptors_[3] = FunctionalDescriptor();
418 descriptors_[4] = FunctionalDescriptor({1,0});
419 descriptors_[5] = FunctionalDescriptor({0,1});
420 descriptors_[6] = FunctionalDescriptor();
421 descriptors_[7] = FunctionalDescriptor({1,0});
422 descriptors_[8] = FunctionalDescriptor({0,1});
424 descriptors_[9] = FunctionalDescriptor();
426 if constexpr (
dim==3)
428 descriptors_[0] = FunctionalDescriptor();
429 descriptors_[1] = FunctionalDescriptor({1,0,0});
430 descriptors_[2] = FunctionalDescriptor({0,1,0});
431 descriptors_[3] = FunctionalDescriptor({0,0,1});
432 descriptors_[4] = FunctionalDescriptor();
433 descriptors_[5] = FunctionalDescriptor({1,0,0});
434 descriptors_[6] = FunctionalDescriptor({0,1,0});
435 descriptors_[7] = FunctionalDescriptor({0,0,1});
436 descriptors_[8] = FunctionalDescriptor();
437 descriptors_[9] = FunctionalDescriptor({1,0,0});
438 descriptors_[10] = FunctionalDescriptor({0,1,0});
439 descriptors_[11] = FunctionalDescriptor({0,0,1});
440 descriptors_[12] = FunctionalDescriptor();
441 descriptors_[13] = FunctionalDescriptor({1,0,0});
442 descriptors_[14] = FunctionalDescriptor({0,1,0});
443 descriptors_[15] = FunctionalDescriptor({0,0,1});
444 descriptors_[16] = FunctionalDescriptor();
445 descriptors_[17] = FunctionalDescriptor();
446 descriptors_[18] = FunctionalDescriptor();
447 descriptors_[19] = FunctionalDescriptor();
453 template<
class Element>
456 averageVertexMeshSize_ = &averageVertexMeshSize;
466 template<
class F,
class C>
471 auto const &refElement = Dune::ReferenceElements<D, dim>::simplex();
474 for (
int i = 0; i < (
dim+1); ++i)
476 auto x = refElement.position(i,
dim);
477 auto&& derivativeValue = df(x);
478 out[i * (
dim +1)] = f(x);
479 for (
int d = 0; d <
dim; ++d)
480 out[i * (
dim+1) + d + 1] = squeezeTensor(derivativeValue)[d] * (*averageVertexMeshSize_)[i];
483 if constexpr (not reduced)
485 for (size_type i = 0; i < (
dim - 1) * (
dim - 1); ++i)
486 out[(
dim +1) * (
dim +1) + i] = f(refElement.position(i, (
dim == 2) ? 0 : 1));
493 const FunctionalDescriptor& functionalDescriptor(size_type i)
const
495 return descriptors_[i];
503 template<
class D,
class R,
int dim ,
bool reduced>
504 struct CubicHermiteLocalBasisTraits
505 :
public H2LocalBasisTraits<D, dim, Dune::FieldVector<D,dim>, R, 1,
506 Dune::FieldVector<R,1>, Dune::FieldMatrix<R,1,dim>, Dune::FieldMatrix<R,dim,dim>>
517 template<
class D,
class R,
int dim,
bool reduced = false>
518 class CubicHermiteLocalFiniteElement
519 :
public Impl::TransformedFiniteElementMixin<CubicHermiteLocalFiniteElement<D,R,dim,reduced>, CubicHermiteLocalBasisTraits<D, R, dim, reduced>>
521 using Base = Impl::TransformedFiniteElementMixin< CubicHermiteLocalFiniteElement<D,R,dim,reduced>, CubicHermiteLocalBasisTraits<D, R, dim, reduced>>;
522 friend class Impl::TransformedLocalBasis<CubicHermiteLocalFiniteElement<D,R,
dim,reduced>, CubicHermiteLocalBasisTraits<D, R,
dim, reduced>>;
526 CubicHermiteLocalFiniteElement()
529 static_assert((
dim > 0) and (
dim <= 3),
"CubicHermiteLocalFiniteElement only implemented for dim=1,2,3");
530 static_assert((not reduced) or (
dim == 2),
"Reduced version of CubicHermiteLocalFiniteElement only implemented for dim=2");
536 using Traits = LocalFiniteElementTraits<
537 Impl::TransformedLocalBasis<CubicHermiteLocalFiniteElement<D,R,dim,reduced>, CubicHermiteLocalBasisTraits<D, R, dim, reduced>>,
538 Impl::CubicHermiteLocalCoefficients<dim, reduced>,
539 Impl::CubicHermiteLocalInterpolation<D, dim, reduced>>;
546 return coefficients_;
553 return interpolation_;
560 return GeometryTypes::simplex(
dim);
567 return Impl::CubicHermiteLocalCoefficients<dim,reduced>::size();
572 template<
class Mapper,
class Element>
573 void bind(Mapper
const& vertexMapper,
std::vector<D> const& globalAverageVertexMeshSize, Element
const &e)
577 averageVertexMeshSize_[i] = globalAverageVertexMeshSize[vertexMapper.subIndex(e, i,
dim)];
580 interpolation_.bind(e, averageVertexMeshSize_);
583 const auto& geometry = e.geometry();
584 const auto& refElement = Dune::ReferenceElements<typename Element::Geometry::ctype, dim>::simplex();
587 scaledVertexJacobians_[i] = geometry.jacobian(refElement.position(i,
dim));
588 scaledVertexJacobians_[i] /= averageVertexMeshSize_[i];
596 Impl::CubicHermiteReferenceLocalBasis<D, R, dim, reduced>
const& referenceLocalBasis()
const
605 template<
class InputValues,
class OutputValues>
606 void transform(InputValues
const &inValues, OutputValues &outValues)
const
608 assert(inValues.size() ==
size());
609 assert(outValues.size() == inValues.size());
610 auto inIt = inValues.begin();
611 auto outIt = outValues.begin();
622 outIt[i] += val_i_j * inIt[j];
625 outIt +=
dim, inIt +=
dim;
629 if constexpr (
dim > 1 and (not reduced))
635 typename Impl::CubicHermiteReferenceLocalBasis<D, R, dim, reduced> basis_;
661 template<
class GV,
class R,
bool reduced>
670 using FiniteElement =
typename Impl::CubicHermiteLocalFiniteElement<typename GV::ctype, R, GV::dimension, reduced>;
722 template<
class GV,
class R,
bool reduced = false>
729 using D =
typename GV::ctype;
761 :
Base(gv, cubicHermiteMapperLayout)
764 static_assert((
dim > 0) and (dim <= 3),
"CubicHermitePreBasis only implemented for dim=1,2,3");
765 static_assert((not reduced) or (dim == 2),
"Reduced version of CubicHermitePreBasis only implemented for dim=2");
792 namespace BasisFactory
802 template<
class R =
double>
805 return [=](
auto const &gridView) {
817 template<
class R =
double>
818 auto reducedCubicHermite()
820 return [=](
auto const &gridView) {
821 return CubicHermitePreBasis<
std::decay_t<
decltype(gridView)>, R,
true>(gridView);
BCRSMatrix< FieldMatrix< T, n, m >, A >::size_type size_type
TrigonometricFunction< K, -cosFactor, sinFactor > derivative(const TrigonometricFunction< K, sinFactor, cosFactor > &f)
Obtain derivative of TrigonometricFunction function.
Definition trigonometricfunction.hh:43
Definition monomialset.hh:19
void interpolate(const B &basis, C &&coeff, const F &f, const BV &bv, const NTRE &nodeToRangeEntry)
Interpolate given function in discrete function space.
Definition interpolate.hh:205
static constexpr IntegralRange< std::decay_t< T > > range(T &&from, U &&to) noexcept
auto sparseRange(Range &&range)
static constexpr size_type size()
#define DUNE_THROW(E,...)
MCMGLayout mcmgVertexLayout()
constexpr bool isVertex() const
constexpr bool isTriangle() const
LI LocalInterpolationType
void update(const GV &gridView)
A pre-basis for a Hermitebasis.
Definition cubichermitebasis.hh:725
std::vector< D > averageVertexMeshSize_
Definition cubichermitebasis.hh:788
Node makeNode() const
Create tree node.
Definition cubichermitebasis.hh:780
GV GridView
The grid view that the FE basis is defined on.
Definition cubichermitebasis.hh:749
SubEntityMapper vertexMapper_
Definition cubichermitebasis.hh:787
void update(GridView const &gv)
Update the stored grid view, to be called if the grid has changed.
Definition cubichermitebasis.hh:770
CubicHermitePreBasis(const GV &gv)
Constructor for a given grid view object.
Definition cubichermitebasis.hh:760
Definition cubichermitebasis.hh:84
H HessianType
Type to represent the Hessian When then HessianType is an 2D-array of m x m components where entry H...
Definition cubichermitebasis.hh:90
Definition cubichermitebasis.hh:664
typename Impl::CubicHermiteLocalFiniteElement< typename GV::ctype, R, GV::dimension, reduced > FiniteElement
Definition cubichermitebasis.hh:670
FiniteElement finiteElement_
Definition cubichermitebasis.hh:706
FiniteElement const & finiteElement() const
Return the LocalFiniteElement for the element we are bound to.
Definition cubichermitebasis.hh:689
Element const & element() const
Return current element, throw if unbound.
Definition cubichermitebasis.hh:679
Element const * element_
Definition cubichermitebasis.hh:707
void bind(Element const &e)
Bind to element.
Definition cubichermitebasis.hh:695
unsigned int order() const
The order of the local basis.
Definition cubichermitebasis.hh:703
typename GV::template Codim< 0 >::Entity Element
Definition cubichermitebasis.hh:669
Mapper const * vertexMapper_
Definition cubichermitebasis.hh:708
std::vector< typename GV::ctype > const * averageVertexMeshSize_
Definition cubichermitebasis.hh:709
CubicHermiteNode(Mapper const &m, std::vector< typename GV::ctype > const &averageVertexMeshSize)
Definition cubichermitebasis.hh:672
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
void setSize(const size_type size)
Definition nodes.hh:193