version 3.11-dev
interpolate.hh
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3//
4// SPDX-FileCopyrightText: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5// SPDX-License-Identifier: GPL-3.0-or-later
6//
12#ifndef DUMUX_DISCRETIZATION_CVFE_INTERPOLATE_HH
13#define DUMUX_DISCRETIZATION_CVFE_INTERPOLATE_HH
14
15#include <cassert>
16#include <optional>
17#include <ranges>
18#include <type_traits>
19
20#include <dune/grid/common/rangegenerators.hh>
22#include <dumux/common/tag.hh>
24#include <dumux/common/concepts/ipdata_.hh>
26
28
33struct DofPositionEvaluation : public Utility::Tag<DofPositionEvaluation> {};
34
39struct L2Projection : public Utility::Tag<L2Projection>
40{
41 std::size_t maxIterations = 100;
42 double residualReduction = 1e-13;
43 int verbosity = 0;
44};
45
46
47} // end namespace Dumux::CVFE::InterpolationPolicy
48
49namespace Dumux::CVFE {
50
51namespace Detail {
52
53template<class ElementDiscretization, class Function, class ValueType>
55 const ElementDiscretization& eDisc,
56 const std::ranges::range_value_t<decltype(localDofs(eDisc))>& ld,
57 Function& f,
58 ValueType& v)
59{
60 { ipData(eDisc, ld) } -> Concept::LocalDofIpData;
61 v = f(eDisc, ipData(eDisc, ld));
62};
63
64template<class ElementDiscretization, class Function, class ValueType>
65concept InterpolatableAtGlobalPos = requires(
66 typename ElementDiscretization::Element::Geometry::GlobalCoordinate globalPos,
67 Function& f,
68 ValueType& v)
69{ v = f(globalPos); };
70
71template<class ElementDiscretization, class Function, class ValueType>
73 ElementDiscretization& eDisc,
74 typename ElementDiscretization::Element::Geometry::GlobalCoordinate globalPos,
75 Function& f,
76 ValueType& v)
77{ v = f(eDisc, globalPos); };
78
86template<class GridDiscretization, class Function>
88{
89 using ElementDiscretization = typename GridDiscretization::LocalView;
90 using Element = typename ElementDiscretization::Element;
91 using LocalCoord = typename Element::Geometry::LocalCoordinate;
92 using GlobalPos = typename Element::Geometry::GlobalCoordinate;
93
94public:
95 LocalFunctionAdapter(const GridDiscretization& gridDisc, Function f)
96 : function_(std::move(f))
97 , elemDisc_(localView(gridDisc))
98 {}
99
100 void bind(const Element& element)
101 {
102 element_.emplace(element);
103 elemDisc_.bind(element);
104 }
105
106 auto operator()(const LocalCoord& localCoord)
107 {
108 const GlobalPos globalPos = elemDisc_.elementGeometry().global(localCoord);
109 if constexpr (requires(ElementDiscretization& elemDisc , GlobalPos g, std::decay_t<Function>& f){ f(elemDisc, g); })
110 return function_(elemDisc_, globalPos);
111 else
112 return function_(globalPos);
113 }
114
115private:
116 Function function_;
117 ElementDiscretization elemDisc_;
118 std::optional<Element> element_;
119};
120
121template<class GridDiscretization, class Function>
122auto makeLocalFunctionAdapter(const GridDiscretization& gridDisc, Function&& f)
123{
125 gridDisc, std::forward<Function>(f));
126}
127
128} // end namespace Detail
129
136template<class GridDiscretization, class CoefficientVector, class Function>
137void interpolate(const GridDiscretization& gridDisc,
138 CoefficientVector& coeffs,
139 Function&& function,
141requires (Detail::InterpolatableAtElemDiscIpData<typename GridDiscretization::LocalView, Function, typename CoefficientVector::value_type>
142 || Detail::InterpolatableAtElemDiscGlobalPos<typename GridDiscretization::LocalView, Function, typename CoefficientVector::value_type>
143 || Detail::InterpolatableAtGlobalPos<typename GridDiscretization::LocalView, Function, typename CoefficientVector::value_type>)
144{
145 using LocalView = typename GridDiscretization::LocalView;
146 using ValueType = typename CoefficientVector::value_type;
147 auto elemDisc = localView(gridDisc);
148 for (const auto& element : elements(gridDisc.gridView()))
149 {
150 elemDisc.bind(element);
151 for (const auto& localDof : localDofs(elemDisc))
152 {
153 if constexpr (Detail::InterpolatableAtElemDiscIpData<LocalView, Function, ValueType>)
154 coeffs[localDof.dofIndex()] = function(elemDisc, ipData(elemDisc, localDof));
155 else if constexpr (Detail::InterpolatableAtElemDiscGlobalPos<LocalView, Function, ValueType>)
156 coeffs[localDof.dofIndex()] = function(elemDisc, ipData(elemDisc, localDof).global());
157 else
158 coeffs[localDof.dofIndex()] = function(ipData(elemDisc, localDof).global());
159 }
160 }
161}
162
170template<class GridDiscretization, class CoefficientVector, class Function>
171void interpolate(const GridDiscretization& gridDisc,
172 CoefficientVector& coeffs,
173 Function&& function,
177{
179 const Basis basis(gridDisc);
180 using L2Proj = Dumux::L2Projection<Basis>;
181
182 typename L2Proj::Params params;
183 params.maxIterations = policy.maxIterations;
184 params.residualReduction = policy.residualReduction;
185 params.verbosity = policy.verbosity;
186
187 auto localFunction = Detail::makeLocalFunctionAdapter(gridDisc, std::forward<Function>(function));
188 const L2Proj projection(basis);
189 const auto result = projection.project(localFunction, params);
190 assert(coeffs.size() == result.size());
191 using ResultValue = typename decltype(result)::value_type; // FieldVector<Scalar, numEq>
192 constexpr int numEq = ResultValue::dimension;
193 for (std::size_t i = 0; i < result.size(); ++i)
194 if constexpr (numEq == 1)
195 coeffs[i] = result[i][0];
196 else
197 coeffs[i] = result[i];
198}
199
200} // end namespace Dumux::CVFE
201
202#endif
Wraps a function callable as f(globalPos) or f(elemDisc, globalPos) into a local-function interface: ...
Definition: interpolate.hh:88
LocalFunctionAdapter(const GridDiscretization &gridDisc, Function f)
Definition: interpolate.hh:95
void bind(const Element &element)
Definition: interpolate.hh:100
auto operator()(const LocalCoord &localCoord)
Definition: interpolate.hh:106
Wraps a CVFE grid discretization to expose the FE basis interface expected by L2Projection.
Definition: l2_projection.hh:81
Definition: l2_projection.hh:136
GridCache::LocalView localView(const GridCache &gridCache)
Free function to get the local view of a grid cache object.
Definition: localview.hh:26
void interpolate(const GridDiscretization &gridDisc, CoefficientVector &coeffs, Function &&function, InterpolationPolicy::DofPositionEvaluation={})
Interpolate a function into a coefficient vector by evaluating it at the dof positions.
Definition: interpolate.hh:137
L2-projections of analytic functions into a given function space.
Class representing dofs on elements for control-volume finite element schemes.
Free function to get the local view of a grid cache object.
Dumux::CVFE::LocalDofInterpolationPointData< typename GridView::template Codim< 0 >::Entity::Geometry::LocalCoordinate, typename GridView::template Codim< 0 >::Entity::Geometry::GlobalCoordinate, typename IndexTraits< GridView >::LocalIndex > LocalDofIpData
Default LocalDofInterpolationPointData type.
Definition: quadraturerules.hh:146
auto makeLocalFunctionAdapter(const GridDiscretization &gridDisc, Function &&f)
Definition: interpolate.hh:122
Definition: interpolate.hh:27
Definition: interpolate.hh:27
constexpr Projection projection
Definition: couplingmanager1d3d_projection.hh:263
auto localDofs(const FVElementGeometry &fvGeometry)
range over local dofs
Definition: localdof.hh:50
Interpolation policy that evaluates a function at the dof positions.
Definition: interpolate.hh:33
Interpolation policy that uses an L2 projection.
Definition: interpolate.hh:40
int verbosity
Definition: interpolate.hh:43
double residualReduction
Definition: interpolate.hh:42
std::size_t maxIterations
Definition: interpolate.hh:41
Helper class to create (named and comparable) tagged types Tags any given type. The tagged type is eq...
Definition: tag.hh:30
Helper class to create (named and comparable) tagged types.