AMDiS  2.10
The Adaptive Multi-Dimensional Simulation Toolbox
LocalAverageInterpolator.hpp
1 #pragma once
2 
3 #include <map>
4 #include <vector>
5 
6 #include <amdis/common/FakeContainer.hpp>
7 #include <amdis/common/FieldMatVec.hpp>
8 #include <amdis/functions/EntitySet.hpp>
9 #include <amdis/functions/HierarchicNodeToRangeMap.hpp>
10 #include <amdis/functions/NodeIndices.hpp>
11 #include <amdis/linearalgebra/Traits.hpp>
12 #include <amdis/operations/Assigner.hpp>
13 #include <amdis/typetree/Traversal.hpp>
14 
15 namespace AMDiS
16 {
17  namespace tag
18  {
19  struct local_average {};
20  }
21 
22  template <class Basis,
23  class TreePath = Dune::TypeTree::HybridTreePath<>>
25  {
26  template <class Coeff, class GridFct, class BitVector>
27  void operator()(Coeff& coeff, GridFct const& gf, BitVector const& bitVec) const
28  {
29  // storage for values computed during the interpolation
30  std::map<typename Basis::MultiIndex, typename Coeff::value_type> values;
31  std::map<typename Basis::MultiIndex, std::uint8_t> counter;
32 
33  std::vector<typename Coeff::value_type> localCoeff;
34 
35  // Obtain a local view of the gridFunction
36  auto lf = localFunction(gf);
37  auto localView = basis_.localView();
38  for (const auto& e : entitySet(basis_))
39  {
40  localView.bind(e);
41  lf.bind(e);
42 
43  auto&& subTree = Dune::TypeTree::child(localView.tree(),treePath_);
44  Traversal::forEachLeafNode(subTree, [&](auto const& node, auto const& tp)
45  {
46  // check whether there is a local contribution
47  bool any = false;
48  for (std::size_t i = 0; i < node.size(); ++i) {
49  auto idx = localView.index(node.localIndex(i));
50  if(bitVec[idx]) {
51  any = true;
52  break;
53  }
54  }
55 
56  if (!any)
57  return;
58 
59  // compute local interpolation coefficients
60  node.finiteElement().localInterpolation().interpolate(HierarchicNodeWrapper{tp,lf}, localCoeff);
61 
62  // assign relevant local coefficients to temporary storage
63  for (std::size_t i = 0; i < node.size(); ++i) {
64  auto idx = localView.index(node.localIndex(i));
65  if (bitVec[idx]) {
66  counter[idx]++;
67  values[idx] += localCoeff[i];
68  }
69  }
70  });
71 
72  lf.unbind();
73  }
74 
75  assert(values.size() == counter.size());
76 
77  // assign computed values to target vector
78  auto value_it = values.begin();
79  auto count_it = counter.begin();
80  for (; value_it != values.end(); ++value_it, ++count_it) {
81  coeff.set(value_it->first, value_it->second/double(count_it->second));
82  }
83  coeff.finish();
84  }
85 
86  template <class Coeff, class GridFct>
87  void operator()(Coeff& coeff, GridFct const& gf) const
88  {
89  (*this)(coeff, gf, FakeContainer<bool,true>{});
90  }
91 
92  LocalAverageInterpolator(Basis const& basis, TreePath treePath = {})
93  : basis_{basis}
94  , treePath_{treePath}
95  {}
96 
97  Basis const& basis_;
98  TreePath treePath_ = {};
99  };
100 
101 
102  template <>
103  struct InterpolatorFactory<tag::local_average>
104  {
105  template <class Basis,
106  class TreePath = Dune::TypeTree::HybridTreePath<>>
107  static auto create(Basis const& basis, TreePath treePath = {})
108  {
109  return LocalAverageInterpolator<Basis,TreePath>{basis, treePath};
110  }
111  };
112 
113 } // end namespace AMDiS
Definition: AdaptBase.hpp:6
Definition: SimpleInterpolator.hpp:80
A container-like data-structure not storing anything and with empty implementations in many container...
Definition: FakeContainer.hpp:34
Definition: LocalAverageInterpolator.hpp:24
Definition: LocalAverageInterpolator.hpp:19
Definition: HierarchicNodeToRangeMap.hpp:41