7#ifndef DUNE_FUFEM_ASSEMBLERS_BASIS_INTERPOLATION_MATRIX_ASSEMBLER_HH
8#define DUNE_FUFEM_ASSEMBLERS_BASIS_INTERPOLATION_MATRIX_ASSEMBLER_HH
20#if DUNE_VERSION_GTE(DUNE_FUNCTIONS, 2, 11)
24#include <dune/typetree/childextraction.hh>
25#include <dune/typetree/traversal.hh>
44template<
class CoarseFiniteElement,
class FineFiniteElement,
class Geometry>
45class LocalInterpolationOperator
47 using CoarseLocalBasis =
typename CoarseFiniteElement::Traits::LocalBasisType;
48 using CoarseRange =
typename CoarseLocalBasis::Traits::RangeType;
51 using CoefficientType =
typename CoarseLocalBasis::Traits::RangeFieldType;
53 using FineLocalInterpolation =
typename FineFiniteElement::Traits::LocalInterpolationType;
57 LocalInterpolationOperator(
const CoarseFiniteElement& coarseFiniteElement,
const FineFiniteElement& fineFiniteElement,
const Geometry& geometry)
58 : coarseLocalBasis_(coarseFiniteElement.localBasis())
59 , fineLocalInterpolation_(fineFiniteElement.localInterpolation())
61 , coefficients_(fineFiniteElement.
size())
62 , coarseValues_(fineFiniteElement.
size())
78 auto trackingCoarseFunction = [&](
const auto& x) {
79 coarseValues_.resize(k+1);
80 coarseLocalBasis_.evaluateFunction(geometry_(x), coarseValues_[k]);
81 return coarseValues_[k++][0];
83 fineLocalInterpolation_.interpolate(trackingCoarseFunction, coefficients_);
86 const auto& bindToCoarseBasisFunction(
std::size_t coarseIndex)
92 auto baseFctj = [&](
const auto& x) {
93 return coarseValues_[k++][coarseIndex];
97 fineLocalInterpolation_.interpolate(baseFctj, coefficients_);
101 const auto& coefficients()
const
103 return coefficients_;
107 const CoarseLocalBasis& coarseLocalBasis_;
108 const FineLocalInterpolation& fineLocalInterpolation_;
109 const Geometry& geometry_;
130template<
class MatrixType,
class CoarseBasis,
class FineBasis>
132 const CoarseBasis& coarseBasis,
133 const FineBasis& fineBasis,
134 const double tolerance = 1e-12)
136 const auto& coarseGridView = coarseBasis.gridView();
137 const auto& fineGridView = fineBasis.gridView();
139 auto coarseLocalView = coarseBasis.localView();
140 auto fineLocalView = fineBasis.localView();
143 constexpr bool isAssemblerMatrixBackend =
requires(MatrixType& matrixBackend) {
144 MatrixType::LocalPattern(0,0);
145 matrixBackend.setZero();
148 constexpr bool isFufemMatrixBackend =
requires(MatrixType& matrixBackend) {
149 matrixBackend.matrix();
150 matrixBackend.assign(0);
156 auto&& matrixBackend = [&]() ->
decltype(
auto) {
157 if constexpr(isAssemblerMatrixBackend)
159 else if constexpr(isFufemMatrixBackend)
166 auto patternBuilder = matrixBackend.patternBuilder();
167 patternBuilder.resize(fineBasis, coarseBasis);
175 using GeometryInFather =
std::decay_t<
decltype(elements(fineGridView).begin()->geometryInFather())>;
177 const auto geometryInFathers = [&](
auto&& x) {
179 for (
const auto& g : geometryInFathersVector)
184 using MatrixBackend =
std::decay_t<
decltype(matrixBackend)>;
186 auto localPattern =
typename MatrixBackend::LocalPattern(fineLocalView.maxSize(), coarseLocalView.maxSize());
189 for (
const auto& fineElement : elements(fineGridView) )
191 fineLocalView.bind(fineElement);
195 auto coarseElement = fineElement;
197 geometryInFathersVector.clear();
198 while ( not coarseGridView.contains(coarseElement) and coarseElement.hasFather() )
201 geometryInFathersVector.push_back(coarseElement.geometryInFather());
203 coarseElement = coarseElement.father();
207 if ( not coarseGridView.contains(coarseElement) )
210 coarseLocalView.bind(coarseElement);
212 localPattern.resize(fineLocalView.size(), coarseLocalView.size());
213 localPattern.clear();
216 auto&& fineNode = Dune::TypeTree::child(fineLocalView.tree(), treePath);
218 auto localInterpolationOperator = Impl::LocalInterpolationOperator(coarseNode.finiteElement(), fineNode.finiteElement(), geometryInFathers);
219 const auto& coefficients = localInterpolationOperator.coefficients();
221 for (auto j : Dune::range(coarseNode.size()))
223 localInterpolationOperator.bindToCoarseBasisFunction(j);
224 for (auto i : Dune::range(fineNode.size()))
226 if (std::abs(coefficients[i]) >= tolerance)
227 localPattern.add(fineNode.localIndex(i), coarseNode.localIndex(j));
231 patternBuilder.scatter(fineLocalView, coarseLocalView, localPattern);
235 patternBuilder.setupMatrix();
241 for (
const auto& fineElement :
elements(fineGridView) )
243 fineLocalView.bind(fineElement);
247 auto coarseElement = fineElement;
249 geometryInFathersVector.clear();
250 while ( not coarseGridView.contains(coarseElement) and coarseElement.hasFather() )
253 geometryInFathersVector.push_back(coarseElement.geometryInFather());
255 coarseElement = coarseElement.father();
258 coarseLocalView.bind(coarseElement);
264 auto&& fineNode = Dune::TypeTree::child(fineLocalView.tree(), treePath);
266 auto localInterpolationOperator = Impl::LocalInterpolationOperator(coarseNode.finiteElement(), fineNode.finiteElement(), geometryInFathers);
267 const auto& coefficients = localInterpolationOperator.coefficients();
269 for (auto j : Dune::range(coarseNode.size()))
271 localInterpolationOperator.bindToCoarseBasisFunction(j);
272 const auto& globalCoarseIndex = coarseLocalView.index( coarseNode.localIndex( j ) );
273 for (auto i : Dune::range(fineNode.size()))
275 if (std::abs(coefficients[i]) >= tolerance)
277 const auto& globalFineIndex = fineLocalView.index( fineNode.localIndex( i ) );
278 matrixBackend(globalFineIndex, globalCoarseIndex) = coefficients[i];
#define DUNE_THROW(E,...)
void forEachLeafNode(Tree &&tree, LeafFunc &&leafFunc)
IteratorRange<... > elements(const GV &gv)
static void assembleGlobalBasisTransferMatrix(MatrixType &matrix, const CoarseBasis &coarseBasis, const FineBasis &fineBasis, const double tolerance=1e-12)
Assemble the transfer matrix for multigrid methods.
Definition basisinterpolationmatrixassembler.hh:131