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>
44template<
class Function,
class Gr
idView>
47 using Element =
typename GridView::template Codim<0>::Entity;
48 using LocalCoord =
typename Element::Geometry::LocalCoordinate;
49 constexpr bool hasLocalInterface =
50 requires(std::decay_t<Function>& lf,
const Element& e,
const LocalCoord& x)
58 if constexpr (hasLocalInterface)
59 return std::forward<Function>(f);
60#ifdef HAVE_DUNE_FUNCTIONS
62 return localFunction(Dune::Functions::makeGridViewFunction(std::forward<Function>(f), gridView));
65 DUNE_THROW(Dune::InvalidStateException,
"Function must provide bind(element) and operator()(localCoord), "
66 "or dune-functions must be available to wrap a global f(globalPos) callable.");
80template<
class Gr
idDiscretization>
83 using GV =
typename GridDiscretization::GridView;
84 using Element =
typename GV::template Codim<0>::Entity;
85 using FE =
typename GridDiscretization::FeCache::FiniteElementType;
93 const FE*
fe_ =
nullptr;
101 explicit LocalView(
const GridDiscretization& gg) : gg_(gg) {}
103 void bind(
const Element& element)
106 tree_.fe_ = &gg_.feCache().get(element.type());
113 const auto& localKey = tree_.fe_->localCoefficients().localKey(
index);
116 return gg_.dofMapper().subIndex(*element_, localKey.subEntity(), localKey.codim()) + localKey.index();
120 const GridDiscretization& gg_;
121 std::optional<Element> element_;
127 std::size_t
size()
const {
return gg_.numDofs(); }
132 const GridDiscretization& gg_;
135template <
class FEBasis>
138 static constexpr int dim = FEBasis::GridView::dimension;
139 using FiniteElement =
typename FEBasis::LocalView::Tree::FiniteElement;
140 using Scalar =
typename FiniteElement::Traits::LocalBasisType::Traits::RangeFieldType;
141 using ShapeValue =
typename FiniteElement::Traits::LocalBasisType::Traits::RangeType;
142 static_assert(ShapeValue::dimension == 1,
"Only scalar-valued shape functions are supported for L2 projection.");
146 template<
int numEq = 1>
161 solver_.setMatrix(std::make_shared<Matrix>(createMassMatrix_(feBasis)));
164 template <
class Function>
168 using LocalPosition =
typename FEBasis::GridView::template Codim<0>::Entity::Geometry::LocalCoordinate;
169 using ReturnType = std::invoke_result_t<Function, LocalPosition>;
170 constexpr int numEq = []() {
171 if constexpr (Dune::IsNumber<ReturnType>::value)
return 1;
172 else return ReturnType::dimension;
176 const auto numDofs = feBasis_.size();
178 std::array<Dune::BlockVector<Scalar>, numEq> rhs;
179 for (
auto& r : rhs) { r.resize(numDofs); r = 0.0; }
183 for (
const auto& element : elements(feBasis_.gridView()))
186 localFunc.bind(element);
188 const auto& localFiniteElement =
localView.tree().finiteElement();
189 const int order = dim*localFiniteElement.localBasis().order();
190 const auto& quad = Dune::QuadratureRules<Scalar, dim>::rule(
element.type(), order);
191 const auto geometry =
element.geometry();
193 for (
auto&& qp : quad)
195 const auto weight = qp.weight();
196 const auto ie = geometry.integrationElement(qp.position());
198 std::vector<ShapeValue> shapeValues;
199 localFiniteElement.localBasis().evaluateFunction(qp.position(), shapeValues);
200 const auto functionValue = localFunc(qp.position());
202 for (
int i = 0; i < localFiniteElement.localBasis().size(); ++i)
205 const auto w = ie*weight*shapeValues[i][0];
206 if constexpr (numEq == 1)
207 rhs[0][globalI] +=
w*functionValue;
209 for (
int compIdx = 0; compIdx < numEq; compIdx++)
210 rhs[compIdx][globalI] +=
w*functionValue[compIdx];
216 CoeffVec coeffs(numDofs);
220 auto solver = solver_;
221 Dune::ParameterTree solverParams;
222 solverParams[
"maxit"] = std::to_string(params.maxIterations);
223 solverParams[
"reduction"] = Fmt::format(
"{}", params.residualReduction);
224 solverParams[
"verbose"] = std::to_string(params.verbosity);
225 solver.setParams(solverParams);
227 Dune::BlockVector<Scalar> sol(numDofs); sol = 0.0;
228 solver.solve(sol, rhs[compIdx]);
230 for (std::size_t i = 0; i < numDofs; ++i)
231 coeffs[i][compIdx] = sol[i];
238 Matrix createMassMatrix_(
const FEBasis& feBasis)
const
243 pattern.exportIdx(massMatrix);
247 for (
const auto& element : elements(feBasis.gridView()))
251 const auto& localFiniteElement =
localView.tree().finiteElement();
252 const int order = 2*dim*localFiniteElement.localBasis().order();
253 const auto& quad = Dune::QuadratureRules<Scalar, dim>::rule(
element.type(), order);
254 const auto geometry =
element.geometry();
256 for (
auto&& qp : quad)
258 const auto weight = qp.weight();
259 const auto ie = geometry.integrationElement(qp.position());
261 std::vector<ShapeValue> shapeValues;
262 localFiniteElement.localBasis().evaluateFunction(qp.position(), shapeValues);
264 for (
int i = 0; i < localFiniteElement.localBasis().size(); ++i)
267 massMatrix[globalI][globalI] += ie*weight*shapeValues[i]*shapeValues[i];
269 for (
int j = i+1; j < localFiniteElement.localBasis().size(); ++j)
272 const auto value = ie*weight*shapeValues[i]*shapeValues[j];
273 massMatrix[globalI][globalJ] += value;
274 massMatrix[globalJ][globalI] += value;
283 const FEBasis& feBasis_;
285 SeqLinearSolverTraits, LinearAlgebraTraits<Matrix, Dune::BlockVector<Scalar>>
GV GridView
Definition l2_projection.hh:88
FEBasisFromCVFEGridDiscretization(const GridDiscretization &gg)
Definition l2_projection.hh:125
const GridView & gridView() const
Definition l2_projection.hh:128
LocalView localView() const
Definition l2_projection.hh:129
std::size_t size() const
Definition l2_projection.hh:127
auto project(Function &&function, const Params ¶ms=Params{}) const
Definition l2_projection.hh:165
Dune::BlockVector< Dune::FieldVector< Scalar, numEq > > CoefficientVector
Definition l2_projection.hh:147
L2Projection(const FEBasis &feBasis)
Definition l2_projection.hh:157
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:743
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.
Definition cvfelocalresidual.hh:25
auto makeLocalFunction(Function &&f, const GridView &gridView)
Create a local function from a given function.
Definition l2_projection.hh:45
const Scalar PengRobinsonMixture< Scalar, StaticParameters >::w
Definition pengrobinsonmixture.hh:140
Parallel for loop (multithreading).
Definition l2_projection.hh:91
const FiniteElement & finiteElement() const
Definition l2_projection.hh:94
FE FiniteElement
Definition l2_projection.hh:92
const FE * fe_
Definition l2_projection.hh:93
Definition l2_projection.hh:98
LocalView(const GridDiscretization &gg)
Definition l2_projection.hh:101
const Tree & tree() const
Definition l2_projection.hh:109
LocalTree Tree
Definition l2_projection.hh:99
void bind(const Element &element)
Definition l2_projection.hh:103
std::size_t index(std::size_t index) const
Definition l2_projection.hh:111
Parameters that can be passed to project().
Definition l2_projection.hh:151
int verbosity
Definition l2_projection.hh:154
Scalar residualReduction
Definition l2_projection.hh:153
std::size_t maxIterations
Definition l2_projection.hh:152