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)
160 return Dune::Assembler::ISTLMatrixBackend(matrix.matrix());
162 return Dune::Assembler::ISTLMatrixBackend(matrix);
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];