AMDiS 2.11-git
The Adaptive Multi-Dimensional Simulation Toolbox
 
Loading...
Searching...
No Matches
AverageInterpolator.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 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 VectorType_t<typename Coeff::value_type, Coeff> coeff0(basis_);
34 VectorType_t<std::uint8_t, Coeff> counter(basis_);
35 using Counter = TYPEOF(counter);
36
37 // Obtain a local view of the gridFunction
38 auto lf = localFunction(gf);
39 auto localView = basis_.localView();
40
41 std::vector<typename Coeff::value_type> localCoeff;
42 std::vector<typename Counter::value_type> localOnes(localView.maxSize(), 1);
43
44 for (const auto& e : entitySet(basis_))
45 {
46 localView.bind(e);
47 lf.bind(e);
48
49 auto&& subTree = Dune::TypeTree::child(localView.tree(),treePath_);
50 Traversal::forEachLeafNode(subTree, [&](auto const& node, auto const& tp)
51 {
52 auto bitVecRange = mappedRangeView(Dune::range(node.size()), [&](std::size_t i) -> bool {
53 return bitVec[localView.index(node.localIndex(i))];
54 });
55
56 // check whether there is a local contribution
57 std::vector<bool> mask(bitVecRange.begin(), bitVecRange.end());
58 if (std::all_of(mask.begin(), mask.end(), [](bool m) { return !m; }))
59 return;
60
61 // compute local interpolation coefficients
62 node.finiteElement().localInterpolation().interpolate(HierarchicNodeWrapper{tp,lf}, localCoeff);
63
64 // assign local coefficients to global vector
65 coeff0.scatter(localView, node, localCoeff, mask, Assigner::plus_assign{});
66
67 localOnes.resize(node.size(), 1);
68 counter.scatter(localView, node, localOnes, mask, Assigner::plus_assign{});
69 });
70
71 lf.unbind();
72 }
73 coeff0.finish();
74 counter.finish();
75
76 // storage for values computed during the interpolation
77 std::map<typename Basis::MultiIndex, typename Coeff::value_type> coeffMap;
78 std::map<typename Basis::MultiIndex, std::uint8_t> counterMap;
79
80 std::vector<typename Coeff::value_type> localCoeffs;
81 std::vector<typename Counter::value_type> localCounter;
82
83 for (const auto& e : entitySet(basis_))
84 {
85 localView.bind(e);
86
87 auto&& node = Dune::TypeTree::child(localView.tree(),treePath_);
88 counter.gather(localView, node, localCounter);
89 coeff0.gather(localView, node, localCoeffs);
90
91 for (std::size_t i = 0; i < node.size(); ++i) {
92 if (localCounter[i] > 0) {
93 auto idx = localView.index(node.localIndex(i));
94 coeffMap[idx] = localCoeffs[i];
95 counterMap[idx] = localCounter[i];
96 }
97 }
98 }
99
100 assert(coeffMap.size() == counterMap.size());
101
102 // assign computed values to target vector
103 auto value_it = coeffMap.begin();
104 auto count_it = counterMap.begin();
105 for (; value_it != coeffMap.end(); ++value_it, ++count_it) {
106 assert(count_it->second > 0);
107 coeff.set(value_it->first, value_it->second/double(count_it->second));
108 }
109 coeff.finish();
110 }
111
112 template <class Coeff, class GridFct>
113 void operator()(Coeff& coeff, GridFct const& gf) const
114 {
115 (*this)(coeff, gf, FakeContainer<bool,true>{});
116 }
117
118 AverageInterpolator(Basis const& basis, TreePath treePath = {})
119 : basis_{basis}
120 , treePath_{treePath}
121 {}
122
123 Basis const& basis_;
124 TreePath treePath_ = {};
125 };
126
127
128 template <>
129 struct InterpolatorFactory<tag::average>
130 {
131 template <class Basis,
132 class TreePath = Dune::TypeTree::TreePath<>>
133 static auto create(Basis const& basis, TreePath treePath = {})
134 {
135 return AverageInterpolator<Basis,TreePath>{basis, treePath};
136 }
137 };
138
139} // end namespace AMDiS
A container-like data-structure not storing anything and with empty implementations in many container...
Definition FakeContainer.hpp:36
Definition Assigner.hpp:17
Definition AverageInterpolator.hpp:28
Definition HierarchicNodeToRangeMap.hpp:42
Definition SimpleInterpolator.hpp:83
Definition AverageInterpolator.hpp:22