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