4 #ifndef DUNE_PDELAB_GRIDFUNCTIONSPACE_INTERPOLATE_HH
5 #define DUNE_PDELAB_GRIDFUNCTIONSPACE_INTERPOLATE_HH
10 #include <dune/common/exceptions.hh>
12 #include <dune/localfunctions/common/interfaceswitch.hh>
13 #include <dune/localfunctions/common/virtualinterface.hh>
14 #include <dune/functions/common/functionfromcallable.hh>
16 #include <dune/typetree/typetree.hh>
17 #include <dune/typetree/pairtraversal.hh>
34 template<
typename FE,
typename ElemFunction,
typename XL>
35 void interpolate(
const FE &fe,
const ElemFunction &elemFunction,
38 FiniteElementInterfaceSwitch<FE>::interpolation(fe).
45 template<
typename IB,
typename LF,
typename XG>
46 struct InterpolateLeafFromScalarVisitor
47 :
public TypeTree::TreeVisitor
48 ,
public TypeTree::DynamicTraversal
51 template<
typename LFS,
typename TreePath>
52 void leaf(
const LFS& lfs, TreePath treePath)
const
54 std::vector<typename XG::ElementType> xl(lfs.size());
57 ib.interpolate(lfs.finiteElement(),
lf, xl);
60 xg.write_sub_container(lfs,xl);
63 InterpolateLeafFromScalarVisitor(
const IB& ib_,
const LF& lf_, XG& xg_)
76 template<
typename IB,
typename LF,
typename XG>
77 struct InterpolateLeafFromVectorVisitor
78 :
public TypeTree::TreeVisitor
79 ,
public TypeTree::DynamicTraversal
81 using Domain =
typename Functions::SignatureTraits<LF>::Domain;
82 using Range =
typename Functions::SignatureTraits<LF>::Range;
83 using RangeField =
typename FieldTraits<Range>::field_type;
85 template<
typename LFS,
typename TreePath>
86 void leaf(
const LFS& lfs, TreePath treePath)
const
88 std::vector<typename XG::ElementType> xl(lfs.size());
90 using LFSRange =
typename LFS::Traits::FiniteElement::Traits::LocalBasisType::Traits::RangeType;
91 static_assert(std::is_convertible<LFSRange,
typename FieldTraits< LFSRange >::field_type>::
value,
92 "only interpolation into scalar leaf function spaces is implemented");
95 auto f = [&](
const Domain& x) -> RangeField {
return lf(x)[
index]; };
97 using LocalFunction =
typename Dune::Functions::FunctionFromCallable<RangeField(Domain), decltype(f), Dune::Function<Domain,RangeField> >;
98 LocalFunction fnkt(f);
100 ib.interpolate(lfs.finiteElement(), fnkt, xl);
103 xg.write_sub_container(lfs,xl);
109 InterpolateLeafFromVectorVisitor(
const IB& ib_,
const LF& lf_, XG& xg_)
124 template<
typename IB,
typename E,
typename XG>
125 struct InterpolateVisitor
126 :
public TypeTree::TreePairVisitor
127 ,
public TypeTree::DynamicTraversal
130 template<
typename F,
typename LFS,
typename TreePath>
131 typename std::enable_if<F::isLeaf && LFS::isLeaf>::type
132 leaf(
const F& f,
const LFS& lfs, TreePath treePath)
const
134 std::vector<typename XG::ElementType> xl(lfs.size());
136 using Domain =
typename Functions::SignatureTraits<F>::Domain;
137 using Range =
typename Functions::SignatureTraits<F>::Range;
138 using LocalFunction =
typename Dune::Functions::FunctionFromCallable<Range(Domain), F, Dune::Function<Domain,Range> >;
140 ib.interpolate(lfs.finiteElement(),
lf, xl);
142 xg.write_sub_container(lfs,xl);
146 template<
typename F,
typename LFS,
typename TreePath,
147 typename Range =
typename Functions::SignatureTraits<F>::Range>
148 typename std::enable_if<F::isLeaf &&
149 std::is_convertible<Range, typename FieldTraits< Range >::field_type>
::value &&
150 (!LFS::isLeaf)>::type
151 leaf(
const F& f,
const LFS& lfs, TreePath treePath)
const
154 using Domain =
typename Functions::SignatureTraits<F>::Domain;
155 using LocalFunction =
typename Dune::Functions::FunctionFromCallable<Range(Domain), F, Dune::Function<Domain,Range> >;
157 TypeTree::applyToTree(lfs,InterpolateLeafFromScalarVisitor<IB,LocalFunction,XG>(
ib,
lf,
xg));
162 template<
typename F,
typename LFS,
typename TreePath,
163 typename Range =
typename Functions::SignatureTraits<F>::Range>
164 typename std::enable_if<F::isLeaf &&
165 (!std::is_convertible<Range, typename FieldTraits< Range >::field_type>
::value) &&
166 (!LFS::isLeaf)>::type
167 leaf(
const F& f,
const LFS& lfs, TreePath treePath)
const
169 static_assert(TypeTree::TreeInfo<LFS>::leafCount == Range::dimension,
170 "Number of leaves and dimension of range type " \
171 "must match for automatic interpolation of " \
172 "vector-valued function");
174 TypeTree::applyToTree(lfs,InterpolateLeafFromVectorVisitor<IB,F,XG>(
ib,f,
xg));
177 InterpolateVisitor(IB ib_,
const E& e_, XG& xg_)
203 template<
typename F,
typename GFS,
typename XG>
209 using EntitySet =
typename GFS::Traits::EntitySet;
210 using Element =
typename EntitySet::Element;
212 auto entity_set = gfs.entitySet();
221 LFSCache lfs_cache(lfs);
222 typedef typename XG::template LocalView<LFSCache> XView;
227 for (
const auto& element : elements(entity_set))
233 x_view.bind(lfs_cache);
236 TypeTree::applyToTreePair(
lf,lfs,InterpolateVisitor<InterpolateBackendStandard,Element,XView>(
InterpolateBackendStandard(),element,x_view));
249 #endif // DUNE_PDELAB_GRIDFUNCTIONSPACE_INTERPOLATE_HH