7#ifndef DUNE_FUNCTIONS_FUNCTIONSPACEBASES_GLOBALVALUEDLOCALFINITEELEMENT_HH
8#define DUNE_FUNCTIONS_FUNCTIONSPACEBASES_GLOBALVALUEDLOCALFINITEELEMENT_HH
18#include <dune/geometry/referenceelements.hh>
20#include <dune/localfunctions/common/localbasis.hh>
21#include <dune/localfunctions/common/localfiniteelementtraits.hh>
23#include <dune/functions/common/densevectorview.hh>
25namespace Dune::Functions::Impl
41 struct ContravariantPiolaTransformator
47 template<
typename Values,
typename LocalCoordinate,
typename Geometry>
48 static auto apply(Values& values,
49 const LocalCoordinate& xi,
50 const Geometry& geometry)
52 auto jacobianTransposed = geometry.jacobianTransposed(xi);
53 auto integrationElement = geometry.integrationElement(xi);
55 for (
auto& value : values)
61 auto tmpDenseVector = Impl::DenseVectorView(tmp);
62 auto valueDenseVector = Impl::DenseVectorView(value);
63 jacobianTransposed.mtv(tmpDenseVector, valueDenseVector);
64 value /= integrationElement;
77 template<
typename Gradients,
typename LocalCoordinate,
typename Geometry>
78 static auto applyJacobian(Gradients& gradients,
79 const LocalCoordinate& xi,
80 const Geometry& geometry)
82 auto jacobianTransposed = geometry.jacobianTransposed(xi);
83 auto integrationElement = geometry.integrationElement(xi);
84 for (
auto& gradient : gradients)
88 for (
size_t k=0; k<gradient.M(); k++)
89 for (
size_t l=0; l<tmp.N(); l++)
91 for(
auto&& [jacobianTransposed_l_j, j] :
sparseRange(jacobianTransposed[l]))
92 gradient[j][k] += jacobianTransposed_l_j * tmp[l][k];
93 gradient /= integrationElement;
104 template<
class Function,
class LocalCoordinate,
class Element>
105 class LocalValuedFunction
108 const Element& element_;
110 using LocalValue = LocalCoordinate;
114 LocalValuedFunction(
const Function& f,
const Element& element)
115 : f_(f), element_(element)
118 auto operator()(
const LocalCoordinate& xi)
const
120 auto globalValue = f_(xi);
123 auto jacobianInverseTransposed = element_.geometry().jacobianInverseTransposed(xi);
124 auto integrationElement = element_.geometry().integrationElement(xi);
126 auto localValue = LocalValue{};
131 auto globalValueDenseVector = Impl::DenseVectorView(globalValue);
132 auto localValueDenseVector = Impl::DenseVectorView(localValue);
133 jacobianInverseTransposed.mtv(globalValueDenseVector, localValueDenseVector);
134 localValue *= integrationElement;
154 struct CovariantPiolaTransformator
160 template<
typename Values,
typename LocalCoordinate,
typename Geometry>
161 static auto apply(Values& values,
162 const LocalCoordinate& xi,
163 const Geometry& geometry)
165 auto jacobianInverseTransposed = geometry.jacobianInverseTransposed(xi);
167 for (
auto& value : values)
173 auto tmpDenseVector = Impl::DenseVectorView(tmp);
174 auto valueDenseVector = Impl::DenseVectorView(value);
175 jacobianInverseTransposed.mv(tmpDenseVector, valueDenseVector);
188 template<
typename Gradients,
typename LocalCoordinate,
typename Geometry>
189 static auto applyJacobian(Gradients& gradients,
190 const LocalCoordinate& xi,
191 const Geometry& geometry)
193 auto jacobianInverseTransposed = geometry.jacobianInverseTransposed(xi);
195 for (
auto& gradient : gradients)
199 for (
size_t j=0; j<gradient.N(); j++)
200 for (
size_t k=0; k<gradient.M(); k++)
202 for(
auto&& [jacobianInverseTransposed_j_l, l] :
sparseRange(jacobianInverseTransposed[j]))
203 gradient[j][k] += jacobianInverseTransposed_j_l * tmp[l][k];
214 template<
class Function,
class LocalCoordinate,
class Element>
215 class LocalValuedFunction
218 const Element& element_;
222 LocalValuedFunction(
const Function& f,
const Element& element)
223 : f_(f), element_(element)
226 auto operator()(
const LocalCoordinate& xi)
const
228 auto globalValue = f_(xi);
231 auto jacobianTransposed = element_.geometry().jacobianTransposed(xi);
233 auto localValue = globalValue;
237 auto localValueDenseVector = Impl::DenseVectorView(localValue);
238 auto globalValueDenseVector = Impl::DenseVectorView(globalValue);
239 jacobianTransposed.mv(globalValueDenseVector, localValueDenseVector);
252 template<
class Transformator,
class LocalValuedLocalBasis,
class Element>
253 class GlobalValuedLocalBasis
256 using Traits =
typename LocalValuedLocalBasis::Traits;
260 void bind(
const LocalValuedLocalBasis& localValuedLocalBasis,
const Element& element)
262 localValuedLocalBasis_ = &localValuedLocalBasis;
270 return localValuedLocalBasis_->size();
274 void evaluateFunction(
const typename Traits::DomainType& x,
275 std::vector<typename Traits::RangeType>& out)
const
277 localValuedLocalBasis_->evaluateFunction(x,out);
279 Transformator::apply(out, x, element_->geometry());
287 void evaluateJacobian(
const typename Traits::DomainType& x,
288 std::vector<typename Traits::JacobianType>& out)
const
290 localValuedLocalBasis_->evaluateJacobian(x,out);
292 Transformator::applyJacobian(out, x, element_->geometry());
301 void partial(
const std::array<unsigned int,2>& order,
302 const typename Traits::DomainType& x,
303 std::vector<typename Traits::RangeType>& out)
const
306 if (totalOrder == 0) {
307 evaluateFunction(x, out);
308 }
else if (totalOrder == 1) {
309 auto const direction = std::distance(order.begin(), std::find(order.begin(), order.end(), 1));
316 std::vector<typename Traits::JacobianType> fullJacobian;
317 localValuedLocalBasis_->evaluateJacobian(x,fullJacobian);
319 Transformator::applyJacobian(fullJacobian, x, element_->geometry());
321 for (std::size_t i=0; i<out.size(); i++)
322 for (std::size_t j=0; j<out[i].size(); j++)
323 out[i][j] = fullJacobian[i][j][direction];
326 DUNE_THROW(NotImplemented,
"Partial derivatives of order 2 or higher");
332 return localValuedLocalBasis_->order();
335 const LocalValuedLocalBasis* localValuedLocalBasis_;
336 const Element* element_;
347 template<
class Transformator,
class LocalValuedLocalInterpolation,
class Element>
348 class GlobalValuedLocalInterpolation
353 void bind(
const LocalValuedLocalInterpolation& localValuedLocalInterpolation,
const Element& element)
355 localValuedLocalInterpolation_ = &localValuedLocalInterpolation;
359 template<
typename F,
typename C>
360 void interpolate (
const F& f, std::vector<C>& out)
const
362 using LocalCoordinate =
typename Element::Geometry::LocalCoordinate;
363 typename Transformator::template LocalValuedFunction<F,LocalCoordinate,Element> localValuedFunction(f, *element_);
364 localValuedLocalInterpolation_->interpolate(localValuedFunction, out);
368 const LocalValuedLocalInterpolation* localValuedLocalInterpolation_;
369 const Element* element_;
379 template<
class Transformator,
class LocalValuedLFE,
class Element>
380 class GlobalValuedLocalFiniteElement
382 using LocalBasis = GlobalValuedLocalBasis<Transformator,
383 typename LocalValuedLFE::Traits::LocalBasisType,
385 using LocalInterpolation = GlobalValuedLocalInterpolation<Transformator,
386 typename LocalValuedLFE::Traits::LocalInterpolationType,
392 using Traits = LocalFiniteElementTraits<LocalBasis,
393 typename LocalValuedLFE::Traits::LocalCoefficientsType,
396 GlobalValuedLocalFiniteElement() {}
398 void bind(
const LocalValuedLFE& localValuedLFE,
const Element& element)
400 globalValuedLocalBasis_.bind(localValuedLFE.localBasis(), element);
401 globalValuedLocalInterpolation_.bind(localValuedLFE.localInterpolation(), element);
402 localValuedLFE_ = &localValuedLFE;
409 return globalValuedLocalBasis_;
416 return localValuedLFE_->localCoefficients();
423 return globalValuedLocalInterpolation_;
427 std::size_t
size()
const
429 return localValuedLFE_->size();
436 return localValuedLFE_->type();
443 const LocalValuedLFE* localValuedLFE_;
GeometryType
Type representing VTK's entity geometry types.
Definition: common.hh:132
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,...)
Definition: exceptions.hh:312
void interpolate(const F &f, const GFS &gfs, XG &xg)
interpolation from a given grid function
Definition: interpolate.hh:177
constexpr T accumulate(Range &&range, T value, F &&f)
Accumulate values.
Definition: hybridutilities.hh:279
auto sparseRange(Range &&range)
Allow structured-binding for-loops for sparse iterators.
Definition: rangeutilities.hh:722
Some useful basic math stuff.
constexpr std::integral_constant< std::size_t, sizeof...(II)> size(std::integer_sequence< T, II... >)
Return the size of the sequence.
Definition: integersequence.hh:75
Utilities for reduction like operations on ranges.
LB LocalBasisType
Definition: localfiniteelementtraits.hh:16
LC LocalCoefficientsType
Definition: localfiniteelementtraits.hh:20
LI LocalInterpolationType
Definition: localfiniteelementtraits.hh:24