7#ifndef DUNE_FUFEM_ASSEMBLERS_BASIS_INTERPOLATION_MATRIX_ASSEMBLER_HH
8#define DUNE_FUFEM_ASSEMBLERS_BASIS_INTERPOLATION_MATRIX_ASSEMBLER_HH
37template<
class CoarseFiniteElement,
class FineFiniteElement,
class Geometry>
38class LocalInterpolationOperator
40 using CoarseLocalBasis =
typename CoarseFiniteElement::Traits::LocalBasisType;
41 using CoarseRange =
typename CoarseLocalBasis::Traits::RangeType;
44 using CoefficientType =
typename CoarseLocalBasis::Traits::RangeFieldType;
46 using FineLocalInterpolation =
typename FineFiniteElement::Traits::LocalInterpolationType;
50 LocalInterpolationOperator(
const CoarseFiniteElement& coarseFiniteElement,
const FineFiniteElement& fineFiniteElement,
const Geometry& geometry)
51 : coarseLocalBasis_(coarseFiniteElement.localBasis())
52 , fineLocalInterpolation_(fineFiniteElement.localInterpolation())
54 , coefficients_(fineFiniteElement.
size())
55 , coarseValues_(fineFiniteElement.
size())
71 auto trackingCoarseFunction = [&](
const auto& x) {
72 coarseValues_.resize(k+1);
73 coarseLocalBasis_.evaluateFunction(geometry_(x), coarseValues_[k]);
74 return coarseValues_[k++][0];
76 fineLocalInterpolation_.interpolate(trackingCoarseFunction, coefficients_);
79 const auto& bindToCoarseBasisFunction(
std::size_t coarseIndex)
85 auto baseFctj = [&](
const auto& x) {
86 return coarseValues_[k++][coarseIndex];
90 fineLocalInterpolation_.interpolate(baseFctj, coefficients_);
94 const auto& coefficients()
const
100 const CoarseLocalBasis& coarseLocalBasis_;
101 const FineLocalInterpolation& fineLocalInterpolation_;
102 const Geometry& geometry_;
123template<
class MatrixType,
class CoarseBasis,
class FineBasis>
125 const CoarseBasis& coarseBasis,
126 const FineBasis& fineBasis,
127 const double tolerance = 1e-12)
129 const auto& coarseGridView = coarseBasis.gridView();
130 const auto& fineGridView = fineBasis.gridView();
132 auto coarseLocalView = coarseBasis.localView();
133 auto fineLocalView = fineBasis.localView();
136 constexpr bool isAssemblerMatrixBackend =
requires(MatrixType& matrixBackend) {
137 MatrixType::LocalPattern(0,0);
138 matrixBackend.setZero();
141 constexpr bool isFufemMatrixBackend =
requires(MatrixType& matrixBackend) {
142 matrixBackend.matrix();
143 matrixBackend.assign(0);
149 auto&& matrixBackend = [&]() ->
decltype(
auto) {
150 if constexpr(isAssemblerMatrixBackend)
152 else if constexpr(isFufemMatrixBackend)
159 auto patternBuilder = matrixBackend.patternBuilder();
160 patternBuilder.resize(fineBasis, coarseBasis);
168 using GeometryInFather =
std::decay_t<
decltype(elements(fineGridView).begin()->geometryInFather())>;
170 const auto geometryInFathers = [&](
auto&& x) {
172 for (
const auto& g : geometryInFathersVector)
177 using MatrixBackend =
std::decay_t<
decltype(matrixBackend)>;
179 auto localPattern =
typename MatrixBackend::LocalPattern(fineLocalView.maxSize(), coarseLocalView.maxSize());
182 for (
const auto& fineElement : elements(fineGridView) )
184 fineLocalView.bind(fineElement);
188 auto coarseElement = fineElement;
190 geometryInFathersVector.clear();
191 while ( not coarseGridView.contains(coarseElement) and coarseElement.hasFather() )
194 geometryInFathersVector.push_back(coarseElement.geometryInFather());
196 coarseElement = coarseElement.father();
200 if ( not coarseGridView.contains(coarseElement) )
203 coarseLocalView.bind(coarseElement);
205 localPattern.resize(fineLocalView.size(), coarseLocalView.size());
206 localPattern.clear();
209 auto&& fineNode = Dune::TypeTree::child(fineLocalView.tree(), treePath);
211 auto localInterpolationOperator = Impl::LocalInterpolationOperator(coarseNode.finiteElement(), fineNode.finiteElement(), geometryInFathers);
212 const auto& coefficients = localInterpolationOperator.coefficients();
214 for (auto j : Dune::range(coarseNode.size()))
216 localInterpolationOperator.bindToCoarseBasisFunction(j);
217 for (auto i : Dune::range(fineNode.size()))
219 if (std::abs(coefficients[i]) >= tolerance)
220 localPattern.add(fineNode.localIndex(i), coarseNode.localIndex(j));
224 patternBuilder.scatter(fineLocalView, coarseLocalView, localPattern);
228 patternBuilder.setupMatrix();
234 for (
const auto& fineElement :
elements(fineGridView) )
236 fineLocalView.bind(fineElement);
240 auto coarseElement = fineElement;
242 geometryInFathersVector.clear();
243 while ( not coarseGridView.contains(coarseElement) and coarseElement.hasFather() )
246 geometryInFathersVector.push_back(coarseElement.geometryInFather());
248 coarseElement = coarseElement.father();
251 coarseLocalView.bind(coarseElement);
257 auto&& fineNode = Dune::TypeTree::child(fineLocalView.tree(), treePath);
259 auto localInterpolationOperator = Impl::LocalInterpolationOperator(coarseNode.finiteElement(), fineNode.finiteElement(), geometryInFathers);
260 const auto& coefficients = localInterpolationOperator.coefficients();
262 for (auto j : Dune::range(coarseNode.size()))
264 localInterpolationOperator.bindToCoarseBasisFunction(j);
265 const auto& globalCoarseIndex = coarseLocalView.index( coarseNode.localIndex( j ) );
266 for (auto i : Dune::range(fineNode.size()))
268 if (std::abs(coefficients[i]) >= tolerance)
270 const auto& globalFineIndex = fineLocalView.index( fineNode.localIndex( i ) );
271 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:124