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 <string>
23#include <utility>
24#include <type_traits>
25
26#include <dune/common/timer.hh>
27#include <dune/common/fmatrix.hh>
28#include <dune/common/exceptions.hh>
29#include <dune/common/promotiontraits.hh>
30#include <dune/common/parametertree.hh>
31
32#include <dune/geometry/quadraturerules.hh>
33#include <dune/istl/matrixindexset.hh>
34#include <dune/istl/bcrsmatrix.hh>
35#include <dune/istl/bvector.hh>
36
37#include <dumux/io/format.hh>
44
45namespace Dumux {
46
53template<class ScalarType>
55{
56 using MatrixBlockType = Dune::FieldMatrix<ScalarType, 1, 1>;
57
58public:
60 using Scalar = ScalarType;
63
65 struct Params
66 {
67 std::size_t maxIterations{100};
69 int verbosity{0};
70 };
71
73 Projector() = delete;
74
80 Projector(Matrix&& massMatrix, Matrix&& projectionMatrix)
81 : massMat_(std::make_shared<Matrix>(std::move(massMatrix)))
82 , projMat_(std::make_shared<Matrix>(std::move(projectionMatrix)))
83 , numDofsTarget_(massMat_->N())
84 {
85 if (massMat_->N() != projMat_->N())
86 DUNE_THROW(Dune::InvalidStateException, "Matrix row size mismatch: " << massMat_->N() << " vs " << projMat_->N());
87
88 massMatrixSolver_.setMatrix(massMat_);
89 }
90
101 Projector(Matrix&& massMatrix,
102 Matrix&& projectionMatrix,
103 std::vector<std::size_t>&& indexMap,
104 std::size_t numDofsTarget)
105 : massMat_(std::make_shared<Matrix>(std::move(massMatrix)))
106 , projMat_(std::make_shared<Matrix>(std::move(projectionMatrix)))
107 , indexMapTarget_(std::move(indexMap))
108 , numDofsTarget_(numDofsTarget)
109 {
110 if (indexMapTarget_.size() != massMat_->N())
111 DUNE_THROW(Dune::InvalidStateException, "Target index map size mismatch: " << indexMapTarget_.size() << " vs " << massMat_->N());
112
113 if (massMat_->N() != projMat_->N())
114 DUNE_THROW(Dune::InvalidStateException, "Matrix row size mismatch: " << massMat_->N() << " vs " << projMat_->N());
115
116 if (!indexMapTarget_.empty())
117 if (*std::max_element(indexMapTarget_.begin(), indexMapTarget_.end()) > numDofsTarget_)
118 DUNE_THROW(Dune::InvalidStateException, "Index map exceeds provided number of dofs in target domain!");
119
120 massMatrixSolver_.setMatrix(massMat_);
121 }
122
129 template< class BlockType, std::enable_if_t<std::is_convertible<BlockType, ScalarType>::value, int> = 0 >
130 Dune::BlockVector<BlockType> project(const Dune::BlockVector<BlockType>& u, const Params& params = Params{}) const
131 {
132 // be picky about size of u
133 if ( u.size() != projMat_->M())
134 DUNE_THROW(Dune::InvalidStateException, "Vector size mismatch");
135
136 Dune::BlockVector<BlockType> up(massMat_->N());
137
138 auto rhs = up;
139 projMat_->mv(u, rhs);
140
141 Dune::ParameterTree solverParams;
142 solverParams["maxit"] = std::to_string(params.maxIterations);
143 solverParams["reduction"] = Fmt::format("{}", params.residualReduction);
144 solverParams["verbose"] = std::to_string(params.verbosity);
145 auto solver = massMatrixSolver_; // copy the solver to modify the parameters
146 solver.setParams(solverParams);
147 solver.solve(up, rhs);
148
149 // if target space occupies a larger region, fill missing entries with zero
150 if (!indexMapTarget_.empty())
151 {
152 Dune::BlockVector<BlockType> result(numDofsTarget_);
153
154 result = 0.0;
155 for (std::size_t i = 0; i < indexMapTarget_.size(); ++i)
156 result[indexMapTarget_[i]] = up[i];
157
158 return result;
159 }
160
161 return up;
162 }
163
170 template< class BlockType, std::enable_if_t<!std::is_convertible<BlockType, ScalarType>::value, int> = 0 >
171 Dune::BlockVector<BlockType> project(const Dune::BlockVector<BlockType>& u, const Params& params = Params{}) const
172 {
173 Dune::BlockVector<BlockType> result(numDofsTarget_);
174
175 for (int pvIdx = 0; pvIdx < BlockType::size(); ++pvIdx)
176 {
177 Dune::BlockVector<Dune::FieldVector<Scalar, 1>> tmp(u.size());
178 std::transform(u.begin(), u.end(), tmp.begin(), [pvIdx] (const auto& v) { return v[pvIdx]; });
179
180 const auto p = project(tmp, params);
181 for (std::size_t i = 0; i < p.size(); ++i)
182 result[i][pvIdx] = p[i];
183 }
184
185 return result;
186 }
187
191 static Params defaultParams()
192 { return {}; }
193
194private:
195 std::shared_ptr<Matrix> massMat_;
196 std::shared_ptr<Matrix> projMat_;
197
200 > massMatrixSolver_;
201
202 std::vector<std::size_t> indexMapTarget_;
203 std::size_t numDofsTarget_;
204};
205
209template<class FEBasisDomain, class FEBasisTarget>
211{
212 using FiniteElementDomain = typename FEBasisDomain::LocalView::Tree::FiniteElement;
213 using FiniteElementTarget = typename FEBasisTarget::LocalView::Tree::FiniteElement;
214 using ScalarDomain = typename FiniteElementDomain::Traits::LocalBasisType::Traits::RangeFieldType;
215 using ScalarTarget = typename FiniteElementTarget::Traits::LocalBasisType::Traits::RangeFieldType;
216 using Scalar = typename Dune::PromotionTraits<ScalarDomain, ScalarTarget>::PromotedType;
217public:
219};
220
221
222// Projector construction details
223namespace Detail {
224
232template<class Matrix>
233void setupReducedMatrices(const Matrix& massMatrix, const Matrix& projMatrix, const std::vector<bool>& dofIsVoid,
234 Matrix& reducedM, Matrix& reducedP, std::vector<std::size_t>& expansionMap)
235{
236 const std::size_t numNonVoidDofs = std::count_if(dofIsVoid.begin(), dofIsVoid.end(), [] (bool v) { return !v; });
237
238 // reduce matrices to only dofs that take part and create index map
239 std::vector<std::size_t> reductionMap(massMatrix.N());
240 expansionMap.resize(numNonVoidDofs);
241
242 std::size_t idxInReducedSpace = 0;
243 for (std::size_t dofIdx = 0; dofIdx < dofIsVoid.size(); ++dofIdx)
244 if (!dofIsVoid[dofIdx])
245 {
246 reductionMap[dofIdx] = idxInReducedSpace;
247 expansionMap[idxInReducedSpace] = dofIdx;
248 idxInReducedSpace++;
249 }
250
251 // create reduced M/P matrix
252 Dune::MatrixIndexSet patternMReduced, patternPReduced;
253 patternMReduced.resize(numNonVoidDofs, numNonVoidDofs);
254 patternPReduced.resize(numNonVoidDofs, projMatrix.M());
255 for (auto rowIt = massMatrix.begin(); rowIt != massMatrix.end(); ++rowIt)
256 if (!dofIsVoid[rowIt.index()])
257 {
258 const auto reducedRowIdx = reductionMap[rowIt.index()];
259 for (auto colIt = (*rowIt).begin(); colIt != (*rowIt).end(); ++colIt)
260 if (!dofIsVoid[colIt.index()])
261 patternMReduced.add(reducedRowIdx, reductionMap[colIt.index()]);
262 }
263
264 for (auto rowIt = projMatrix.begin(); rowIt != projMatrix.end(); ++rowIt)
265 if (!dofIsVoid[rowIt.index()])
266 {
267 const auto reducedRowIdx = reductionMap[rowIt.index()];
268 for (auto colIt = (*rowIt).begin(); colIt != (*rowIt).end(); ++colIt)
269 patternPReduced.add(reducedRowIdx, colIt.index());
270 }
271
272 patternMReduced.exportIdx(reducedM);
273 patternPReduced.exportIdx(reducedP);
274
275 // fill matrix entries
276 for (auto rowIt = massMatrix.begin(); rowIt != massMatrix.end(); ++rowIt)
277 if (!dofIsVoid[rowIt.index()])
278 {
279 const auto reducedRowIdx = reductionMap[rowIt.index()];
280 for (auto colIt = (*rowIt).begin(); colIt != (*rowIt).end(); ++colIt)
281 if (!dofIsVoid[colIt.index()])
282 reducedM[reducedRowIdx][reductionMap[colIt.index()]] = *colIt;
283 }
284
285 for (auto rowIt = projMatrix.begin(); rowIt != projMatrix.end(); ++rowIt)
286 if (!dofIsVoid[rowIt.index()])
287 {
288 const auto reducedRowIdx = reductionMap[rowIt.index()];
289 for (auto colIt = (*rowIt).begin(); colIt != (*rowIt).end(); ++colIt)
290 reducedP[reducedRowIdx][colIt.index()] = *colIt;
291 }
292}
293
310template<bool doBidirectional, class FEBasisDomain, class FEBasisTarget, class GlueType>
311auto createProjectionMatrices(const FEBasisDomain& feBasisDomain,
312 const FEBasisTarget& feBasisTarget,
313 const GlueType& glue,
314 bool treatDiagonalZeroes = true)
315{
316 // we assume that target dim <= domain dimension
317 static constexpr int domainDim = FEBasisDomain::GridView::dimension;
318 static constexpr int targetDim = FEBasisTarget::GridView::dimension;
319 static_assert(targetDim <= domainDim, "This expects target dim < domain dim, please swap arguments");
320
321 using ForwardProjector = typename ProjectorTraits<FEBasisDomain, FEBasisTarget>::Projector;
322 using BackwardProjector = typename ProjectorTraits<FEBasisTarget, FEBasisDomain>::Projector;
323
324 using ForwardProjectionMatrix = typename ForwardProjector::Matrix;
325 using BackwardProjectionMatrix = typename BackwardProjector::Matrix;
326
327 auto domainLocalView = feBasisDomain.localView();
328 auto targetLocalView = feBasisTarget.localView();
329
330 // determine mass matrix patterns (standard FE scheme pattern)
331 Dune::MatrixIndexSet backwardPatternM, forwardPatternM;
332 forwardPatternM = getFEJacobianPattern(feBasisTarget);
333 if (doBidirectional) backwardPatternM = getFEJacobianPattern(feBasisDomain);
334
335 // determine projection matrix patterns
336 Dune::MatrixIndexSet backwardPatternP, forwardPatternP;
337 forwardPatternP.resize(feBasisTarget.size(), feBasisDomain.size());
338 if (doBidirectional) backwardPatternP.resize(feBasisDomain.size(), feBasisTarget.size());
339
340 using std::max;
341 unsigned int maxBasisOrder = 0;
342 for (const auto& is : intersections(glue))
343 {
344 // since target dim <= domain dim there is maximum one!
345 targetLocalView.bind( is.targetEntity(0) );
346 const auto& targetLocalBasis = targetLocalView.tree().finiteElement().localBasis();
347
348 for (unsigned int nIdx = 0; nIdx < is.numDomainNeighbors(); ++nIdx)
349 {
350 domainLocalView.bind( is.domainEntity(nIdx) );
351 const auto& domainLocalBasis = domainLocalView.tree().finiteElement().localBasis();
352
353 // keep track of maximum basis order (used in integration)
354 maxBasisOrder = max(maxBasisOrder, max(domainLocalBasis.order(), targetLocalBasis.order()));
355
356 for (unsigned int i = 0; i < domainLocalBasis.size(); ++i)
357 for (unsigned int j = 0; j < targetLocalBasis.size(); ++j)
358 {
359 forwardPatternP.add(targetLocalView.index(j), domainLocalView.index(i));
360 if (doBidirectional) backwardPatternP.add(domainLocalView.index(i), targetLocalView.index(j));
361 }
362 }
363 }
364
365 // assemble matrices
366 ForwardProjectionMatrix forwardM, forwardP;
367 forwardPatternM.exportIdx(forwardM); forwardM = 0.0;
368 forwardPatternP.exportIdx(forwardP); forwardP = 0.0;
369
370 BackwardProjectionMatrix backwardM, backwardP;
371 if (doBidirectional)
372 {
373 backwardPatternM.exportIdx(backwardM); backwardM = 0.0;
374 backwardPatternP.exportIdx(backwardP); backwardP = 0.0;
375 }
376
377 for (const auto& is : intersections(glue))
378 {
379 const auto& targetElement = is.targetEntity(0);
380 const auto& targetElementGeometry = targetElement.geometry();
381
382 targetLocalView.bind( targetElement );
383 const auto& targetLocalBasis = targetLocalView.tree().finiteElement().localBasis();
384
385 // perform integration over intersection geometry
386 using IsGeometry = typename std::decay_t<decltype(is.geometry())>;
387 using ctype = typename IsGeometry::ctype;
388
389 const auto& isGeometry = is.geometry();
390 const int intOrder = maxBasisOrder + 1;
391 const auto& quad = Dune::QuadratureRules<ctype, IsGeometry::mydimension>::rule(isGeometry.type(), intOrder);
392 for (auto&& qp : quad)
393 {
394 const auto weight = qp.weight();
395 const auto ie = isGeometry.integrationElement(qp.position());
396 const auto globalPos = isGeometry.global(qp.position());
397
398 std::vector< Dune::FieldVector<ctype, 1> > targetShapeVals;
399 targetLocalBasis.evaluateFunction(targetElementGeometry.local(globalPos), targetShapeVals);
400
401 // mass matrix entries target domain
402 for (unsigned int i = 0; i < targetLocalBasis.size(); ++i)
403 {
404 const auto dofIdxI = targetLocalView.index(i);
405 forwardM[dofIdxI][dofIdxI][0][0] += ie*weight*targetShapeVals[i]*targetShapeVals[i];
406
407 for (unsigned int j = i+1; j < targetLocalBasis.size(); ++j)
408 {
409 const auto dofIdxJ = targetLocalView.index(j);
410 const auto value = ie*weight*targetShapeVals[i]*targetShapeVals[j];
411 forwardM[dofIdxI][dofIdxJ][0][0] += value;
412 forwardM[dofIdxJ][dofIdxI][0][0] += value;
413 }
414 }
415
416 // If targetDim < domainDim, there can be several "neighbors" if
417 // targetElement is aligned with a facet of domainElement. In
418 // this case make sure the basis functions are not added
419 // multiple times! (division by numNeighbors)
420 const auto numNeighbors = is.numDomainNeighbors();
421 for (unsigned int nIdx = 0; nIdx < numNeighbors; ++nIdx)
422 {
423 const auto& domainElement = is.domainEntity(nIdx);
424 domainLocalView.bind( domainElement );
425 const auto& domainLocalBasis = domainLocalView.tree().finiteElement().localBasis();
426
427 std::vector< Dune::FieldVector<ctype, 1> > domainShapeVals;
428 domainLocalBasis.evaluateFunction(domainElement.geometry().local(globalPos), domainShapeVals);
429
430 // add entries in matrices
431 for (unsigned int i = 0; i < domainLocalBasis.size(); ++i)
432 {
433 const auto dofIdxDomain = domainLocalView.index(i);
434 const auto domainShapeVal = domainShapeVals[i];
435 if (doBidirectional)
436 {
437 backwardM[dofIdxDomain][dofIdxDomain][0][0] += ie*weight*domainShapeVal*domainShapeVal;
438
439 for (unsigned int j = i+1; j < domainLocalBasis.size(); ++j)
440 {
441 const auto dofIdxDomainJ = domainLocalView.index(j);
442 const auto value = ie*weight*domainShapeVal*domainShapeVals[j];
443 backwardM[dofIdxDomain][dofIdxDomainJ][0][0] += value;
444 backwardM[dofIdxDomainJ][dofIdxDomain][0][0] += value;
445 }
446 }
447
448 for (unsigned int j = 0; j < targetLocalBasis.size(); ++j)
449 {
450 const auto dofIdxTarget = targetLocalView.index(j);
451 const auto entry = ie*weight*domainShapeVal*targetShapeVals[j];
452
453 forwardP[dofIdxTarget][dofIdxDomain][0][0] += entry/numNeighbors;
454 if (doBidirectional)
455 backwardP[dofIdxDomain][dofIdxTarget][0][0] += entry;
456 }
457 }
458 }
459 }
460 }
461
462 // maybe treat zeroes on the diagonal
463 if (treatDiagonalZeroes)
464 {
465 for (std::size_t dofIdxTarget = 0; dofIdxTarget < forwardM.N(); ++dofIdxTarget)
466 if (forwardM[dofIdxTarget][dofIdxTarget][0][0] == 0.0)
467 forwardM[dofIdxTarget][dofIdxTarget][0][0] = 1.0;
468
469 if (doBidirectional)
470 {
471 for (std::size_t dofIdxDomain = 0; dofIdxDomain < backwardM.N(); ++dofIdxDomain)
472 if (backwardM[dofIdxDomain][dofIdxDomain][0][0] == 0.0)
473 backwardM[dofIdxDomain][dofIdxDomain][0][0] = 1.0;
474 }
475 }
476
477 return std::make_pair( std::make_pair(std::move(forwardM), std::move(forwardP)),
478 std::make_pair(std::move(backwardM), std::move(backwardP)) );
479}
480
486template<bool doBidirectional, class FEBasisDomain, class FEBasisTarget, class GlueType>
487auto makeProjectorPair(const FEBasisDomain& feBasisDomain,
488 const FEBasisTarget& feBasisTarget,
489 const GlueType& glue)
490{
491 using ForwardProjector = typename ProjectorTraits<FEBasisDomain, FEBasisTarget>::Projector;
492 using BackwardProjector = typename ProjectorTraits<FEBasisTarget, FEBasisDomain>::Projector;
493
494 using ForwardProjectionMatrix = typename ForwardProjector::Matrix;
495 using BackwardProjectionMatrix = typename BackwardProjector::Matrix;
496
497 auto projectionMatrices = createProjectionMatrices<doBidirectional>(feBasisDomain, feBasisTarget, glue, false);
498 auto& forwardMatrices = projectionMatrices.first;
499 auto& backwardMatrices = projectionMatrices.second;
500
501 auto& forwardM = forwardMatrices.first;
502 auto& forwardP = forwardMatrices.second;
503
504 auto& backwardM = backwardMatrices.first;
505 auto& backwardP = backwardMatrices.second;
506
507 // determine the dofs that do not take part in intersections
508 std::vector<bool> isVoidTarget(forwardM.N(), false);
509 for (std::size_t dofIdxTarget = 0; dofIdxTarget < forwardM.N(); ++dofIdxTarget)
510 if (forwardM[dofIdxTarget][dofIdxTarget][0][0] == 0.0)
511 isVoidTarget[dofIdxTarget] = true;
512
513 std::vector<bool> isVoidDomain;
514 if (doBidirectional)
515 {
516 isVoidDomain.resize(backwardM.N(), false);
517 for (std::size_t dofIdxDomain = 0; dofIdxDomain < backwardM.N(); ++dofIdxDomain)
518 if (backwardM[dofIdxDomain][dofIdxDomain][0][0] == 0.0)
519 isVoidDomain[dofIdxDomain] = true;
520 }
521
522 const bool hasVoidTarget = std::any_of(isVoidTarget.begin(), isVoidTarget.end(), [] (bool v) { return v; });
523 const bool hasVoidDomain = std::any_of(isVoidDomain.begin(), isVoidDomain.end(), [] (bool v) { return v; });
524 if (!hasVoidDomain && !hasVoidTarget)
525 {
526 return std::make_pair(ForwardProjector(std::move(forwardM), std::move(forwardP)),
527 BackwardProjector(std::move(backwardM), std::move(backwardP)));
528 }
529 else if (!hasVoidDomain && hasVoidTarget)
530 {
531 std::vector<std::size_t> expansionMapTarget;
532 ForwardProjectionMatrix forwardMReduced, forwardPReduced;
533 setupReducedMatrices(forwardM, forwardP, isVoidTarget,
534 forwardMReduced, forwardPReduced, expansionMapTarget);
535
536 return std::make_pair( ForwardProjector(std::move(forwardMReduced),
537 std::move(forwardPReduced),
538 std::move(expansionMapTarget),
539 forwardM.N()),
540 BackwardProjector(std::move(backwardM), std::move(backwardP)) );
541 }
542 else if (hasVoidDomain && !hasVoidTarget)
543 {
544 if (doBidirectional)
545 {
546 std::vector<std::size_t> expansionMapDomain;
547 BackwardProjectionMatrix backwardMReduced, backwardPReduced;
548 setupReducedMatrices(backwardM, backwardP, isVoidDomain,
549 backwardMReduced, backwardPReduced, expansionMapDomain);
550
551 return std::make_pair( ForwardProjector(std::move(forwardM), std::move(forwardP)),
552 BackwardProjector(std::move(backwardMReduced),
553 std::move(backwardPReduced),
554 std::move(expansionMapDomain),
555 backwardM.N()) );
556 }
557 else
558 return std::make_pair( ForwardProjector(std::move(forwardM), std::move(forwardP)),
559 BackwardProjector(std::move(backwardM), std::move(backwardP)) );
560 }
561 else
562 {
563 std::vector<std::size_t> expansionMapTarget;
564 ForwardProjectionMatrix forwardMReduced, forwardPReduced;
565 setupReducedMatrices(forwardM, forwardP, isVoidTarget,
566 forwardMReduced, forwardPReduced, expansionMapTarget);
567
568 if (doBidirectional)
569 {
570 std::vector<std::size_t> expansionMapDomain;
571 BackwardProjectionMatrix backwardMReduced, backwardPReduced;
572 setupReducedMatrices(backwardM, backwardP, isVoidDomain,
573 backwardMReduced, backwardPReduced, expansionMapDomain);
574
575 return std::make_pair( ForwardProjector(std::move(forwardMReduced),
576 std::move(forwardPReduced),
577 std::move(expansionMapTarget),
578 forwardM.N()),
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(forwardMReduced),
586 std::move(forwardPReduced),
587 std::move(expansionMapTarget),
588 forwardM.N()),
589 BackwardProjector(std::move(backwardM), std::move(backwardP)) );
590 }
591}
592
593} // end namespace Detail
594
595
608template< class FEBasisDomain, class FEBasisTarget, class GlueType >
609auto makeProjectorPair(const FEBasisDomain& feBasisDomain,
610 const FEBasisTarget& feBasisTarget,
611 GlueType glue)
612{
613 // we assume that target dim <= domain dimension
614 static constexpr int domainDim = FEBasisDomain::GridView::dimension;
615 static constexpr int targetDim = FEBasisTarget::GridView::dimension;
616 static_assert(targetDim <= domainDim, "makeProjectorPair() expects targetDim < domainDim, please swap arguments");
617
618 return Detail::makeProjectorPair<true>(feBasisDomain, feBasisTarget, glue);
619}
620
631template< class FEBasisDomain, class FEBasisTarget, class GlueType >
632auto makeProjector(const FEBasisDomain& feBasisDomain,
633 const FEBasisTarget& feBasisTarget,
634 GlueType glue)
635{
636 // we assume that target dim <= domain dimension
637 static constexpr int domainDim = FEBasisDomain::GridView::dimension;
638 static constexpr int targetDim = FEBasisTarget::GridView::dimension;
639 static_assert(targetDim <= domainDim, "makeProjectorPair() expects targetDim < domainDim, please swap arguments");
640
641 return Detail::makeProjectorPair<false>(feBasisDomain, feBasisTarget, glue).first;
642}
643
655template< class FEBasisDomain, class FEBasisTarget, class GlueType >
656auto makeProjectionMatricesPair(const FEBasisDomain& feBasisDomain,
657 const FEBasisTarget& feBasisTarget,
658 GlueType glue)
659{
660 // we assume that target dim <= domain dimension
661 static constexpr int domainDim = FEBasisDomain::GridView::dimension;
662 static constexpr int targetDim = FEBasisTarget::GridView::dimension;
663 static_assert(targetDim <= domainDim, "makeProjectionMatrixPair() expects targetDim < domainDim, please swap arguments");
664
665 return Detail::createProjectionMatrices<true>(feBasisDomain, feBasisTarget, glue);
666}
667
676template< class FEBasisDomain, class FEBasisTarget, class GlueType >
677auto makeProjectionMatrices(const FEBasisDomain& feBasisDomain,
678 const FEBasisTarget& feBasisTarget,
679 GlueType glue)
680{
681 // we assume that target dim <= domain dimension
682 static constexpr int domainDim = FEBasisDomain::GridView::dimension;
683 static constexpr int targetDim = FEBasisTarget::GridView::dimension;
684 static_assert(targetDim <= domainDim, "makeProjectionMatrixPair() expects targetDim < domainDim, please swap arguments");
685
686 return Detail::createProjectionMatrices<false>(feBasisDomain, feBasisTarget, glue).first;
687}
688
689} // end namespace Dumux
690
691#endif
static Params defaultParams()
Returns the default parameters.
Definition projector.hh:191
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:101
ScalarType Scalar
Export the scalar type.
Definition projector.hh:60
Projector(Matrix &&massMatrix, Matrix &&projectionMatrix)
Constructor. Receives the mass and projection matrix that define the linear system describing the L2-...
Definition projector.hh:80
Dune::BCRSMatrix< MatrixBlockType > Matrix
Export the type of the projection matrices.
Definition projector.hh:62
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:130
Traits class stating the type of projector between to bases.
Definition projector.hh:211
Dumux::Projector< Scalar > Projector
Definition projector.hh:218
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)
Creates a forward projector from the space feBasisDomain to the space with basis feBasisTarget.
Definition projector.hh:632
auto makeProjectorPair(const FEBasisDomain &feBasisDomain, const FEBasisTarget &feBasisTarget, GlueType glue)
Creates a pair of projectors between the space with basis feBasisDomain to the space with basis feBas...
Definition projector.hh:609
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:743
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 createProjectionMatrices(const FEBasisDomain &feBasisDomain, const FEBasisTarget &feBasisTarget, const GlueType &glue, bool treatDiagonalZeroes=true)
Creates the matrices underlying l2-projections.
Definition projector.hh:311
auto makeProjectorPair(const FEBasisDomain &feBasisDomain, const FEBasisTarget &feBasisTarget, const GlueType &glue)
Creates a projector class between two function space bases.
Definition projector.hh:487
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:233
Definition adapt.hh:17
auto makeProjectionMatricesPair(const FEBasisDomain &feBasisDomain, const FEBasisTarget &feBasisTarget, GlueType glue)
Creates the matrices underlying l2-projections.
Definition projector.hh:656
const Scalar PengRobinsonMixture< Scalar, StaticParameters >::u
Definition pengrobinsonmixture.hh:138
auto makeProjectionMatrices(const FEBasisDomain &feBasisDomain, const FEBasisTarget &feBasisTarget, GlueType glue)
Creates the matrices underlying l2-projections.
Definition projector.hh:677
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.
Definition linearalgebratraits.hh:51
Parameters that can be passed to project().
Definition projector.hh:66
Scalar residualReduction
Definition projector.hh:68
int verbosity
Definition projector.hh:69
std::size_t maxIterations
Definition projector.hh:67
Definition linearsolvertraits.hh:55