Loading [MathJax]/extensions/tex2jax.js

DUNE-FUNCTIONS (unstable)

finefunctiononcoarsegridview.hh
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3
4// SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file AUTHORS.md
5// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception OR LGPL-3.0-or-later
6
7#ifndef DUNE_FUNCTIONS_GRIDFUNCTIONS_FINEFUNCTIONONCOARSEGRIDVIEW_HH
8#define DUNE_FUNCTIONS_GRIDFUNCTIONS_FINEFUNCTIONONCOARSEGRIDVIEW_HH
9
10#include <optional>
11#include <type_traits>
12#include <utility>
13#include <limits>
14#include <algorithm>
15#include <cmath>
16
17#include <dune/common/referencehelper.hh>
18
19#include <dune/geometry/type.hh>
20
21#include <dune/functions/common/defaultderivativetraits.hh>
22#include <dune/functions/gridfunctions/gridfunction.hh>
23#include <dune/functions/gridfunctions/gridviewentityset.hh>
24
25namespace Dune::Functions {
26
27namespace Impl {
28
29namespace ReferenceElementUtilities {
30
31// Compute the l1-distance of x to the reference element identified
32// by the topology id and dimension.
33template<class X, class FT = std::decay_t<decltype(std::declval<X>()[0])> >
34FT distance(unsigned int topologyId, int dim, X x, FT scaleFactor = FT(1))
35{
36 using std::abs;
37 using std::max;
38 using std::min;
39 auto dist_x_last = max(max(x[dim-1]-scaleFactor, -x[dim-1]), FT(0));
40 if (dim > 1)
41 {
42 if (Dune::Impl::isPyramid(topologyId, dim))
43 scaleFactor -= max(min(x[dim-1], scaleFactor), FT(0));
44 return distance(Dune::Impl::baseTopologyId(topologyId, dim), dim-1, x, scaleFactor) + dist_x_last;
45 }
46 if (dim == 1)
47 return dist_x_last;
48 return FT(0);
49}
50
51// Check if the l1-distance of x to the reference element identified
52// by the topology id and dimension is less than a tolerance. This
53// implementation is significantly faster than checking if
54// distance(...) <= tolerance. It is almost as fast as checkInside(...)
55// of the refenece element, but the latter does not reflect the
56// distance wrt any norm while we use the l1-norm here.
57template<class X, class FT = std::decay_t<decltype(std::declval<X>()[0])> >
58bool checkInside(unsigned int topologyId, int dim, X x, FT tolerance, FT scaleFactor = FT(1))
59{
60 using std::abs;
61 using std::max;
62 using std::min;
63 if (dim > 0)
64 {
65 auto dist_x_last = max(x[dim-1]-scaleFactor, -x[dim-1]);
66 if (dist_x_last <= tolerance)
67 {
68 if (Dune::Impl::isPyramid(topologyId, dim))
69 scaleFactor -= max(min(x[dim-1], scaleFactor), FT(0));
70 return checkInside(Dune::Impl::baseTopologyId(topologyId, dim), dim-1, x, tolerance - max(dist_x_last, FT(0)), scaleFactor);
71 }
72 return false;
73 }
74 return true;
75}
76
77} // namespace ReferenceElementUtilities
78
79} // namespace Impl
80
81
82
83
84
85
86
101template<class GridFunction, class GV, template<class> class DerivativeTraits=Dune::Functions::DefaultDerivativeTraits>
103{
104 using RawGridFunction = Dune::ResolveRef_t<GridFunction>;
105
106 auto&& rawFunction() const
107 {
108 return Dune::resolveRef(function_);
109 }
110
111 static constexpr auto dim = GV::Grid::dimension;
112
113public:
114
115 using GridView = GV;
117 using Element = typename EntitySet::Element;
118 using Domain = typename EntitySet::GlobalCoordinate;
119 using LocalDomain = typename EntitySet::LocalCoordinate;
120 using Range = std::decay_t<decltype(std::declval<RawGridFunction>()(std::declval<Domain>()))>;
121
122private:
123
124 using FineEntitySet = std::decay_t<decltype(std::declval<RawGridFunction>().entitySet())>;
125 using Traits = Dune::Functions::Imp::GridFunctionTraits<Range(Domain), EntitySet, DerivativeTraits, 56>;
126
127 class FineLocalFunctionOnCoarseGridView
128 {
129 using Traits = typename FineFunctionOnCoarseGridView::Traits::LocalFunctionTraits;
130
131 public:
132
133 using Derivative = decltype(localFunction(derivative(std::declval<FineFunctionOnCoarseGridView>())));
134 using RawLocalFunction = std::decay_t<decltype(localFunction(std::declval<const RawGridFunction&>()))>;
135
141 FineLocalFunctionOnCoarseGridView(RawLocalFunction&& localFunction, const FineEntitySet& fineEntitySet)
142 : element_()
143 , localFunction_(localFunction)
144 , fineEntitySet_(fineEntitySet)
145 , forwardToFineFunction_(false)
146 {}
147
153 FineLocalFunctionOnCoarseGridView(
154 RawLocalFunction&& localFunction,
155 const FineEntitySet& fineEntitySet,
156 bool forwardToFineFunction,
157 const std::optional<Element>& element
158 )
159 : element_(element)
160 , localFunction_(localFunction)
161 , fineEntitySet_(fineEntitySet)
162 , forwardToFineFunction_(forwardToFineFunction)
163 {}
164
166 void bind(const Element& element)
167 {
168 element_ = element;
169 forwardToFineFunction_ = fineEntitySet_.contains(*element_);
170 if (forwardToFineFunction_)
171 localFunction_.bind(element);
172 }
173
175 void unbind()
176 {
177 element_.reset();
178 }
179
181 bool bound() const
182 {
183 return static_cast<bool>(element_);
184 }
185
187 const Element& localContext() const
188 {
189 return *element_;
190 }
191
193 friend auto derivative(const FineLocalFunctionOnCoarseGridView& f)
194 {
195 if constexpr(requires{ derivative(f.localFunction_); })
196 return Derivative(derivative(f.localFunction_), f.fineEntitySet_, f.forwardToFineFunction_, f.element_);
197 else
198 return typename Traits::DerivativeInterface{};
199 }
200
202 Range operator()(LocalDomain x) const
203 {
204 if (forwardToFineFunction_)
205 return localFunction_(x);
206 return evaluateInDescendent(*element_, x);
207 }
208
209 private:
210
211 // Find a child containing the point and evaluate there recursively
212 Range evaluateInDescendent(const Element& element, LocalDomain x) const
213 {
214 Element closestChild;
215 LocalDomain xInClosestChild;
216 double distanceToClosestChild = std::numeric_limits<double>::max();
217 for(const auto& child : descendantElements(element, element.level()+1))
218 {
219 auto&& geometry = child.geometryInFather();
220 auto xInChild = geometry.local(x);
221 auto dist = Impl::ReferenceElementUtilities::distance(child.type().id(), dim, xInChild);
222 if (dist < distanceToClosestChild)
223 {
224 closestChild = child;
225 distanceToClosestChild = dist;
226 xInClosestChild = xInChild;
227 if (distanceToClosestChild==0)
228 break;
229 }
230 }
231 if (fineEntitySet_.contains(closestChild))
232 {
233 localFunction_.bind(closestChild);
234 return localFunction_(xInClosestChild);
235 }
236 else
237 return evaluateInDescendent(closestChild, xInClosestChild);
238 }
239
240 std::optional<Element> element_;
241 mutable RawLocalFunction localFunction_;
242 const FineEntitySet& fineEntitySet_;
243 bool forwardToFineFunction_ = false;
244 };
245
246public:
247
248 using LocalFunction = FineLocalFunctionOnCoarseGridView;
249
256 FineFunctionOnCoarseGridView(const GridFunction& function, const GridView& gridView)
257 : function_(function)
258 , entitySet_(gridView)
259 {}
260
267 FineFunctionOnCoarseGridView(GridFunction&& function, const GridView& gridView)
268 : function_(std::move(function))
269 , entitySet_(gridView)
270 {}
271
273 Range operator()(const Domain& x) const
274 {
275 return function_(x);
276 }
277
280 {
281 if constexpr(requires{ derivative(f.rawFunction()); })
282 {
283 using RawDerivative = std::decay_t<decltype(derivative(f.rawFunction()))>;
285 }
286 else
287 return typename Traits::DerivativeInterface{};
288 }
289
291 friend LocalFunction localFunction(const FineFunctionOnCoarseGridView& f)
292 {
293 return LocalFunction(localFunction(f.rawFunction()), f.rawFunction().entitySet());
294 }
295
297 const EntitySet& entitySet() const
298 {
299 return entitySet_;
300 }
301
302protected:
303
304 GridFunction function_;
305 EntitySet entitySet_;
306};
307
308
309
310} // namespace Dune::Functions
311
312#endif // DUNE_FUNCTIONS_GRIDFUNCTIONS_FINEFUNCTIONONCOARSEGRIDVIEW_HH
A wrapper representing a fine grid function on a gridview.
Definition: finefunctiononcoarsegridview.hh:103
Range operator()(const Domain &x) const
Evaluate function in global coordinates.
Definition: finefunctiononcoarsegridview.hh:273
FineFunctionOnCoarseGridView(const GridFunction &function, const GridView &gridView)
Create FineFunctionOnCoarseGridView from GridFunction and GridView.
Definition: finefunctiononcoarsegridview.hh:256
friend auto derivative(const FineFunctionOnCoarseGridView &f)
Obtain global derivative of this function.
Definition: finefunctiononcoarsegridview.hh:279
FineFunctionOnCoarseGridView(GridFunction &&function, const GridView &gridView)
Create FineFunctionOnCoarseGridView from GridFunction and GridView.
Definition: finefunctiononcoarsegridview.hh:267
friend LocalFunction localFunction(const FineFunctionOnCoarseGridView &f)
Create a LocalFunction for evaluation in local coordinates.
Definition: finefunctiononcoarsegridview.hh:291
const EntitySet & entitySet() const
Return the EntitySet associated to this GridViewFunction.
Definition: finefunctiononcoarsegridview.hh:297
GridView::template Codim< codim >::Entity Element
Type of Elements contained in this EntitySet.
Definition: gridviewentityset.hh:36
const GridView & gridView() const
Return the associated GridView.
Definition: gridviewentityset.hh:80
Element::Geometry::LocalCoordinate LocalCoordinate
Type of local coordinates with respect to the Element.
Definition: gridviewentityset.hh:39
Default implementation for derivative traits.
Definition: defaultderivativetraits.hh:41
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden & Uni Heidelberg  |  generated with Hugo v0.111.3 (Mar 12, 23:28, 2025)