AMDiS 2.10
The Adaptive Multi-Dimensional Simulation Toolbox
CoarsenedGridFunction.hpp
1#pragma once
2
3#include <functional>
4#include <type_traits>
5
6#include <dune/common/referencehelper.hh>
7#include <dune/functions/gridfunctions/gridviewentityset.hh>
8
9#include <amdis/common/TypeTraits.hpp>
10#include <amdis/Output.hpp>
11
12// backport of dune/functions/gridfunctions/coarsenedgridfunction.hh
13
14namespace AMDiS {
15
17
26template <class GV, class GF>
28{
29public:
31 using EntitySet = Dune::Functions::GridViewEntitySet<GV,0>;
32
34 using Domain = typename EntitySet::GlobalCoordinate;
35
37 using Range = std::invoke_result_t<GF, Domain>;
38
40 using LocalDomain = typename EntitySet::LocalCoordinate;
41
43 using Element = typename EntitySet::Element;
44
45 using Grid = typename GV::Grid;
46 using Geometry = typename Element::Geometry;
47
48 template <class ES, class LF>
50 {
51 public:
52 using Domain = LocalDomain;
53 using Range = CoarsenedGridFunction::Range;
54 using Element = CoarsenedGridFunction::Element;
55
56 using Mapping = std::function<Domain(Domain const&)>;
57 struct ChildElement {
58 typename Element::HierarchicIterator it;
59 Mapping local;
60 };
61
62 public:
64 CoarsenedLocalFunction(ES const& entitySet, LF const& localFct, int maxLevel)
65 : entitySet_(entitySet)
66 , localFct_(localFct)
67 , maxLevel_(maxLevel)
68 {}
69
70 CoarsenedLocalFunction(ES const& entitySet, LF&& localFct, int maxLevel)
71 : entitySet_(entitySet)
72 , localFct_(std::move(localFct))
73 , maxLevel_(maxLevel)
74 {}
75
77
82 void bind(Element const& element)
83 {
84 element_.emplace(element);
85
86 childs_.clear();
87 if (entitySet_.contains(*element_)) {
88 localFct_.bind(*element_);
89 return;
90 }
91
92 test_exit_dbg(!element_->isLeaf(), "Element is leaf. Cannot traverse its children.");
93 for (auto it = element_->hbegin(maxLevel_); it != element_->hend(maxLevel_); ++it) {
94 if (entitySet_.contains(*it))
95 childs_.emplace_back(ChildElement{.it=it, .local=makeMapping(*element_,*it)});
96 }
97
98 test_exit_dbg(!childs_.empty(), "No child element in entitySet found!");
99 }
100
102 void unbind()
103 {
104 element_.reset();
105 }
106
108 bool bound() const
109 {
110 return !!element_;
111 }
112
114 Range operator()(Domain const& x) const
115 {
116 if (childs_.empty())
117 return localFct_(x);
118
119 // calculate checkInsideTolerance
120 typename Grid::ctype const checkInsideTolerance = std::sqrt(std::numeric_limits<typename Grid::ctype>::epsilon());
121 for (auto const& child : childs_) {
122 auto refElem = referenceElement(*child.it);
123 auto local = child.local(x);
124 auto refTypeId = refElem.type().id();
125 bool isInside = Dune::Geo::Impl::checkInside(refTypeId, Geometry::mydimension, local, checkInsideTolerance);
126 if (isInside) {
127 localFct_.bind(*child.it);
128 return localFct_(local);
129 }
130 }
131
132 error_exit("No child element with x in child found!");
133 return Range{};
134 }
135
137 Element const& localContext() const
138 {
139 assert(!!element_);
140 return *element_;
141 }
142
144 template <class LF_ = LF>
145 auto makeDerivative() const
146 -> CoarsenedLocalFunction<ES,TYPEOF(derivative(std::declval<LF_ const&>()))>
147 {
149 entitySet_, derivative(localFct_)};
150
151 // bind derivative if this is bound
152 if (bound())
153 df.bind(*element_);
154 return df;
155 }
156
157 protected:
158 // Construct the coordinate mapping
159 Mapping makeMapping(Element const& coarse, Element fine) const
160 {
161 Mapping map = [](Domain const& x) { return x; };
162 while (coarse != fine && fine.hasFather()) {
163 map = [map, geo=fine.geometryInFather()](Domain const& x) {
164 return map(geo.local(x));
165 };
166 fine = fine.father();
167 }
168 return map;
169 }
170
171 private:
172 ES const& entitySet_;
173 mutable LF localFct_;
174 int maxLevel_;
175 std::optional<Element> element_;
176
177 std::vector<ChildElement> childs_;
178 };
179
180
182
186 CoarsenedGridFunction(GV const& gridView, GF const& gridFct)
187 : gridView_{gridView}
188 , entitySet_{gridView}
189 , gridFct_{gridFct}
190 {}
191
192 CoarsenedGridFunction(GV const& gridView, GF&& gridFct)
193 : gridView_{gridView}
194 , entitySet_{gridView}
195 , gridFct_{std::move(gridFct)}
196 {}
197
199 Range operator()(Domain const& x) const
200 {
201 return gridFct_(x);
202 }
203
205 template <class GF_ = GF>
206 auto makeDerivative() const
208 TYPEOF(derivative(Dune::resolveRef(std::declval<GF_ const&>())))>
209 {
210 return {gridView_, derivative(Dune::resolveRef(gridFct_))};
211 }
212
214 auto makeLocalFunction() const
215 {
216 using LF = TYPEOF(localFunction(Dune::resolveRef(gridFct_)));
217 using LocalFunction = CoarsenedLocalFunction<EntitySet,LF>;
218 return LocalFunction{gridFct_.entitySet(),
219 localFunction(Dune::resolveRef(gridFct_)),
220 gridView_.grid().maxLevel()};
221 }
222
224 EntitySet const& entitySet () const
225 {
226 return entitySet_;
227 }
228
229private:
230 GV gridView_;
231 EntitySet entitySet_;
232 GF gridFct_;
233};
234
235} // end namespace AMDiS
Definition: CoarsenedGridFunction.hpp:50
auto makeDerivative() const -> CoarsenedLocalFunction< ES, TYPEOF(derivative(std::declval< LF_ const & >()))>
Construct a derivative by wrapping the derivative of the wrapped local-function.
Definition: CoarsenedGridFunction.hpp:145
bool bound() const
Check whether the LocalFunction is bound to an element.
Definition: CoarsenedGridFunction.hpp:108
Range operator()(Domain const &x) const
Evaluate LocalFunction at bound element.
Definition: CoarsenedGridFunction.hpp:114
void bind(Element const &element)
Bind the wrapped local-function to grid element.
Definition: CoarsenedGridFunction.hpp:82
CoarsenedLocalFunction(ES const &entitySet, LF const &localFct, int maxLevel)
Constructor. Stores the localFct by value.
Definition: CoarsenedGridFunction.hpp:64
Element const & localContext() const
Return the element this LocalFunction is bound to.
Definition: CoarsenedGridFunction.hpp:137
void unbind()
Unbind the wrapped local-function.
Definition: CoarsenedGridFunction.hpp:102
A grid function defining data on a coarser entity level than it can be bound to.
Definition: CoarsenedGridFunction.hpp:28
std::invoke_result_t< GF, Domain > Range
The result type of the function.
Definition: CoarsenedGridFunction.hpp:37
auto makeDerivative() const -> CoarsenedGridFunction< GV, TYPEOF(derivative(Dune::resolveRef(std::declval< GF_ const & >())))>
Construct a derivative by wrapping the derivative of the wrapped grid-function.
Definition: CoarsenedGridFunction.hpp:206
typename EntitySet::GlobalCoordinate Domain
The global coordinates.
Definition: CoarsenedGridFunction.hpp:34
Range operator()(Domain const &x) const
Evaluate the wrapped grid-function.
Definition: CoarsenedGridFunction.hpp:199
typename EntitySet::Element Element
Type of the grid element the LocalFunction can be bound to.
Definition: CoarsenedGridFunction.hpp:43
auto makeLocalFunction() const
Construct local function from a DiscreteGlobalBasisFunction.
Definition: CoarsenedGridFunction.hpp:214
EntitySet const & entitySet() const
Get associated EntitySet.
Definition: CoarsenedGridFunction.hpp:224
typename EntitySet::LocalCoordinate LocalDomain
The local coordinates.
Definition: CoarsenedGridFunction.hpp:40
CoarsenedGridFunction(GV const &gridView, GF const &gridFct)
Constructor.
Definition: CoarsenedGridFunction.hpp:186
Dune::Functions::GridViewEntitySet< GV, 0 > EntitySet
The set of entities this function can be evaluated on.
Definition: CoarsenedGridFunction.hpp:31