3#ifndef DUNE_FUNCTIONS_FUNCTIONSPACEBASES_INTERPOLATE_HH
4#define DUNE_FUNCTIONS_FUNCTIONSPACEBASES_INTERPOLATE_HH
11#include <dune/common/referencehelper.hh>
13#include <dune/typetree/traversal.hh>
15#include <dune/functions/gridfunctions/gridviewfunction.hh>
16#include <dune/functions/common/functionconcepts.hh>
18#include <dune/functions/backends/concepts.hh>
19#include <dune/functions/backends/istlvectorbackend.hh>
20#include <dune/functions/functionspacebases/flatvectorview.hh>
21#include <dune/functions/functionspacebases/hierarchicnodetorangemap.hh>
28struct AllTrueBitSetVector
32 bool test(
int)
const {
return true; }
41 const AllTrueBitSetVector& operator[](
const I&)
const
47 void resize(
const SP&)
const
57template<
class F,
class Restriction>
58class ComponentFunction
62 ComponentFunction(F f, Restriction restriction) :
64 restriction_(
std::move(restriction))
67 template<
class Domain>
68 auto operator()(
const Domain& x)
const
70 return restriction_(f_(x));
73 friend auto derivative(
const ComponentFunction& cf)
79 return [&, df=forwardCapture(std::forward<
decltype(df)>(df))](
auto&& x) {
80 return cf.restriction_(df.forward()(x));
86 Restriction restriction_;
104class CachedDerivativeLocalFunction
106 using Derivative = std::decay_t<decltype(derivative(Dune::resolveRef(std::declval<const F&>())))>;
110 CachedDerivativeLocalFunction(F f) :
114 template<
class Element>
115 void bind(
const Element& element)
119 derivative_.value().bind(element);
123 auto operator()(
const X& x)
const
128 friend const Derivative&
derivative(
const CachedDerivativeLocalFunction& cdlf)
130 if (not cdlf.derivative_)
135 cdlf.derivative_.value().bind(lf.localContext());
137 return cdlf.derivative_.value();
142 mutable std::optional<Derivative> derivative_;
147template<
class VectorBackend,
class BitVectorBackend,
class LocalFunction,
class LocalView,
class NodeToRangeEntry>
148void interpolateLocal(VectorBackend& vector,
const BitVectorBackend& bitVector,
const LocalFunction& localF,
const LocalView& localView,
const NodeToRangeEntry& nodeToRangeEntry)
151 using Node = std::decay_t<decltype(node)>;
152 using FiniteElement = typename Node::FiniteElement;
153 using FiniteElementRangeField = typename FiniteElement::Traits::LocalBasisType::Traits::RangeFieldType;
155 auto interpolationCoefficients = std::vector<FiniteElementRangeField>();
156 auto&& fe = node.finiteElement();
157 auto localF_RE = ComponentFunction(std::cref(localF), [&](auto&& y) { return nodeToRangeEntry(node, treePath, y); });
159 fe.localInterpolation().interpolate(localF_RE, interpolationCoefficients);
160 for (
size_t i=0; i<fe.localBasis().
size(); ++i)
162 auto multiIndex = localView.index(node.localIndex(i));
163 if ( bitVector[multiIndex] )
164 vector[multiIndex] = interpolationCoefficients[i];
173 auto require(F&& f) ->
decltype(
derivative(f));
198template <
class B,
class C,
class F,
class BV,
class NTRE>
199void interpolate(
const B& basis, C&& coeff,
const F& f,
const BV& bv,
const NTRE& nodeToRangeEntry)
201 using GridView =
typename B::GridView;
202 using Element =
typename GridView::template Codim<0>::Entity;
203 using GlobalDomain =
typename Element::Geometry::GlobalCoordinate;
205 static_assert(Dune::Functions::Concept::isCallable<F, GlobalDomain>(),
"Function passed to interpolate does not model the Callable<GlobalCoordinate> concept");
207 auto&& gridView = basis.gridView();
211 auto toVectorBackend = [&](
auto& v) ->
decltype(
auto) {
212 if constexpr (models<Concept::VectorBackend<B>,
decltype(v)>()) {
219 auto toConstVectorBackend = [&](
auto& v) ->
decltype(
auto) {
220 if constexpr (models<Concept::ConstVectorBackend<B>,
decltype(v)>()) {
227 auto&& bitVector = toConstVectorBackend(bv);
228 auto&& vector = toVectorBackend(coeff);
229 vector.resize(basis);
232 auto gf = makeGridViewFunction(f, gridView);
240 if constexpr (models<Imp::HasDerivative, decltype(localFunction(gf))>())
241 return Imp::CachedDerivativeLocalFunction(localFunction(gf));
243 return localFunction(gf);
246 auto localView = basis.localView();
248 for (
const auto& e : elements(gridView))
252 Imp::interpolateLocal(vector, bitVector, localF, localView, nodeToRangeEntry);
272template <
class B,
class C,
class F,
class BV>
273void interpolate(
const B& basis, C&& coeff,
const F& f,
const BV& bitVector)
275 interpolate(basis, coeff, f, bitVector, HierarchicNodeToRangeMap());
292template <
class B,
class C,
class F>
293void interpolate(
const B& basis, C&& coeff,
const F& f)
295 interpolate (basis, coeff, f, Imp::AllTrueBitSetVector(), HierarchicNodeToRangeMap());
Efficient implementation of a dynamic array of static arrays of booleans.
A few common exception classes.
constexpr T & resolveRef(T &gf) noexcept
Helper function to resolve std::reference_wrapper.
Definition: referencehelper.hh:47
TrigonometricFunction< K, -cosFactor, sinFactor > derivative(const TrigonometricFunction< K, sinFactor, cosFactor > &f)
Obtain derivative of TrigonometricFunction function.
Definition: trigonometricfunction.hh:39
auto istlVectorBackend(Vector &v)
Return a vector backend wrapping non-const ISTL like containers.
Definition: istlvectorbackend.hh:346
void interpolate(const F &f, const GFS &gfs, XG &xg)
interpolation from a given grid function
Definition: interpolate.hh:177
constexpr auto treePath(const T &... t)
Constructs a new HybridTreePath from the given indices.
Definition: treepath.hh:326
void forEachLeafNode(Tree &&tree, LeafFunc &&leafFunc)
Traverse tree and visit each leaf node.
Definition: traversal.hh:269
Dune namespace.
Definition: alignedallocator.hh:13
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