AMDiS  0.1
The Adaptive Multi-Dimensional Simulation Toolbox
Interpolate.hpp
1 #pragma once
2 
3 #include <memory>
4 #include <optional>
5 #include <vector>
6 
7 #include <dune/common/tuplevector.hh>
8 #include <dune/common/version.hh>
9 #include <dune/functions/functionspacebases/interpolate.hh>
10 
11 #include <amdis/common/Concepts.hpp>
12 #include <amdis/common/FakeContainer.hpp>
13 #include <amdis/common/FieldMatVec.hpp>
14 #include <amdis/common/Logical.hpp>
15 #include <amdis/common/Tags.hpp>
16 #include <amdis/functions/FunctionFromCallable.hpp>
17 #include <amdis/functions/HierarchicNodeToRangeMap.hpp>
18 #include <amdis/functions/NodeIndices.hpp>
19 #include <amdis/gridfunctions/GridFunction.hpp>
20 #include <amdis/linearalgebra/Traits.hpp>
21 #include <amdis/operations/Assigner.hpp>
22 #include <amdis/typetree/Traversal.hpp>
23 
24 namespace AMDiS
25 {
26  namespace Impl
27  {
28  template <class B, class Vec, class GF, class TP, class C, class BV, class NTRE, class Assign>
29  void interpolateTreeSubset(B const& basis, Vec& vector, GF const& gf, TP const& treePath,
30  C& counter, BV const& bitVec, NTRE const& nodeToRangeEntry, Assign assign)
31  {
32  auto localView = basis.localView();
33 
34  // set vector to zero at subtree
35  if (!std::is_same_v<Assign, Assigner::assign>) {
36  for (const auto& e : elements(basis.gridView(), typename BackendTraits<B>::PartitionSet{}))
37  {
38  localView.bind(e);
39  auto&& subTree = Dune::TypeTree::child(localView.tree(), treePath);
40  vector.forEach(nodeIndices(localView, subTree), [&](auto dof, auto& coeff) {
41  if (bitVec[dof]) { coeff = 0; }
42  });
43  }
44  }
45 
46  // Obtain a local view of f
47  auto lf = localFunction(gf);
48 
49  vector.init(sizeInfo(basis), false);
50  counter.init(sizeInfo(basis), true); // set to zero
51  for (const auto& e : elements(basis.gridView(), typename BackendTraits<B>::PartitionSet{}))
52  {
53  localView.bind(e);
54  lf.bind(e);
55 
56  auto&& subTree = Dune::TypeTree::child(localView.tree(),treePath);
57  for_each_leaf_node(subTree, [&](auto const& node, auto const& tp)
58  {
59  using Traits = typename TYPEOF(node)::FiniteElement::Traits::LocalBasisType::Traits;
60  using RangeField = typename Traits::RangeFieldType;
61 
62  auto&& fe = node.finiteElement();
63  std::size_t feSize = fe.localBasis().size();
64 
65  auto bitVecRange = mappedRangeView(Dune::range(feSize), [&](std::size_t i) -> bool {
66  return bitVec[localView.index(node.localIndex(i))];
67  });
68 
69  std::vector<RangeField> visit(bitVecRange.begin(), bitVecRange.end());
70  if (std::all_of(visit.begin(), visit.end(), [](auto i) { return i == 0; }))
71  return;
72 
73  // extract component of local function result corresponding to node in tree
74  auto localFj = [&](auto const& local)
75  {
76  const auto& tmp = lf(local);
77  return nodeToRangeEntry(node, tp, Dune::MatVec::as_vector(tmp));
78  };
79 
80  thread_local std::vector<RangeField> interpolationCoeff;
81  auto localFjFct = functionFromCallable<Traits>(localFj);
82  fe.localInterpolation().interpolate(localFjFct, interpolationCoeff);
83 
84  counter.scatter(localView, node, visit, assign);
85  vector.scatter(localView, node, interpolationCoeff, visit, assign);
86  });
87  }
88  vector.finish();
89  counter.finish();
90  }
91 
92  } // namespace Impl
93 
94 
95  template <class T, class Default>
96  decltype(auto) value_or(T&& value, Default&&) { return FWD(value); }
97 
98  template <class Default>
99  decltype(auto) value_or(tag::defaulted, Default&& def) { return FWD(def); }
100 
101 
103 
119  template <class Basis, class Vec, class GF, class TP, class C, class BV, class Assign>
120  void interpolate(Basis const& basis, Vec& vec, GF const& gf, TP const& tp_, C&& c_, BV&& bv_, Assign&& a_)
121  {
122  auto&& tp = value_or(FWD(tp_), Dune::TypeTree::hybridTreePath());
123  auto&& c = value_or(FWD(c_), FakeContainer<int,1>());
124  auto&& bv = value_or(FWD(bv_), FakeContainer<bool,true>());
125  auto&& a = value_or(FWD(a_), Assigner::assign());
126 
127  auto ntrm = AMDiS::HierarchicNodeToRangeMap();
128  AMDiS::Impl::interpolateTreeSubset(basis, vec, gf, tp, c, bv, ntrm, a);
129  }
130 
131  template <class B, class Vec, class GF, class TP, class C, class BV>
132  void interpolate(B const& basis, Vec& vec, GF const& gf, TP&& tp, C&& c, BV const& bitVec)
133  {
134  static_assert(not std::is_same_v<BV, tag::defaulted>, "");
135  AMDiS::interpolate(basis, vec, gf, FWD(tp), FWD(c), bitVec, tag::defaulted{});
136  }
137 
138  template <class B, class Vec, class GF, class TP, class C>
139  void interpolate(B const& basis, Vec& vec, GF const& gf, TP&& tp, C& counter)
140  {
141  static_assert(not std::is_same_v<C, tag::defaulted>, "");
142  AMDiS::interpolate(basis, vec, gf, FWD(tp), counter, tag::defaulted{}, Assigner::plus_assign{});
143  }
144 
145  template <class B, class Vec, class GF, class TreePath>
146  void interpolate(B const& basis, Vec& vec, GF const& gf, TreePath const& treePath)
147  {
148  static_assert(not std::is_same_v<TreePath, tag::defaulted>, "");
149  AMDiS::interpolate(basis, vec, gf, treePath, tag::defaulted{}, tag::defaulted{}, Assigner::assign{});
150  }
151 
152  template <class B, class Vec, class GF>
153  void interpolate(B const& basis, Vec& vec, GF const& gf)
154  {
156  }
157 
158 } // end namespace AMDiS
void for_each_leaf_node(Tree &&tree, LeafFunc &&leafFunc)
Traverse tree and visit each leaf node.
Definition: Traversal.hpp:127
Definition: Tags.hpp:17
void interpolate(Basis const &basis, Vec &vec, GF const &gf, TP const &tp_, C &&c_, BV &&bv_, Assign &&a_)
Interpolate given function in discrete function space.
Definition: Interpolate.hpp:120
Definition: Assigner.hpp:16
Contains all classes needed for solving linear and non linear equation systems.
Definition: AdaptBase.hpp:6
auto mappedRangeView(R &&range, F const &f)
Create a MappedRangeView.
Definition: MappedRangeView.hpp:445
A simple node to range map using the nested tree indices.
Definition: HierarchicNodeToRangeMap.hpp:23
A container-like data-structure not storing anything and with empty implementations in many container...
Definition: FakeContainer.hpp:34
auto nodeIndices(LocalView const &localView, Node const &node)
Returns a range over (flat) DOF indices on a node, given by the localView.
Definition: NodeIndices.hpp:13
Definition: Assigner.hpp:7