12#ifndef DUMUX_DISCRETIZATION_L2_PROJECTION_HH
13#define DUMUX_DISCRETIZATION_L2_PROJECTION_HH
20#include <dune/common/fvector.hh>
21#include <dune/common/fmatrix.hh>
22#include <dune/common/parametertree.hh>
23#include <dune/common/typetraits.hh>
24#include <dune/geometry/quadraturerules.hh>
25#include <dune/istl/bcrsmatrix.hh>
26#include <dune/istl/bvector.hh>
27#ifdef HAVE_DUNE_FUNCTIONS
28#include <dune/functions/gridfunctions/gridviewfunction.hh>
43template<
class Function,
class Gr
idView>
46 using Element =
typename GridView::template Codim<0>::Entity;
47 using LocalCoord =
typename Element::Geometry::LocalCoordinate;
48 constexpr bool hasLocalInterface =
49 requires(std::decay_t<Function>& lf,
const Element& e,
const LocalCoord& x)
57 if constexpr (hasLocalInterface)
58 return std::forward<Function>(f);
59#ifdef HAVE_DUNE_FUNCTIONS
61 return localFunction(Dune::Functions::makeGridViewFunction(std::forward<Function>(f), gridView));
64 DUNE_THROW(Dune::InvalidStateException,
"Function must provide bind(element) and operator()(localCoord), "
65 "or dune-functions must be available to wrap a global f(globalPos) callable.");
79template<
class Gr
idDiscretization>
82 using GV =
typename GridDiscretization::GridView;
83 using Element =
typename GV::template Codim<0>::Entity;
84 using FE =
typename GridDiscretization::FeCache::FiniteElementType;
92 const FE*
fe_ =
nullptr;
100 explicit LocalView(
const GridDiscretization& gg) : gg_(gg) {}
102 void bind(
const Element& element)
105 tree_.
fe_ = &gg_.feCache().get(element.type());
112 const auto& localKey = tree_.
fe_->localCoefficients().localKey(
index);
115 return gg_.dofMapper().subIndex(*element_, localKey.subEntity(), localKey.codim()) + localKey.index();
119 const GridDiscretization& gg_;
120 std::optional<Element> element_;
126 std::size_t
size()
const {
return gg_.numDofs(); }
131 const GridDiscretization& gg_;
134template <
class FEBasis>
137 static constexpr int dim = FEBasis::GridView::dimension;
138 using FiniteElement =
typename FEBasis::LocalView::Tree::FiniteElement;
139 using Scalar =
typename FiniteElement::Traits::LocalBasisType::Traits::RangeFieldType;
140 using ShapeValue =
typename FiniteElement::Traits::LocalBasisType::Traits::RangeType;
141 static_assert(ShapeValue::dimension == 1,
"Only scalar-valued shape functions are supported for L2 projection.");
145 template<
int numEq = 1>
160 solver_.setMatrix(std::make_shared<Matrix>(createMassMatrix_(feBasis)));
163 template <
class Function>
167 using LocalPosition =
typename FEBasis::GridView::template Codim<0>::Entity::Geometry::LocalCoordinate;
168 using ReturnType = std::invoke_result_t<Function, LocalPosition>;
169 constexpr int numEq = []() {
170 if constexpr (Dune::IsNumber<ReturnType>::value)
return 1;
171 else return ReturnType::dimension;
173 using CoeffVec = CoefficientVector<numEq>;
175 const auto numDofs = feBasis_.size();
177 std::array<Dune::BlockVector<Scalar>, numEq> rhs;
178 for (
auto& r : rhs) { r.resize(numDofs); r = 0.0; }
182 for (
const auto& element : elements(feBasis_.gridView()))
185 localFunc.bind(element);
187 const auto& localFiniteElement =
localView.tree().finiteElement();
188 const int order = dim*localFiniteElement.localBasis().order();
189 const auto& quad = Dune::QuadratureRules<Scalar, dim>::rule(
element.type(), order);
190 const auto geometry =
element.geometry();
192 for (
auto&& qp : quad)
194 const auto weight = qp.weight();
195 const auto ie = geometry.integrationElement(qp.position());
197 std::vector<ShapeValue> shapeValues;
198 localFiniteElement.localBasis().evaluateFunction(qp.position(), shapeValues);
199 const auto functionValue = localFunc(qp.position());
201 for (
int i = 0; i < localFiniteElement.localBasis().size(); ++i)
204 const auto w = ie*weight*shapeValues[i][0];
205 if constexpr (numEq == 1)
206 rhs[0][globalI] += w*functionValue;
208 for (
int compIdx = 0; compIdx < numEq; compIdx++)
209 rhs[compIdx][globalI] += w*functionValue[compIdx];
215 CoeffVec coeffs(numDofs);
219 auto solver = solver_;
220 Dune::ParameterTree solverParams;
221 solverParams[
"maxit"] = std::to_string(params.maxIterations);
222 solverParams[
"reduction"] = std::to_string(params.residualReduction);
223 solverParams[
"verbose"] = std::to_string(params.verbosity);
224 solver.setParams(solverParams);
226 Dune::BlockVector<Scalar> sol(numDofs); sol = 0.0;
227 solver.solve(sol, rhs[compIdx]);
229 for (std::size_t i = 0; i < numDofs; ++i)
230 coeffs[i][compIdx] = sol[i];
237 Matrix createMassMatrix_(
const FEBasis& feBasis)
const
242 pattern.exportIdx(massMatrix);
246 for (
const auto& element : elements(feBasis.gridView()))
250 const auto& localFiniteElement =
localView.tree().finiteElement();
251 const int order = 2*dim*localFiniteElement.localBasis().order();
252 const auto& quad = Dune::QuadratureRules<Scalar, dim>::rule(
element.type(), order);
253 const auto geometry =
element.geometry();
255 for (
auto&& qp : quad)
257 const auto weight = qp.weight();
258 const auto ie = geometry.integrationElement(qp.position());
260 std::vector<ShapeValue> shapeValues;
261 localFiniteElement.localBasis().evaluateFunction(qp.position(), shapeValues);
263 for (
int i = 0; i < localFiniteElement.localBasis().size(); ++i)
266 massMatrix[globalI][globalI] += ie*weight*shapeValues[i]*shapeValues[i];
268 for (
int j = i+1; j < localFiniteElement.localBasis().size(); ++j)
271 const auto value = ie*weight*shapeValues[i]*shapeValues[j];
272 massMatrix[globalI][globalJ] += value;
273 massMatrix[globalJ][globalI] += value;
282 const FEBasis& feBasis_;
284 SeqLinearSolverTraits, LinearAlgebraTraits<Matrix, Dune::BlockVector<Scalar>>
Wraps a CVFE grid discretization to expose the FE basis interface expected by L2Projection.
Definition: l2_projection.hh:81
GV GridView
Definition: l2_projection.hh:87
FEBasisFromCVFEGridDiscretization(const GridDiscretization &gg)
Definition: l2_projection.hh:124
const GridView & gridView() const
Definition: l2_projection.hh:127
LocalView localView() const
Definition: l2_projection.hh:128
std::size_t size() const
Definition: l2_projection.hh:126
Definition: l2_projection.hh:136
auto project(Function &&function, const Params ¶ms=Params{}) const
Definition: l2_projection.hh:164
L2Projection(const FEBasis &feBasis)
Definition: l2_projection.hh:156
Dune::BlockVector< Dune::FieldVector< Scalar, numEq > > CoefficientVector
Definition: l2_projection.hh:146
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:706
void parallelFor(const std::size_t count, const FunctorType &functor)
A parallel for loop (multithreading)
Definition: parallel_for.hh:160
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.
auto makeLocalFunction(Function &&f, const GridView &gridView)
Create a local function from a given function.
Definition: l2_projection.hh:44
Parallel for loop (multithreading)
Definition: l2_projection.hh:90
const FiniteElement & finiteElement() const
Definition: l2_projection.hh:93
FE FiniteElement
Definition: l2_projection.hh:91
const FE * fe_
Definition: l2_projection.hh:92
Definition: l2_projection.hh:97
LocalView(const GridDiscretization &gg)
Definition: l2_projection.hh:100
const Tree & tree() const
Definition: l2_projection.hh:108
LocalTree Tree
Definition: l2_projection.hh:98
void bind(const Element &element)
Definition: l2_projection.hh:102
std::size_t index(std::size_t index) const
Definition: l2_projection.hh:110
Parameters that can be passed to project()
Definition: l2_projection.hh:150
int verbosity
Definition: l2_projection.hh:153
Scalar residualReduction
Definition: l2_projection.hh:152
std::size_t maxIterations
Definition: l2_projection.hh:151