12#ifndef DUMUX_COMMON_INTEGRATE_HH
13#define DUMUX_COMMON_INTEGRATE_HH
18#include <dune/common/typetraits.hh>
19#include <dune/common/ftraits.hh>
20#include <dune/geometry/quadraturerules.hh>
21#include <dune/common/concept.hh>
23#if HAVE_DUNE_FUNCTIONS
24#include <dune/functions/gridfunctions/gridfunction.hh>
37struct HasLocalFunction
40 auto require(F&& f) ->
decltype(
42 localFunction(f).unbind()
47static constexpr bool hasLocalFunction()
48{
return Dune::models<HasLocalFunction, F>(); }
51 typename std::enable_if_t<Dune::IsIndexable<Error>::value,
int> = 0>
52Error sqrtNorm(
const Error& error)
56 for (
int i = 0; i < error.size(); ++i)
57 e[i] = sqrt(error[i]);
62 typename std::enable_if_t<!Dune::IsIndexable<Error>::value,
int> = 0>
63Error sqrtNorm(
const Error& error)
69template<
class T,
typename =
int>
76struct FieldTypeImpl<T, typename std::enable_if<(sizeof(std::declval<T>()[0]) > 0), int>::type>
78 using type =
typename FieldTypeImpl<std::decay_t<decltype(std::declval<T>()[0])>>::type;
82using FieldType =
typename FieldTypeImpl<T>::type;
86auto scalarIntegrand(
const T& t)
88 if constexpr (Dune::IsNumber<T>::value)
92 static_assert(T::size() == 1,
"The integrand has to be a scalar or a vector with a single entry");
99auto squaredNorm(
const T& t)
101 if constexpr (Dune::IsNumber<T>::value)
104 const auto a = abs(t);
108 return t.two_norm2();
120template<
class GridGeometry,
class SolutionVector,
121 typename std::enable_if_t<!Detail::hasLocalFunction<SolutionVector>(),
int> = 0>
123 const SolutionVector& sol,
126 using GridView =
typename GridGeometry::GridView;
127 using Scalar =
typename Detail::FieldType< std::decay_t<
decltype(sol[0])> >;
129 Scalar integral(0.0);
130 for (
const auto& element : elements(gg.gridView()))
133 const auto geometry = element.geometry();
134 const auto& quad = Dune::QuadratureRules<typename GridView::ctype, GridView::dimension>::rule(geometry.type(), order);
135 for (
auto&& qp : quad)
137 auto value =
evalSolution(element, geometry, gg, elemSol, geometry.global(qp.position()));
138 value *= qp.weight()*geometry.integrationElement(qp.position());
139 integral += Detail::scalarIntegrand(value);
153template<
class GridGeometry,
class Sol1,
class Sol2,
154 typename std::enable_if_t<!Detail::hasLocalFunction<Sol1>(),
int> = 0>
160 using GridView =
typename GridGeometry::GridView;
161 using Scalar =
typename Dune::FieldTraits<Detail::FieldType< std::decay_t<
decltype(sol1[0])> >>::real_type;
164 for (
const auto& element : elements(gg.gridView()))
169 const auto geometry = element.geometry();
170 const auto& quad = Dune::QuadratureRules<typename GridView::ctype, GridView::dimension>::rule(geometry.type(), order);
171 for (
auto&& qp : quad)
173 const auto& globalPos = geometry.global(qp.position());
174 const auto value1 =
evalSolution(element, geometry, gg, elemSol1, globalPos);
175 const auto value2 =
evalSolution(element, geometry, gg, elemSol2, globalPos);
176 const auto error = (value1 - value2);
177 l2norm += Detail::squaredNorm(error)*qp.weight()*geometry.integrationElement(qp.position());
185#if HAVE_DUNE_FUNCTIONS
194template<
class GridView,
class F,
195 typename std::enable_if_t<Detail::hasLocalFunction<F>(),
int> = 0>
200 auto fLocal = localFunction(f);
202 using Element =
typename GridView::template Codim<0>::Entity;
203 using LocalPosition =
typename Element::Geometry::LocalCoordinate;
204 using Scalar =
typename Detail::FieldType< std::decay_t<decltype(fLocal(std::declval<LocalPosition>()))> >;
206 Scalar integral(0.0);
207 for (
const auto& element : elements(gv))
209 fLocal.bind(element);
211 const auto geometry = element.geometry();
212 const auto& quad = Dune::QuadratureRules<typename GridView::ctype, GridView::dimension>::rule(geometry.type(), order);
213 for (
auto&& qp : quad)
215 auto value = fLocal(qp.position());
216 value *= qp.weight()*geometry.integrationElement(qp.position());
217 integral += Detail::scalarIntegrand(value);
234template<
class GridView,
class F,
class G,
235 typename std::enable_if_t<Detail::hasLocalFunction<F>(),
int> = 0>
241 auto fLocal = localFunction(f);
242 auto gLocal = localFunction(g);
244 using Element =
typename GridView::template Codim<0>::Entity;
245 using LocalPosition =
typename Element::Geometry::LocalCoordinate;
246 using Scalar =
typename Dune::FieldTraits<Detail::FieldType< std::decay_t<decltype(fLocal(std::declval<LocalPosition>()))> >>::real_type;
249 for (
const auto& element : elements(gv))
251 fLocal.bind(element);
252 gLocal.bind(element);
254 const auto geometry =
element.geometry();
255 const auto& quad = Dune::QuadratureRules<typename GridView::ctype, GridView::dimension>::rule(geometry.type(), order);
256 for (
auto&& qp : quad)
258 const auto error = fLocal(qp.position()) - gLocal(qp.position());
259 l2norm += Detail::squaredNorm(error)*qp.weight()*geometry.integrationElement(qp.position());
279template<
class Scalar,
class Function,
280 typename std::enable_if_t<std::is_invocable_r_v<Scalar, Function, Scalar>>...>
282 const Scalar lowerBound,
283 const Scalar upperBound,
284 const Scalar targetAbsoluteError = 1e-13)
static Scalar integrate(const Function &f, const Scalar a, const Scalar b, const Scalar targetAbsoluteError, int &numFunctionEvaluations, Scalar &errorEstimate)
Integrate an analytic function over a finite interval.
Definition doubleexpintegrator.hh:80
A double exponential integrator.
Element solution classes and factory functions.
free functions for the evaluation of primary variables inside elements.
PrimaryVariables evalSolution(const Element &element, const typename Element::Geometry &geometry, const typename FVElementGeometry::GridGeometry &gridGeometry, const CVFEElementSolution< FVElementGeometry, PrimaryVariables > &elemSol, const typename Element::Geometry::GlobalCoordinate &globalPos, bool ignoreState=false)
Interpolates a given box element solution at a given global position. Uses the finite element cache o...
Definition evalsolution.hh:197
auto elementSolution(const Element &element, const SolutionVector &sol, const GridGeometry &gg) -> std::enable_if_t< GridGeometry::discMethod==DiscretizationMethods::cctpfa||GridGeometry::discMethod==DiscretizationMethods::ccmpfa, CCElementSolution< typename GridGeometry::LocalView, std::decay_t< decltype(std::declval< SolutionVector >()[0])> > >
Make an element solution for cell-centered schemes.
Definition cellcentered/elementsolution.hh:101
Definition cvfelocalresidual.hh:25
typename ScalarType< X >::Type Scalar
Definition odesolver.hh:52
Scalar integrateScalarFunction(const Function &f, const Scalar lowerBound, const Scalar upperBound, const Scalar targetAbsoluteError=1e-13)
Integrate a scalar function.
Definition integrate.hh:281
auto integrateGridFunction(const GridGeometry &gg, const SolutionVector &sol, std::size_t order)
Integrate a grid function over a grid view.
Definition integrate.hh:122
auto integrateL2Error(const GridGeometry &gg, const Sol1 &sol1, const Sol2 &sol2, std::size_t order)
Integrate a function over a grid view.
Definition integrate.hh:155