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 
14 namespace AMDiS {
15 
17 
26 template <class GV, class GF>
28 {
29 public:
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
207  -> CoarsenedGridFunction<GV,
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 
229 private:
230  GV gridView_;
231  EntitySet entitySet_;
232  GF gridFct_;
233 };
234 
235 } // end namespace AMDiS
auto makeLocalFunction() const
Construct local function from a DiscreteGlobalBasisFunction.
Definition: CoarsenedGridFunction.hpp:214
Range operator()(Domain const &x) const
Evaluate the wrapped grid-function.
Definition: CoarsenedGridFunction.hpp:199
Definition: AdaptiveGrid.hpp:393
void bind(Element const &element)
Bind the wrapped local-function to grid element.
Definition: CoarsenedGridFunction.hpp:82
Definition: FieldMatVec.hpp:12
Definition: CoarsenedGridFunction.hpp:49
typename EntitySet::Element Element
Type of the grid element the LocalFunction can be bound to.
Definition: CoarsenedGridFunction.hpp:43
Definition: AdaptBase.hpp:6
void unbind()
Unbind the wrapped local-function.
Definition: CoarsenedGridFunction.hpp:102
Range operator()(Domain const &x) const
Evaluate LocalFunction at bound element.
Definition: CoarsenedGridFunction.hpp:114
typename EntitySet::GlobalCoordinate Domain
The global coordinates.
Definition: CoarsenedGridFunction.hpp:34
Dune::Functions::GridViewEntitySet< GV, 0 > EntitySet
The set of entities this function can be evaluated on.
Definition: CoarsenedGridFunction.hpp:31
CoarsenedGridFunction(GV const &gridView, GF const &gridFct)
Constructor.
Definition: CoarsenedGridFunction.hpp:186
bool bound() const
Check whether the LocalFunction is bound to an element.
Definition: CoarsenedGridFunction.hpp:108
EntitySet const & entitySet() const
Get associated EntitySet.
Definition: CoarsenedGridFunction.hpp:224
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
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
A grid function defining data on a coarser entity level than it can be bound to.
Definition: CoarsenedGridFunction.hpp:27
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
std::invoke_result_t< GF, Domain > Range
The result type of the function.
Definition: CoarsenedGridFunction.hpp:37
typename EntitySet::LocalCoordinate LocalDomain
The local coordinates.
Definition: CoarsenedGridFunction.hpp:40