version 3.8
l2_projection.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-FileCopyrightInfo: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5// SPDX-License-Identifier: GPL-3.0-or-later
6//
12#ifndef DUMUX_DISCRETIZATION_L2_PROJECTION_HH
13#define DUMUX_DISCRETIZATION_L2_PROJECTION_HH
14#if HAVE_DUNE_FUNCTIONS
15
16#include <vector>
17
18#include <dune/common/fvector.hh>
19#include <dune/common/fmatrix.hh>
20#include <dune/common/parametertree.hh>
21#include <dune/geometry/quadraturerules.hh>
22#include <dune/istl/bcrsmatrix.hh>
23#include <dune/istl/bvector.hh>
24#include <dune/functions/gridfunctions/gridviewfunction.hh>
25
30
31namespace Dumux {
32
33
34template <class FEBasis>
35class L2Projection
36{
37 static constexpr int dim = FEBasis::GridView::dimension;
38 using FiniteElement = typename FEBasis::LocalView::Tree::FiniteElement;
39 using Scalar = typename FiniteElement::Traits::LocalBasisType::Traits::RangeFieldType;
40 using ShapeValue = typename FiniteElement::Traits::LocalBasisType::Traits::RangeType;
42public:
43 using CoefficientVector = Dune::BlockVector<Dune::FieldVector<Scalar, 1>>;
44
46 struct Params
47 {
48 std::size_t maxIterations{100};
49 Scalar residualReduction{1e-13};
50 int verbosity{0};
51 };
52
53 L2Projection(const FEBasis& feBasis)
54 : feBasis_(feBasis)
55 , solver_()
56 {
57 solver_.setMatrix(std::make_shared<Matrix>(createMassMatrix_(feBasis)));
58 }
59
60 template <class Function>
61 CoefficientVector project(Function&& function, const Params& params = Params{}) const
62 {
63 CoefficientVector projection, rhs;
64 projection.resize(feBasis_.size());
65 rhs.resize(feBasis_.size());
66 rhs = 0.0;
67
68 // assemble right hand size
69 auto localFunc = localFunction(Dune::Functions::makeGridViewFunction(function, feBasis_.gridView()));
70 auto localView = feBasis_.localView();
71 for (const auto& element : elements(feBasis_.gridView()))
72 {
73 localView.bind(element);
74 localFunc.bind(element);
75
76 const auto& localFiniteElement = localView.tree().finiteElement();
77 const int order = dim*localFiniteElement.localBasis().order();
78 const auto& quad = Dune::QuadratureRules<Scalar, dim>::rule(element.type(), order);
79 const auto geometry = element.geometry();
80
81 for (auto&& qp : quad)
82 {
83 const auto weight = qp.weight();
84 const auto ie = geometry.integrationElement(qp.position());
85 const auto globalPos = geometry.global(qp.position());
86
87 std::vector<ShapeValue> shapeValues;
88 localFiniteElement.localBasis().evaluateFunction(geometry.local(globalPos), shapeValues);
89 const auto functionValue = localFunc(qp.position());
90
91 for (int i = 0; i < localFiniteElement.localBasis().size(); ++i)
92 {
93 const auto globalI = localView.index(i);
94 rhs[globalI] += ie*weight*shapeValues[i]*functionValue;
95 }
96 }
97 }
98
99 // solve projection
100 Dune::ParameterTree solverParams;
101 solverParams["maxit"] = std::to_string(params.maxIterations);
102 solverParams["reduction"] = std::to_string(params.residualReduction);
103 solverParams["verbose"] = std::to_string(params.verbosity);
104 auto solver = solver_; // copy the solver to modify the parameters
105 solver.setParams(solverParams);
106 solver.solve(projection, rhs);
107
108 return projection;
109 }
110
111private:
112 Matrix createMassMatrix_(const FEBasis& feBasis) const
113 {
114 Matrix massMatrix;
115
116 auto pattern = getFEJacobianPattern(feBasis);
117 pattern.exportIdx(massMatrix);
118
119 auto localView = feBasis.localView();
120 for (const auto& element : elements(feBasis.gridView()))
121 {
122 localView.bind(element);
123
124 const auto& localFiniteElement = localView.tree().finiteElement();
125 const int order = 2*(dim*localFiniteElement.localBasis().order()-1);
126 const auto& quad = Dune::QuadratureRules<Scalar, dim>::rule(element.type(), order);
127 const auto geometry = element.geometry();
128
129 for (auto&& qp : quad)
130 {
131 const auto weight = qp.weight();
132 const auto ie = geometry.integrationElement(qp.position());
133 const auto globalPos = geometry.global(qp.position());
134
135 std::vector<ShapeValue> shapeValues;
136 localFiniteElement.localBasis().evaluateFunction(geometry.local(globalPos), shapeValues);
137
138 for (int i = 0; i < localFiniteElement.localBasis().size(); ++i)
139 {
140
141 const auto globalI = localView.index(i);
142 massMatrix[globalI][globalI] += ie*weight*shapeValues[i]*shapeValues[i];
143
144 for (int j = i+1; j < localFiniteElement.localBasis().size(); ++j)
145 {
146 const auto globalJ = localView.index(j);
147 const auto value = ie*weight*shapeValues[i]*shapeValues[j];
148 massMatrix[globalI][globalJ] += value;
149 massMatrix[globalJ][globalI] += value;
150 }
151 }
152 }
153 }
154
155 return massMatrix;
156 }
157
158 const FEBasis& feBasis_;
160 SeqLinearSolverTraits, LinearAlgebraTraits<Matrix, CoefficientVector>
161 > solver_;
162};
163
164} // end namespace Dumux
165
166#endif // HAVE_DUNE_FUNCTIONS
167#endif
Definition: matrix.hh:20
Dune::MatrixIndexSet getFEJacobianPattern(const FEBasis &feBasis)
Helper function to generate Jacobian pattern for finite element scheme.
Definition: jacobianpattern.hh:106
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:657
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.
constexpr Projection projection
Definition: couplingmanager1d3d_projection.hh:263
Definition: adapt.hh:17