Commit 90c3d73b authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

improved error messages, added quadrature degree parameter

parent e4baaf0f
......@@ -25,8 +25,8 @@ namespace AMDiS
"Expression must be of scalar or matrix type." );
public:
GridFunctionOperator(tag::testvec_trialvec, GridFct const& expr)
: Super(expr, 0)
GridFunctionOperator(tag::testvec_trialvec, GridFct const& expr, int degree)
: Super(expr, 0, degree)
{}
template <class Context, class QuadratureRule,
......
......@@ -76,25 +76,33 @@ namespace AMDiS
/// Return the polynomial order of the function f, if a free function
/// order(f) exists, otherwise return a default value.
#ifdef AMDIS_HAS_CXX_CONSTEXPR_IF
template <class Sig, class LocalContext, class F>
template <class Sig, class LocalContext, class F,
REQUIRES(Concepts::HasOrder<F>)>
int order(AnalyticLocalFunction<Sig,LocalContext,F> const& lf)
{
if constexpr (Concepts::HasOrder<F>)
return order(lf.fct(),1);
else
return AMDIS_CALLABLE_DEFAULT_ORDER;
return order(lf.fct(),1);
}
#else
template <class Sig, class LC, class F>
int order(AnalyticLocalFunction<Sig,LC,F> const& lf)
{
return Dune::Hybrid::ifElse( bool_<Concepts::HasOrder<F>>,
[&lf](auto id) { return id( order(lf.fct(),1) ); },
[] (auto id) { return AMDIS_CALLABLE_DEFAULT_ORDER; }
);
}
#endif
// #ifdef AMDIS_HAS_CXX_CONSTEXPR_IF
// template <class Sig, class LocalContext, class F>
// int order(AnalyticLocalFunction<Sig,LocalContext,F> const& lf)
// {
// if constexpr (Concepts::HasOrder<F>)
// return order(lf.fct(),1);
// else
// return AMDIS_CALLABLE_DEFAULT_ORDER;
// }
// #else
// template <class Sig, class LC, class F>
// int order(AnalyticLocalFunction<Sig,LC,F> const& lf)
// {
// return Dune::Hybrid::ifElse( bool_<Concepts::HasOrder<F>>,
// [&lf](auto id) { return id( order(lf.fct(),1) ); },
// [] (auto id) { return AMDIS_CALLABLE_DEFAULT_ORDER; }
// );
// }
// #endif
/// A Gridfunction that evaluates a function with global coordinates
......@@ -180,22 +188,24 @@ namespace AMDiS
return AnalyticPreGridFunction<Function>{f};
}
/** @} **/
/// Generator function for \ref AnalyticGridFunction expressions from callable functions.
template <class Function, class GridView,
REQUIRES(Concepts::CallableDomain<Function>)>
auto makeGridFunction(Function const& f, GridView const& gridView, Dune::PriorityTag<3>)
{
return AnalyticGridFunction<Function, GridView>{f, gridView};
}
/// Generator function for \ref AnalyticGridFunction expressions from \ref AnalyticPreGridFunction.
template <class Function, class GridView>
auto makeGridFunction(AnalyticPreGridFunction<Function> const& pre, GridView const& gridView, Dune::PriorityTag<3>)
namespace Impl
{
return AnalyticGridFunction<Function, GridView>{pre.fct_, gridView};
}
/// Generator function for \ref AnalyticGridFunction expressions from callable functions.
template <class Function, class GridView,
REQUIRES(Concepts::CallableDomain<Function>)>
auto makeGridFunctionImpl(Function const& f, GridView const& gridView, Dune::PriorityTag<3>)
{
return AnalyticGridFunction<Function, GridView>{f, gridView};
}
/** @} **/
/// Generator function for \ref AnalyticGridFunction expressions from \ref AnalyticPreGridFunction.
template <class Function, class GridView>
auto makeGridFunctionImpl(AnalyticPreGridFunction<Function> const& pre, GridView const& gridView, Dune::PriorityTag<3>)
{
return AnalyticGridFunction<Function, GridView>{pre.fct_, gridView};
}
} // end namespace Impl
} // end namespace AMDiS
......@@ -57,21 +57,19 @@ namespace AMDiS
return 0;
}
friend auto derivative(ConstantLocalFunction const& lf)
{
using RawSignature = typename Dune::Functions::SignatureTraits<R(D)>::RawSignature;
using DerivativeRange = typename Dune::Functions::DefaultDerivativeTraits<RawSignature>::Range;
DerivativeRange diff(0);
return ConstantLocalFunction<DerivativeRange(D),LocalContext,DerivativeRange>{diff};
}
private:
T value_;
};
template <class R, class D, class LC, class T>
auto derivative(ConstantLocalFunction<R(D),LC,T> const& lf)
{
using RawSignature = typename Dune::Functions::SignatureTraits<R(D)>::RawSignature;
using DerivativeRange = typename Dune::Functions::DefaultDerivativeTraits<RawSignature>::Range;
DerivativeRange diff(0);
return ConstantLocalFunction<DerivativeRange(D),LC,DerivativeRange>{diff};
}
/// A Gridfunction that evaluates a function with global coordinates
template <class T, class GridView>
class ConstantGridFunction
......@@ -157,20 +155,15 @@ namespace AMDiS
} // end namespace Concepts
/**
* \addtogroup GridFunctions
* @{
**/
/// Generator for a GridFunction representing a constant value
template <class T, class GridView,
REQUIRES(Concepts::ConstantToGridFunction<T>)>
auto makeGridFunction(T const& value, GridView const& gridView, Dune::PriorityTag<2>)
namespace Impl
{
return ConstantGridFunction<T,GridView>{value, gridView};
}
/** @} **/
/// Generator for a GridFunction representing a constant value
template <class T, class GridView,
REQUIRES(Concepts::ConstantToGridFunction<T>)>
auto makeGridFunctionImpl(T const& value, GridView const& gridView, Dune::PriorityTag<2>)
{
return ConstantGridFunction<T,GridView>{value, gridView};
}
} // end namespace Impl
} // end namespace AMDiS
......@@ -16,6 +16,17 @@ namespace AMDiS
/// A functor that evaluates to the global coordinates
struct CoordsFunction
{
template <class T, int N>
Dune::FieldVector<T, N> const& operator()(Dune::FieldVector<T, N> const& x) const
{
return x;
}
friend int order(CoordsFunction const& /*f*/, int /*d*/)
{
return 1;
}
struct Derivative
{
template <class T, int N>
......@@ -24,28 +35,32 @@ namespace AMDiS
return Dune::DiagonalMatrix<T,N>{T(1)};
}
};
template <class T, int N>
Dune::FieldVector<T, N> const& operator()(Dune::FieldVector<T, N> const& x) const
{
return x;
}
friend Derivative partial(CoordsFunction const& /*f*/, index_t<0>)
{
return Derivative{};
}
friend int order(CoordsFunction const& /*f*/, int /*d*/)
{
return 1;
}
};
/// A functor that evaluates to a component of the global coordinates
struct CoordsCompFunction
{
/// Constructor. Stores the component `comp` of the coordinates.
explicit CoordsCompFunction(int comp)
: comp_(comp)
{}
template <class T, int N>
T const& operator()(Dune::FieldVector<T, N> const& x) const
{
return x[comp_];
}
friend int order(CoordsCompFunction const& /*f*/, int /*d*/)
{
return 1;
}
struct Derivative
{
explicit Derivative(int comp)
......@@ -65,27 +80,11 @@ namespace AMDiS
int comp_;
};
/// Constructor. Stores the component `comp` of the coordinates.
explicit CoordsCompFunction(int comp)
: comp_(comp)
{}
template <class T, int N>
T const& operator()(Dune::FieldVector<T, N> const& x) const
{
return x[comp_];
}
friend Derivative partial(CoordsCompFunction const& f, index_t<0>)
{
return Derivative{f.comp_};
}
friend int order(CoordsCompFunction const& /*f*/, int /*d*/)
{
return 1;
}
private:
int comp_;
};
......@@ -117,25 +116,21 @@ namespace AMDiS
: std::true_type {};
}
/**
* \addtogroup GridFunctions
* @{
**/
/// Generator for GridFunction from the pre-GridFunction \ref CoordsFunction
template <class GridView>
auto makeGridFunction(Operation::CoordsFunction const& f, GridView const& gridView, Dune::PriorityTag<1>)
{
return makeAnalyticGridFunction(f, gridView);
}
/// Generator for GridFunction from the pre-GridFunction \ref CoordsCompFunction
template <class GridView>
auto makeGridFunction(Operation::CoordsCompFunction const& f, GridView const& gridView, Dune::PriorityTag<1>)
namespace Impl
{
return makeAnalyticGridFunction(f, gridView);
}
/// Generator for GridFunction from the pre-GridFunction \ref CoordsFunction
template <class GridView>
auto makeGridFunctionImpl(Operation::CoordsFunction const& f, GridView const& gridView, Dune::PriorityTag<1>)
{
return makeAnalyticGridFunction(f, gridView);
}
/** @} **/
/// Generator for GridFunction from the pre-GridFunction \ref CoordsCompFunction
template <class GridView>
auto makeGridFunctionImpl(Operation::CoordsCompFunction const& f, GridView const& gridView, Dune::PriorityTag<1>)
{
return makeAnalyticGridFunction(f, gridView);
}
} // end namespace Impl
} // end namespace AMDiS
......@@ -201,7 +201,6 @@ namespace AMDiS
public:
/// Constructor. Stores a pointer to the dofVector and a copy of the treePath.
DOFVectorView(DOFVector<GlobalBasis> const& dofVector, TreePath const& treePath)
: dofVector_(&dofVector)
......@@ -228,9 +227,7 @@ namespace AMDiS
return entitySet_;
}
public:
/// Return global basis
GlobalBasis const& basis() const
{
......@@ -249,9 +246,7 @@ namespace AMDiS
return *dofVector_;
}
protected:
DOFVector<GlobalBasis> const* dofVector_;
TreePath const treePath_;
......@@ -271,16 +266,13 @@ namespace AMDiS
using TreePath = TreePathType;
public:
/// Constructor. Stores a pointer to the mutable `dofvector`.
DOFVectorView(DOFVector<GlobalBasis>& dofVector, TreePath const& treePath)
: DOFVectorConstView(dofVector, treePath)
, mutableDofVector_(&dofVector)
{}
public:
/// Interpolation of GridFunction to DOFVector
template <class Expr>
DOFVectorView& interpolate(Expr&& expr)
......@@ -288,7 +280,7 @@ namespace AMDiS
auto const& basis = DOFVectorConstView::basis();
auto const& treePath = DOFVectorConstView::treePath();
auto&& gridFct = makeGridFunction(std::forward<Expr>(expr), basis.gridView(), Dune::PriorityTag<42>{});
auto&& gridFct = makeGridFunction(std::forward<Expr>(expr), basis.gridView());
DOFVector<GlobalBasis> tmp(basis, "tmp");
Dune::Functions::interpolate(basis, treePath, tmp, std::forward<decltype(gridFct)>(gridFct));
......@@ -304,9 +296,7 @@ namespace AMDiS
/// Return the const DOFVector
using DOFVectorConstView::coefficients;
protected:
DOFVector<GlobalBasis>* mutableDofVector_;
};
......
......@@ -21,7 +21,8 @@ namespace AMDiS
using GridFctDomain = typename GridFct::Domain;
public:
using Range = typename Dune::Functions::DefaultDerivativeTraits<GridFctRange(GridFctDomain)>::Range;
using RawSignature = typename Dune::Functions::SignatureTraits<GridFctRange(GridFctDomain)>::RawSignature;
using Range = typename Dune::Functions::DefaultDerivativeTraits<RawSignature>::Range;
using Domain = GridFctDomain;
using LocalFunction = std::decay_t<decltype(derivative(localFunction(std::declval<GridFct>())))>;
......@@ -83,13 +84,16 @@ namespace AMDiS
return DerivativePreGridFunction<Expr>{expr};
}
/// Generator function for \ref AnalyticGridFunction expressions from \ref AnalyticPreGridFunction.
template <class Expr, class GridView>
auto makeGridFunction(DerivativePreGridFunction<Expr> const& pre, GridView const& gridView, Dune::PriorityTag<3>)
{
return derivative(makeGridFunction(pre.expr, gridView, Dune::PriorityTag<42>{}));
}
/** @} **/
namespace Impl
{
/// Generator function for \ref AnalyticGridFunction expressions from \ref AnalyticPreGridFunction.
template <class Expr, class GridView>
auto makeGridFunctionImpl(DerivativePreGridFunction<Expr> const& pre, GridView const& gridView, Dune::PriorityTag<3>)
{
return derivative(Impl::makeGridFunctionImpl(pre.expr, gridView, Dune::PriorityTag<10>{}));
}
} // end namespace Impl
} // end namespace AMDiS
......@@ -119,7 +119,6 @@ namespace AMDiS
using LocalDomain = typename EntitySet::LocalCoordinate;
public:
template <class GridFct>
using LocalFct = std::decay_t<decltype(localFunction(std::declval<GridFct>()))>;
......@@ -213,27 +212,27 @@ namespace AMDiS
}
#ifdef AMDIS_HAS_CXX_CONSTEXPR_IF
template <class Sig, class F, class... LFs>
int order(FunctorLocalFunction<Sig,F,LFs...> const& lf)
{
if constexpr (Concepts::HasFunctorOrder<F,sizeof...(LFs)> &&
all_of_v<Concepts::HasOrder<LFs>...>)
{
return Dune::Std::apply([&lf](auto const&... lfs) { return order(lf.fct(), order(lfs)...); }, lf.localFcts());
}
else if constexpr (not Concepts::HasFunctorOrder<F,sizeof...(LFs)> &&
all_of_v<Concepts::HasOrder<LFs>...>)
{
return Dune::Std::apply([](auto const&... lfs) { return Math::max(order(lfs)...); }, lf.localFcts());
}
else {
return AMDIS_FUNCTOR_DEFAULT_ORDER;
}
}
#else
// #ifdef AMDIS_HAS_CXX_CONSTEXPR_IF
// template <class Sig, class F, class... LFs>
// int order(FunctorLocalFunction<Sig,F,LFs...> const& lf)
// {
// if constexpr (Concepts::HasFunctorOrder<F,sizeof...(LFs)> &&
// all_of_v<Concepts::HasOrder<LFs>...>)
// {
// return Dune::Std::apply([&lf](auto const&... lfs) { return order(lf.fct(), order(lfs)...); }, lf.localFcts());
// }
// else if constexpr (not Concepts::HasFunctorOrder<F,sizeof...(LFs)> &&
// all_of_v<Concepts::HasOrder<LFs>...>)
// {
// return Dune::Std::apply([](auto const&... lfs) { return Math::max(order(lfs)...); }, lf.localFcts());
// }
// else {
// return AMDIS_FUNCTOR_DEFAULT_ORDER;
// }
// }
// #else
/// Calculate the polynomial order for functors f providing a free functions
/// order(f, degs...), where degs are the order of the LocalFunctions
template <class Sig, class F, class... LFs,
......@@ -245,26 +244,26 @@ namespace AMDiS
lf.localFcts());
}
/// Specialization for \ref order for functor not providing an order free function.
/// Take the maximum of all provided LocalFunction orders
template <class Sig, class F, class... LFs,
REQUIRES(not Concepts::HasFunctorOrder<F,sizeof...(LFs)>
&& all_of_v<Concepts::HasOrder<LFs>...>)>
int order(FunctorLocalFunction<Sig,F,LFs...> const& lf)
{
return Dune::Std::apply([](auto const&... gfs) { return Math::max(order(gfs)...); },
lf.localFcts());
}
/// Specialization for \ref order for functor not providing an order free function
/// and some LocalFunctions do not provide an order function. Take a constant value.
template <class F, class... LFs,
REQUIRES(any_of_v<(not Concepts::HasOrder<LFs>)...>)>
int order(FunctorLocalFunction<Sig,F,LFs...> const& /*lf*/)
{
return AMDIS_FUNCTOR_DEFAULT_ORDER;
}
#endif
// /// Specialization for \ref order for functor not providing an order free function.
// /// Take the maximum of all provided LocalFunction orders
// template <class Sig, class F, class... LFs,
// REQUIRES(not Concepts::HasFunctorOrder<F,sizeof...(LFs)>
// && all_of_v<Concepts::HasOrder<LFs>...>)>
// int order(FunctorLocalFunction<Sig,F,LFs...> const& lf)
// {
// return Dune::Std::apply([](auto const&... gfs) { return Math::max(order(gfs)...); },
// lf.localFcts());
// }
// /// Specialization for \ref order for functor not providing an order free function
// /// and some LocalFunctions do not provide an order function. Take a constant value.
// template <class F, class... LFs,
// REQUIRES(any_of_v<(not Concepts::HasOrder<LFs>)...>)>
// int order(FunctorLocalFunction<Sig,F,LFs...> const& /*lf*/)
// {
// return AMDIS_FUNCTOR_DEFAULT_ORDER;
// }
// #endif
/// PreGridFunction related to \ref FunctorGridFunction, \relates FunctorGridFunction
......@@ -290,24 +289,28 @@ namespace AMDiS
/// Generator function for \ref FunctorPreGridFunction, i.e., creates a
/// pre GridFunction. \relates FunctorGridFunction
/// pre-GridFunction. \relates FunctorGridFunction
template <class Functor, class... GridFcts>
auto invokeAtQP(Functor const& f, GridFcts const&... gridFcts)
{
return FunctorPreGridFunction<Functor, GridFcts...>{f, gridFcts...};
}
/// Generator function from a \ref FunctorPreGridFunction to a \ref FunctorGridFunction.
template <class Functor, class... GridFcts, class GridView>
auto makeGridFunction(FunctorPreGridFunction<Functor, GridFcts...> const& preGridFct,
GridView const& gridView,
Dune::PriorityTag<5>)
{
return Dune::Std::apply([&](auto const&... pgf) {
return makeFunctorGridFunction(preGridFct.fct_, makeGridFunction(pgf, gridView, Dune::PriorityTag<42>{})...);
}, preGridFct.gridFcts_);
}
/** @} **/
namespace Impl
{
/// Generator function from a \ref FunctorPreGridFunction to a \ref FunctorGridFunction.
template <class Functor, class... GridFcts, class GridView>
auto makeGridFunctionImpl(FunctorPreGridFunction<Functor, GridFcts...> const& preGridFct,
GridView const& gridView,
Dune::PriorityTag<5>)
{
return Dune::Std::apply([&](auto const&... pgf) {
return makeFunctorGridFunction(preGridFct.fct_,
Impl::makeGridFunctionImpl(pgf, gridView, Dune::PriorityTag<10>{})...);
}, preGridFct.gridFcts_);
}
} // end namespace Impl
} // end namespace AMDiS
......@@ -55,16 +55,10 @@ namespace AMDiS
auto requires_(F&& f) -> decltype( order(f) );
};
struct HasFunctorOrder
{
template <class F, std::size_t... I>
auto requires_(F&& f, Indices<I...>) -> decltype( order(f, int(I)...) );
};
struct HasGridFunctionTypes
{
template <class GF>
auto requires_(GF&& /*gf*/) -> Void_t<
auto requires_(GF const& /*gf*/) -> Void_t<
typename GF::Range,
typename GF::Domain,
typename GF::EntitySet >;
......@@ -95,9 +89,6 @@ namespace AMDiS
template <class F>
constexpr bool HasOrder = models<Definition::HasOrder(F)>;
template <class F, std::size_t N>
constexpr bool HasFunctorOrder = models<Definition::HasOrder(F, MakeSeq_t<N>)>;
#ifndef AMDIS_DOW
template <class F>
constexpr bool CallableDomain =
......@@ -121,12 +112,15 @@ namespace AMDiS
} // end namespace Concepts
// Functions that forwards GridFunctions
template <class GridFct, class GridView,
REQUIRES(Concepts::GridFunction<GridFct>)>
auto const& makeGridFunction(GridFct const& gridFct, GridView const& /*gridView*/, Dune::PriorityTag<10>)
namespace Impl
{
return gridFct;
}
// Functions that forwards GridFunctions
template <class GridFct, class GridView,
REQUIRES(Concepts::GridFunction<GridFct>)>
auto const& makeGridFunctionImpl(GridFct const& gridFct, GridView const& /*gridView*/, Dune::PriorityTag<10>)
{
return gridFct;
}
} // end namespace Impl
} // end namespace AMDiS
......@@ -6,30 +6,76 @@
namespace AMDiS
{
namespace Impl
{
template <class GridFct, class GridView, class QuadProvider>
auto integrateImpl(GridFct&& gridFct, GridView const& gridView, QuadProvider makeQuad)
{
auto localFct = localFunction(gridFct);
using Range = typename std::decay_t<GridFct>::Range;
Range result(0);
for (auto const& element : elements(gridView)) {
auto geometry = element.geometry();
localFct.bind(element);