version 3.11-dev
Loading...
Searching...
No Matches
projector.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//
18#ifndef DUMUX_DISCRETIZATION_PROJECTOR_HH
19#define DUMUX_DISCRETIZATION_PROJECTOR_HH
20
21#include <algorithm>
22#include <optional>
23#include <string>
24#include <utility>
25#include <type_traits>
26
27#include <dune/common/timer.hh>
28#include <dune/common/fmatrix.hh>
29#include <dune/common/exceptions.hh>
30#include <dune/common/promotiontraits.hh>
31#include <dune/common/parametertree.hh>
32
33#include <dune/geometry/quadraturerules.hh>
34#include <dune/istl/matrixindexset.hh>
35#include <dune/istl/bcrsmatrix.hh>
36#include <dune/istl/bvector.hh>
37
38#include <dumux/io/format.hh>
45
46namespace Dumux {
47
54template<class ScalarType>
56{
57 using MatrixBlockType = Dune::FieldMatrix<ScalarType, 1, 1>;
58
59public:
61 using Scalar = ScalarType;
64
66 struct Params
67 {
68 std::size_t maxIterations{100};
70 int verbosity{0};
71 };
72
74 Projector() = delete;
75
81 Projector(Matrix&& massMatrix, Matrix&& projectionMatrix)
82 : massMat_(std::make_shared<Matrix>(std::move(massMatrix)))
83 , projMat_(std::make_shared<Matrix>(std::move(projectionMatrix)))
84 , numDofsTarget_(massMat_->N())
85 {
86 if (massMat_->N() != projMat_->N())
87 DUNE_THROW(Dune::InvalidStateException, "Matrix row size mismatch: " << massMat_->N() << " vs " << projMat_->N());
88
89 massMatrixSolver_.setMatrix(massMat_);
90 }
91
102 Projector(Matrix&& massMatrix,
103 Matrix&& projectionMatrix,
104 std::vector<std::size_t>&& indexMap,
105 std::size_t numDofsTarget)
106 : massMat_(std::make_shared<Matrix>(std::move(massMatrix)))
107 , projMat_(std::make_shared<Matrix>(std::move(projectionMatrix)))
108 , indexMapTarget_(std::move(indexMap))
109 , numDofsTarget_(numDofsTarget)
110 {
111 if (indexMapTarget_.size() != massMat_->N())
112 DUNE_THROW(Dune::InvalidStateException, "Target index map size mismatch: " << indexMapTarget_.size() << " vs " << massMat_->N());
113
114 if (massMat_->N() != projMat_->N())
115 DUNE_THROW(Dune::InvalidStateException, "Matrix row size mismatch: " << massMat_->N() << " vs " << projMat_->N());
116
117 if (!indexMapTarget_.empty())
118 if (*std::max_element(indexMapTarget_.begin(), indexMapTarget_.end()) > numDofsTarget_)
119 DUNE_THROW(Dune::InvalidStateException, "Index map exceeds provided number of dofs in target domain!");
120
121 massMatrixSolver_.setMatrix(massMat_);
122 }
123
130 template< class BlockType, std::enable_if_t<std::is_convertible<BlockType, ScalarType>::value, int> = 0 >
131 Dune::BlockVector<BlockType> project(const Dune::BlockVector<BlockType>& u, const Params& params = Params{}) const
132 {
133 // be picky about size of u
134 if ( u.size() != projMat_->M())
135 DUNE_THROW(Dune::InvalidStateException, "Vector size mismatch");
136
137 Dune::BlockVector<BlockType> up(massMat_->N());
138
139 auto rhs = up;
140 projMat_->mv(u, rhs);
141
142 Dune::ParameterTree solverParams;
143 solverParams["maxit"] = std::to_string(params.maxIterations);
144 solverParams["reduction"] = Fmt::format("{}", params.residualReduction);
145 solverParams["verbose"] = std::to_string(params.verbosity);
146 auto solver = massMatrixSolver_; // copy the solver to modify the parameters
147 solver.setParams(solverParams);
148 solver.solve(up, rhs);
149
150 // if target space occupies a larger region, fill missing entries with zero
151 if (!indexMapTarget_.empty())
152 {
153 Dune::BlockVector<BlockType> result(numDofsTarget_);
154
155 result = 0.0;
156 for (std::size_t i = 0; i < indexMapTarget_.size(); ++i)
157 result[indexMapTarget_[i]] = up[i];
158
159 return result;
160 }
161
162 return up;
163 }
164
171 template< class BlockType, std::enable_if_t<!std::is_convertible<BlockType, ScalarType>::value, int> = 0 >
172 Dune::BlockVector<BlockType> project(const Dune::BlockVector<BlockType>& u, const Params& params = Params{}) const
173 {
174 Dune::BlockVector<BlockType> result(numDofsTarget_);
175
176 for (int pvIdx = 0; pvIdx < BlockType::size(); ++pvIdx)
177 {
178 Dune::BlockVector<Dune::FieldVector<Scalar, 1>> tmp(u.size());
179 std::transform(u.begin(), u.end(), tmp.begin(), [pvIdx] (const auto& v) { return v[pvIdx]; });
180
181 const auto p = project(tmp, params);
182 for (std::size_t i = 0; i < p.size(); ++i)
183 result[i][pvIdx] = p[i];
184 }
185
186 return result;
187 }
188
192 static Params defaultParams()
193 { return {}; }
194
195private:
196 std::shared_ptr<Matrix> massMat_;
197 std::shared_ptr<Matrix> projMat_;
198
201 > massMatrixSolver_;
202
203 std::vector<std::size_t> indexMapTarget_;
204 std::size_t numDofsTarget_;
205};
206
210template<class FEBasisDomain, class FEBasisTarget>
212{
213 using FiniteElementDomain = typename FEBasisDomain::LocalView::Tree::FiniteElement;
214 using FiniteElementTarget = typename FEBasisTarget::LocalView::Tree::FiniteElement;
215 using ScalarDomain = typename FiniteElementDomain::Traits::LocalBasisType::Traits::RangeFieldType;
216 using ScalarTarget = typename FiniteElementTarget::Traits::LocalBasisType::Traits::RangeFieldType;
217 using Scalar = typename Dune::PromotionTraits<ScalarDomain, ScalarTarget>::PromotedType;
218public:
220};
221
222
223// Projector construction details
224namespace Detail {
225
233template<class Matrix>
234void setupReducedMatrices(const Matrix& massMatrix, const Matrix& projMatrix, const std::vector<bool>& dofIsVoid,
235 Matrix& reducedM, Matrix& reducedP, std::vector<std::size_t>& expansionMap)
236{
237 const std::size_t numNonVoidDofs = std::count_if(dofIsVoid.begin(), dofIsVoid.end(), [] (bool v) { return !v; });
238
239 // reduce matrices to only dofs that take part and create index map
240 std::vector<std::size_t> reductionMap(massMatrix.N());
241 expansionMap.resize(numNonVoidDofs);
242
243 std::size_t idxInReducedSpace = 0;
244 for (std::size_t dofIdx = 0; dofIdx < dofIsVoid.size(); ++dofIdx)
245 if (!dofIsVoid[dofIdx])
246 {
247 reductionMap[dofIdx] = idxInReducedSpace;
248 expansionMap[idxInReducedSpace] = dofIdx;
249 idxInReducedSpace++;
250 }
251
252 // create reduced M/P matrix
253 Dune::MatrixIndexSet patternMReduced, patternPReduced;
254 patternMReduced.resize(numNonVoidDofs, numNonVoidDofs);
255 patternPReduced.resize(numNonVoidDofs, projMatrix.M());
256 for (auto rowIt = massMatrix.begin(); rowIt != massMatrix.end(); ++rowIt)
257 if (!dofIsVoid[rowIt.index()])
258 {
259 const auto reducedRowIdx = reductionMap[rowIt.index()];
260 for (auto colIt = (*rowIt).begin(); colIt != (*rowIt).end(); ++colIt)
261 if (!dofIsVoid[colIt.index()])
262 patternMReduced.add(reducedRowIdx, reductionMap[colIt.index()]);
263 }
264
265 for (auto rowIt = projMatrix.begin(); rowIt != projMatrix.end(); ++rowIt)
266 if (!dofIsVoid[rowIt.index()])
267 {
268 const auto reducedRowIdx = reductionMap[rowIt.index()];
269 for (auto colIt = (*rowIt).begin(); colIt != (*rowIt).end(); ++colIt)
270 patternPReduced.add(reducedRowIdx, colIt.index());
271 }
272
273 patternMReduced.exportIdx(reducedM);
274 patternPReduced.exportIdx(reducedP);
275
276 // fill matrix entries
277 for (auto rowIt = massMatrix.begin(); rowIt != massMatrix.end(); ++rowIt)
278 if (!dofIsVoid[rowIt.index()])
279 {
280 const auto reducedRowIdx = reductionMap[rowIt.index()];
281 for (auto colIt = (*rowIt).begin(); colIt != (*rowIt).end(); ++colIt)
282 if (!dofIsVoid[colIt.index()])
283 reducedM[reducedRowIdx][reductionMap[colIt.index()]] = *colIt;
284 }
285
286 for (auto rowIt = projMatrix.begin(); rowIt != projMatrix.end(); ++rowIt)
287 if (!dofIsVoid[rowIt.index()])
288 {
289 const auto reducedRowIdx = reductionMap[rowIt.index()];
290 for (auto colIt = (*rowIt).begin(); colIt != (*rowIt).end(); ++colIt)
291 reducedP[reducedRowIdx][colIt.index()] = *colIt;
292 }
293}
294
316template<bool doBidirectional, class FEBasisDomain, class FEBasisTarget, class GlueType>
317auto createProjectionMatrices(const FEBasisDomain& feBasisDomain,
318 const FEBasisTarget& feBasisTarget,
319 const GlueType& glue,
320 bool treatDiagonalZeroes = true,
321 std::optional<int> quadratureOrder = {})
322{
323 // we assume that target dim <= domain dimension
324 static constexpr int domainDim = FEBasisDomain::GridView::dimension;
325 static constexpr int targetDim = FEBasisTarget::GridView::dimension;
326 static_assert(targetDim <= domainDim, "This expects target dim < domain dim, please swap arguments");
327
328 using ForwardProjector = typename ProjectorTraits<FEBasisDomain, FEBasisTarget>::Projector;
329 using BackwardProjector = typename ProjectorTraits<FEBasisTarget, FEBasisDomain>::Projector;
330
331 using ForwardProjectionMatrix = typename ForwardProjector::Matrix;
332 using BackwardProjectionMatrix = typename BackwardProjector::Matrix;
333
334 auto domainLocalView = feBasisDomain.localView();
335 auto targetLocalView = feBasisTarget.localView();
336
337 // determine mass matrix patterns (standard FE scheme pattern)
338 Dune::MatrixIndexSet backwardPatternM, forwardPatternM;
339 forwardPatternM = getFEJacobianPattern(feBasisTarget);
340 if (doBidirectional) backwardPatternM = getFEJacobianPattern(feBasisDomain);
341
342 // determine projection matrix patterns
343 Dune::MatrixIndexSet backwardPatternP, forwardPatternP;
344 forwardPatternP.resize(feBasisTarget.size(), feBasisDomain.size());
345 if (doBidirectional) backwardPatternP.resize(feBasisDomain.size(), feBasisTarget.size());
346
347 for (const auto& is : intersections(glue))
348 {
349 // since target dim <= domain dim there is maximum one!
350 targetLocalView.bind( is.targetEntity(0) );
351 const auto& targetLocalBasis = targetLocalView.tree().finiteElement().localBasis();
352
353 for (unsigned int nIdx = 0; nIdx < is.numDomainNeighbors(); ++nIdx)
354 {
355 domainLocalView.bind( is.domainEntity(nIdx) );
356 const auto& domainLocalBasis = domainLocalView.tree().finiteElement().localBasis();
357
358 for (unsigned int i = 0; i < domainLocalBasis.size(); ++i)
359 for (unsigned int j = 0; j < targetLocalBasis.size(); ++j)
360 {
361 forwardPatternP.add(targetLocalView.index(j), domainLocalView.index(i));
362 if (doBidirectional) backwardPatternP.add(domainLocalView.index(i), targetLocalView.index(j));
363 }
364 }
365 }
366
367 // assemble matrices
368 ForwardProjectionMatrix forwardM, forwardP;
369 forwardPatternM.exportIdx(forwardM); forwardM = 0.0;
370 forwardPatternP.exportIdx(forwardP); forwardP = 0.0;
371
372 BackwardProjectionMatrix backwardM, backwardP;
373 if (doBidirectional)
374 {
375 backwardPatternM.exportIdx(backwardM); backwardM = 0.0;
376 backwardPatternP.exportIdx(backwardP); backwardP = 0.0;
377 }
378
379 const auto totalDegree = [] (const auto& localView)
380 {
381 const auto& fe = localView.tree().finiteElement();
382 const auto order = fe.localBasis().order();
383 return fe.type().isCube() ? fe.type().dim()*order : order;
384 };
385
386 // one rule serves the mass matrices and the projection matrix of an intersection, so
387 // that the row sums of both agree exactly whatever the geometry; it has to integrate
388 // the square of a shape function of either space, the highest degree among the integrands
389 using std::max;
390 const auto integrationOrder = [&] (const auto& is, unsigned int targetDegree)
391 {
392 if (quadratureOrder)
393 return *quadratureOrder;
394 auto degree = targetDegree;
395 for (unsigned int nIdx = 0; nIdx < is.numDomainNeighbors(); ++nIdx)
396 {
397 domainLocalView.bind( is.domainEntity(nIdx) );
398 degree = max(degree, totalDegree(domainLocalView));
399 }
400 return static_cast<int>(max(2*degree, 1u));
401 };
402
403 for (const auto& is : intersections(glue))
404 {
405 const auto& targetElement = is.targetEntity(0);
406 const auto& targetElementGeometry = targetElement.geometry();
407
408 targetLocalView.bind( targetElement );
409 const auto& targetLocalBasis = targetLocalView.tree().finiteElement().localBasis();
410
411 // perform integration over intersection geometry
412 using IsGeometry = typename std::decay_t<decltype(is.geometry())>;
413 using ctype = typename IsGeometry::ctype;
414
415 const auto& isGeometry = is.geometry();
416 const int intOrder = integrationOrder(is, totalDegree(targetLocalView));
417 const auto& quad = Dune::QuadratureRules<ctype, IsGeometry::mydimension>::rule(isGeometry.type(), intOrder);
418 for (auto&& qp : quad)
419 {
420 const auto weight = qp.weight();
421 const auto ie = isGeometry.integrationElement(qp.position());
422 const auto globalPos = isGeometry.global(qp.position());
423
424 std::vector< Dune::FieldVector<ctype, 1> > targetShapeVals;
425 targetLocalBasis.evaluateFunction(targetElementGeometry.local(globalPos), targetShapeVals);
426
427 // mass matrix entries target domain
428 for (unsigned int i = 0; i < targetLocalBasis.size(); ++i)
429 {
430 const auto dofIdxI = targetLocalView.index(i);
431 forwardM[dofIdxI][dofIdxI][0][0] += ie*weight*targetShapeVals[i]*targetShapeVals[i];
432
433 for (unsigned int j = i+1; j < targetLocalBasis.size(); ++j)
434 {
435 const auto dofIdxJ = targetLocalView.index(j);
436 const auto value = ie*weight*targetShapeVals[i]*targetShapeVals[j];
437 forwardM[dofIdxI][dofIdxJ][0][0] += value;
438 forwardM[dofIdxJ][dofIdxI][0][0] += value;
439 }
440 }
441
442 // If targetDim < domainDim, there can be several "neighbors" if
443 // targetElement is aligned with a facet of domainElement. In
444 // this case make sure the basis functions are not added
445 // multiple times! (division by numNeighbors)
446 const auto numNeighbors = is.numDomainNeighbors();
447 for (unsigned int nIdx = 0; nIdx < numNeighbors; ++nIdx)
448 {
449 const auto& domainElement = is.domainEntity(nIdx);
450 domainLocalView.bind( domainElement );
451 const auto& domainLocalBasis = domainLocalView.tree().finiteElement().localBasis();
452
453 std::vector< Dune::FieldVector<ctype, 1> > domainShapeVals;
454 domainLocalBasis.evaluateFunction(domainElement.geometry().local(globalPos), domainShapeVals);
455
456 // add entries in matrices
457 for (unsigned int i = 0; i < domainLocalBasis.size(); ++i)
458 {
459 const auto dofIdxDomain = domainLocalView.index(i);
460 const auto domainShapeVal = domainShapeVals[i];
461 if (doBidirectional)
462 {
463 backwardM[dofIdxDomain][dofIdxDomain][0][0] += ie*weight*domainShapeVal*domainShapeVal;
464
465 for (unsigned int j = i+1; j < domainLocalBasis.size(); ++j)
466 {
467 const auto dofIdxDomainJ = domainLocalView.index(j);
468 const auto value = ie*weight*domainShapeVal*domainShapeVals[j];
469 backwardM[dofIdxDomain][dofIdxDomainJ][0][0] += value;
470 backwardM[dofIdxDomainJ][dofIdxDomain][0][0] += value;
471 }
472 }
473
474 for (unsigned int j = 0; j < targetLocalBasis.size(); ++j)
475 {
476 const auto dofIdxTarget = targetLocalView.index(j);
477 const auto entry = ie*weight*domainShapeVal*targetShapeVals[j];
478
479 forwardP[dofIdxTarget][dofIdxDomain][0][0] += entry/numNeighbors;
480 if (doBidirectional)
481 backwardP[dofIdxDomain][dofIdxTarget][0][0] += entry;
482 }
483 }
484 }
485 }
486 }
487
488 // maybe treat zeroes on the diagonal
489 if (treatDiagonalZeroes)
490 {
491 for (std::size_t dofIdxTarget = 0; dofIdxTarget < forwardM.N(); ++dofIdxTarget)
492 if (forwardM[dofIdxTarget][dofIdxTarget][0][0] == 0.0)
493 forwardM[dofIdxTarget][dofIdxTarget][0][0] = 1.0;
494
495 if (doBidirectional)
496 {
497 for (std::size_t dofIdxDomain = 0; dofIdxDomain < backwardM.N(); ++dofIdxDomain)
498 if (backwardM[dofIdxDomain][dofIdxDomain][0][0] == 0.0)
499 backwardM[dofIdxDomain][dofIdxDomain][0][0] = 1.0;
500 }
501 }
502
503 return std::make_pair( std::make_pair(std::move(forwardM), std::move(forwardP)),
504 std::make_pair(std::move(backwardM), std::move(backwardP)) );
505}
506
512template<bool doBidirectional, class FEBasisDomain, class FEBasisTarget, class GlueType>
513auto makeProjectorPair(const FEBasisDomain& feBasisDomain,
514 const FEBasisTarget& feBasisTarget,
515 const GlueType& glue,
516 std::optional<int> quadratureOrder = {})
517{
518 using ForwardProjector = typename ProjectorTraits<FEBasisDomain, FEBasisTarget>::Projector;
519 using BackwardProjector = typename ProjectorTraits<FEBasisTarget, FEBasisDomain>::Projector;
520
521 using ForwardProjectionMatrix = typename ForwardProjector::Matrix;
522 using BackwardProjectionMatrix = typename BackwardProjector::Matrix;
523
524 auto projectionMatrices = createProjectionMatrices<doBidirectional>(feBasisDomain, feBasisTarget, glue, false, quadratureOrder);
525 auto& forwardMatrices = projectionMatrices.first;
526 auto& backwardMatrices = projectionMatrices.second;
527
528 auto& forwardM = forwardMatrices.first;
529 auto& forwardP = forwardMatrices.second;
530
531 auto& backwardM = backwardMatrices.first;
532 auto& backwardP = backwardMatrices.second;
533
534 // determine the dofs that do not take part in intersections
535 std::vector<bool> isVoidTarget(forwardM.N(), false);
536 for (std::size_t dofIdxTarget = 0; dofIdxTarget < forwardM.N(); ++dofIdxTarget)
537 if (forwardM[dofIdxTarget][dofIdxTarget][0][0] == 0.0)
538 isVoidTarget[dofIdxTarget] = true;
539
540 std::vector<bool> isVoidDomain;
541 if (doBidirectional)
542 {
543 isVoidDomain.resize(backwardM.N(), false);
544 for (std::size_t dofIdxDomain = 0; dofIdxDomain < backwardM.N(); ++dofIdxDomain)
545 if (backwardM[dofIdxDomain][dofIdxDomain][0][0] == 0.0)
546 isVoidDomain[dofIdxDomain] = true;
547 }
548
549 const bool hasVoidTarget = std::any_of(isVoidTarget.begin(), isVoidTarget.end(), [] (bool v) { return v; });
550 const bool hasVoidDomain = std::any_of(isVoidDomain.begin(), isVoidDomain.end(), [] (bool v) { return v; });
551 if (!hasVoidDomain && !hasVoidTarget)
552 {
553 return std::make_pair(ForwardProjector(std::move(forwardM), std::move(forwardP)),
554 BackwardProjector(std::move(backwardM), std::move(backwardP)));
555 }
556 else if (!hasVoidDomain && hasVoidTarget)
557 {
558 std::vector<std::size_t> expansionMapTarget;
559 ForwardProjectionMatrix forwardMReduced, forwardPReduced;
560 setupReducedMatrices(forwardM, forwardP, isVoidTarget,
561 forwardMReduced, forwardPReduced, expansionMapTarget);
562
563 return std::make_pair( ForwardProjector(std::move(forwardMReduced),
564 std::move(forwardPReduced),
565 std::move(expansionMapTarget),
566 forwardM.N()),
567 BackwardProjector(std::move(backwardM), std::move(backwardP)) );
568 }
569 else if (hasVoidDomain && !hasVoidTarget)
570 {
571 if (doBidirectional)
572 {
573 std::vector<std::size_t> expansionMapDomain;
574 BackwardProjectionMatrix backwardMReduced, backwardPReduced;
575 setupReducedMatrices(backwardM, backwardP, isVoidDomain,
576 backwardMReduced, backwardPReduced, expansionMapDomain);
577
578 return std::make_pair( ForwardProjector(std::move(forwardM), std::move(forwardP)),
579 BackwardProjector(std::move(backwardMReduced),
580 std::move(backwardPReduced),
581 std::move(expansionMapDomain),
582 backwardM.N()) );
583 }
584 else
585 return std::make_pair( ForwardProjector(std::move(forwardM), std::move(forwardP)),
586 BackwardProjector(std::move(backwardM), std::move(backwardP)) );
587 }
588 else
589 {
590 std::vector<std::size_t> expansionMapTarget;
591 ForwardProjectionMatrix forwardMReduced, forwardPReduced;
592 setupReducedMatrices(forwardM, forwardP, isVoidTarget,
593 forwardMReduced, forwardPReduced, expansionMapTarget);
594
595 if (doBidirectional)
596 {
597 std::vector<std::size_t> expansionMapDomain;
598 BackwardProjectionMatrix backwardMReduced, backwardPReduced;
599 setupReducedMatrices(backwardM, backwardP, isVoidDomain,
600 backwardMReduced, backwardPReduced, expansionMapDomain);
601
602 return std::make_pair( ForwardProjector(std::move(forwardMReduced),
603 std::move(forwardPReduced),
604 std::move(expansionMapTarget),
605 forwardM.N()),
606 BackwardProjector(std::move(backwardMReduced),
607 std::move(backwardPReduced),
608 std::move(expansionMapDomain),
609 backwardM.N()) );
610 }
611 else
612 return std::make_pair( ForwardProjector(std::move(forwardMReduced),
613 std::move(forwardPReduced),
614 std::move(expansionMapTarget),
615 forwardM.N()),
616 BackwardProjector(std::move(backwardM), std::move(backwardP)) );
617 }
618}
619
620} // end namespace Detail
621
622
637template< class FEBasisDomain, class FEBasisTarget, class GlueType >
638auto makeProjectorPair(const FEBasisDomain& feBasisDomain,
639 const FEBasisTarget& feBasisTarget,
640 GlueType glue,
641 std::optional<int> quadratureOrder = {})
642{
643 // we assume that target dim <= domain dimension
644 static constexpr int domainDim = FEBasisDomain::GridView::dimension;
645 static constexpr int targetDim = FEBasisTarget::GridView::dimension;
646 static_assert(targetDim <= domainDim, "makeProjectorPair() expects targetDim < domainDim, please swap arguments");
647
648 return Detail::makeProjectorPair<true>(feBasisDomain, feBasisTarget, glue, quadratureOrder);
649}
650
663template< class FEBasisDomain, class FEBasisTarget, class GlueType >
664auto makeProjector(const FEBasisDomain& feBasisDomain,
665 const FEBasisTarget& feBasisTarget,
666 GlueType glue,
667 std::optional<int> quadratureOrder = {})
668{
669 // we assume that target dim <= domain dimension
670 static constexpr int domainDim = FEBasisDomain::GridView::dimension;
671 static constexpr int targetDim = FEBasisTarget::GridView::dimension;
672 static_assert(targetDim <= domainDim, "makeProjectorPair() expects targetDim < domainDim, please swap arguments");
673
674 return Detail::makeProjectorPair<false>(feBasisDomain, feBasisTarget, glue, quadratureOrder).first;
675}
676
690template< class FEBasisDomain, class FEBasisTarget, class GlueType >
691auto makeProjectionMatricesPair(const FEBasisDomain& feBasisDomain,
692 const FEBasisTarget& feBasisTarget,
693 GlueType glue,
694 std::optional<int> quadratureOrder = {})
695{
696 // we assume that target dim <= domain dimension
697 static constexpr int domainDim = FEBasisDomain::GridView::dimension;
698 static constexpr int targetDim = FEBasisTarget::GridView::dimension;
699 static_assert(targetDim <= domainDim, "makeProjectionMatrixPair() expects targetDim < domainDim, please swap arguments");
700
701 return Detail::createProjectionMatrices<true>(feBasisDomain, feBasisTarget, glue, true, quadratureOrder);
702}
703
714template< class FEBasisDomain, class FEBasisTarget, class GlueType >
715auto makeProjectionMatrices(const FEBasisDomain& feBasisDomain,
716 const FEBasisTarget& feBasisTarget,
717 GlueType glue,
718 std::optional<int> quadratureOrder = {})
719{
720 // we assume that target dim <= domain dimension
721 static constexpr int domainDim = FEBasisDomain::GridView::dimension;
722 static constexpr int targetDim = FEBasisTarget::GridView::dimension;
723 static_assert(targetDim <= domainDim, "makeProjectionMatrixPair() expects targetDim < domainDim, please swap arguments");
724
725 return Detail::createProjectionMatrices<false>(feBasisDomain, feBasisTarget, glue, true, quadratureOrder).first;
726}
727
728} // end namespace Dumux
729
730#endif
static Params defaultParams()
Returns the default parameters.
Definition projector.hh:192
Projector(Matrix &&massMatrix, Matrix &&projectionMatrix, std::vector< std::size_t > &&indexMap, std::size_t numDofsTarget)
Constructor for projection into a target space that occupies a larger geometric region than the domai...
Definition projector.hh:102
ScalarType Scalar
Export the scalar type.
Definition projector.hh:61
Projector(Matrix &&massMatrix, Matrix &&projectionMatrix)
Constructor. Receives the mass and projection matrix that define the linear system describing the L2-...
Definition projector.hh:81
Dune::BCRSMatrix< MatrixBlockType > Matrix
Export the type of the projection matrices.
Definition projector.hh:63
Projector()=delete
delete default constructor
Dune::BlockVector< BlockType > project(const Dune::BlockVector< BlockType > &u, const Params &params=Params{}) const
Project a solution u into up.
Definition projector.hh:131
Traits class stating the type of projector between to bases.
Definition projector.hh:212
Dumux::Projector< Scalar > Projector
Definition projector.hh:219
Formatting based on the fmt-library which implements std::format of C++20.
Provides helper aliases and functionality to obtain the types and instances of Dune::Functions functi...
Dune::MatrixIndexSet getFEJacobianPattern(const FEBasis &feBasis)
Helper function to generate Jacobian pattern for finite element scheme.
Definition jacobianpattern.hh:106
auto makeProjector(const FEBasisDomain &feBasisDomain, const FEBasisTarget &feBasisTarget, GlueType glue, std::optional< int > quadratureOrder={})
Creates a forward projector from the space feBasisDomain to the space with basis feBasisTarget.
Definition projector.hh:664
auto makeProjectorPair(const FEBasisDomain &feBasisDomain, const FEBasisTarget &feBasisTarget, GlueType glue, std::optional< int > quadratureOrder={})
Creates a pair of projectors between the space with basis feBasisDomain to the space with basis feBas...
Definition projector.hh:638
GridCache::LocalView localView(const GridCache &gridCache)
Free function to get the local view of a grid cache object.
Definition localview.hh:26
Detail::IstlIterativeLinearSolver< LSTraits, LATraits, Dune::CGSolver< typename LATraits::Vector >, Detail::IstlSolvers::IstlDefaultBlockLevelPreconditionerFactory< Dune::SeqSSOR > > SSORCGIstlSolver
An SSOR-preconditioned CG solver using dune-istl.
Definition istlsolvers.hh:744
Linear solvers from dune-istl.
Helper function to generate Jacobian pattern for different discretization methods.
Define traits for linear algebra backends.
Define traits for linear solvers.
Definition cvfelocalresidual.hh:25
auto makeProjectorPair(const FEBasisDomain &feBasisDomain, const FEBasisTarget &feBasisTarget, const GlueType &glue, std::optional< int > quadratureOrder={})
Creates a projector class between two function space bases.
Definition projector.hh:513
auto createProjectionMatrices(const FEBasisDomain &feBasisDomain, const FEBasisTarget &feBasisTarget, const GlueType &glue, bool treatDiagonalZeroes=true, std::optional< int > quadratureOrder={})
Creates the matrices underlying l2-projections.
Definition projector.hh:317
void setupReducedMatrices(const Matrix &massMatrix, const Matrix &projMatrix, const std::vector< bool > &dofIsVoid, Matrix &reducedM, Matrix &reducedP, std::vector< std::size_t > &expansionMap)
Reduces a mass matrix and projection matrix such that they are composed of only those dofs that actua...
Definition projector.hh:234
Definition adapt.hh:17
auto makeProjectionMatrices(const FEBasisDomain &feBasisDomain, const FEBasisTarget &feBasisTarget, GlueType glue, std::optional< int > quadratureOrder={})
Creates the matrices underlying l2-projections.
Definition projector.hh:715
auto makeProjectionMatricesPair(const FEBasisDomain &feBasisDomain, const FEBasisTarget &feBasisTarget, GlueType glue, std::optional< int > quadratureOrder={})
Creates the matrices underlying l2-projections.
Definition projector.hh:691
const Scalar PengRobinsonMixture< Scalar, StaticParameters >::u
Definition pengrobinsonmixture.hh:138
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.
Definition linearalgebratraits.hh:51
Parameters that can be passed to project().
Definition projector.hh:67
Scalar residualReduction
Definition projector.hh:69
int verbosity
Definition projector.hh:70
std::size_t maxIterations
Definition projector.hh:68
Definition linearsolvertraits.hh:55