Commit 7489f1fb authored by Praetorius, Simon's avatar Praetorius, Simon

Merge branch 'issue/order' into 'master'

repaired the order function

See merge request !198
parents 59f986f2 3b87a828
Pipeline #4541 passed with stage
in 39 minutes and 23 seconds
......@@ -4,6 +4,7 @@
#include <dune/geometry/quadraturerules.hh>
#include <dune/grid/common/partitionset.hh>
#include <amdis/GridFunctions.hpp>
#include <amdis/common/Order.hpp>
namespace AMDiS
{
......@@ -49,9 +50,15 @@ namespace AMDiS
{
auto&& gridFct = makeGridFunction(FWD(expr), gridView);
using LocalFct = TYPEOF(localFunction(gridFct));
static_assert(Concepts::Polynomial<LocalFct>, "Polynomial degree of expression can not be deduced. You need to provide an explicit value for the quadrature degree or a quadrature rule in `integrate()`.");
using Rules = Dune::QuadratureRules<typename GridView::ctype, GridView::dimension>;
if constexpr(Concepts::Polynomial<LocalFct>)
return Impl::integrateImpl(FWD(gridFct), gridView,
[](auto&& t, auto&& lf) { return Rules::rule(t, polynomialDegree(lf).value()); });
[](auto&& t, auto&& lf) { return Rules::rule(t, order(lf)); });
else
return 0.0;
}
......
......@@ -7,6 +7,7 @@
#include <amdis/ContextGeometry.hpp>
#include <amdis/Output.hpp>
#include <amdis/common/TypeTraits.hpp>
#include <amdis/functions/Order.hpp>
#include <amdis/typetree/FiniteElementType.hpp>
namespace AMDiS
......
......@@ -23,7 +23,7 @@ install(FILES
Literals.hpp
Logical.hpp
Math.hpp
PolynomialDegree.hpp
Order.hpp
Range.hpp
QuadMath.hpp
SharedPtr.hpp
......
......@@ -6,12 +6,12 @@
namespace AMDiS
{
// polynomial order of local functions
template <class LocalFunction>
auto order(LocalFunction const& lf)
-> decltype(lf.order())
/// polynomial order of functions
template <class F>
auto order(F const& f)
-> decltype(f.order())
{
return lf.order();
return f.order();
}
namespace Concepts
......@@ -32,12 +32,12 @@ namespace AMDiS
} // end namespace Definition
/// \brief LocalFuncion LF has free function `order(F)`
template <class LF>
constexpr bool Polynomial = models<Definition::Polynomial(LF)>;
/// \brief Funcion F has free function `order(F)`
template <class F>
constexpr bool Polynomial = models<Definition::Polynomial(F)>;
template <class LF>
using Polynomial_t = models_t<Definition::Polynomial(LF)>;
template <class F>
using Polynomial_t = models_t<Definition::Polynomial(F)>;
/** @} **/
......
#pragma once
#include <optional>
#include <type_traits>
#include <dune/common/std/type_traits.hh>
namespace AMDiS
{
namespace Traits
{
template <class T>
using OrderFreeFunction = decltype(order(std::declval<T>()));
template <class T>
using OrderMemberFunction = decltype(std::declval<T>().order());
} // end namespace Traits
/// Polynomial degree of a local function or a finite-element space or anything
/// else that defines an order function.
/**
* Return the derived or defined polynomial degree of a function `f`
* If no order is defined, return an empty optional.
**/
template <class F>
std::optional<int> polynomialDegree(F const& f)
{
if constexpr (Dune::Std::is_detected_v<Traits::OrderFreeFunction,F>)
return order(f);
else if constexpr (Dune::Std::is_detected_v<Traits::OrderMemberFunction,F>)
return f.order();
else
return std::nullopt;
}
} // end namespace AMDiS
\ No newline at end of file
#pragma once
#include <cmath>
#include <type_traits>
#include <dune/common/typetraits.hh>
#include <dune/typetree/nodetags.hh>
#include <amdis/common/ConceptsBase.hpp>
#include <amdis/common/ForEach.hpp>
#include <amdis/Output.hpp>
#include <amdis/common/Math.hpp>
#include <amdis/common/Apply.hpp>
namespace AMDiS
{
template <class Node>
auto order(Node const& node)
-> decltype(node.finiteElement().localBasis().order())
/// Polynomial order of local basis-node
template <class N,
class = typename N::NodeTag>
int order(N const& node)
{
if constexpr (N::isLeaf)
return node.finiteElement().localBasis().order();
}
template <class Node,
REQUIRES(std::is_same_v<typename Node::NodeTag, Dune::TypeTree::PowerNodeTag>)>
int order(Node const& node)
{
else if constexpr (N::isPower)
return order(node.child(0u));
}
template <class Node,
REQUIRES(std::is_same_v<typename Node::NodeTag, Dune::TypeTree::CompositeNodeTag>)>
int order(Node const& node)
{
int degree = 0;
Tools::for_range<0,Node::CHILDREN>([&](auto const _i) {
degree = std::max(degree, int(order(node.child(_i))));
else if constexpr (N::isComposite)
return Tools::apply_indices<N::degree()>([&](auto... ii) {
return Math::max(order(node.child(ii))...);
});
return degree;
else {
warning("Unknown basis-node type. Assuming polynomial degree 1.");
return 1;
}
}
} // end namespace AMDiS
......@@ -8,8 +8,8 @@
#include <amdis/Operations.hpp>
#include <amdis/common/DerivativeTraits.hpp>
#include <amdis/common/Order.hpp>
#include <amdis/gridfunctions/GridFunction.hpp>
#include <amdis/gridfunctions/Order.hpp>
namespace AMDiS
{
......
......@@ -12,5 +12,4 @@ install(FILES
FunctorGridFunction.hpp
GridFunction.hpp
OperationsGridFunction.hpp
Order.hpp
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/amdis/gridfunctions)
......@@ -8,9 +8,9 @@
#include <amdis/Operations.hpp>
#include <amdis/common/ForEach.hpp>
#include <amdis/common/Logical.hpp>
#include <amdis/common/Order.hpp>
#include <amdis/gridfunctions/Derivative.hpp>
#include <amdis/gridfunctions/GridFunction.hpp>
#include <amdis/gridfunctions/Order.hpp>
namespace AMDiS
{
......
......@@ -6,8 +6,8 @@
#include <amdis/common/Concepts.hpp>
#include <amdis/common/Logical.hpp>
#include <amdis/common/Order.hpp>
#include <amdis/gridfunctions/Derivative.hpp>
#include <amdis/gridfunctions/Order.hpp>
namespace AMDiS
{
......
......@@ -179,7 +179,10 @@ namespace AMDiS
template <class LocalFct>
int coeffOrder(LocalFct const& localFct)
{
return polynomialDegree(localFct).value_or(0);
if constexpr (Concepts::Polynomial<LocalFct>)
return order(localFct);
else
return 0;
}
template <class T, int N>
......
#pragma once
#include <cmath>
#include <dune/common/typetraits.hh>
#include <dune/typetree/nodetags.hh>
#include <amdis/common/Concepts.hpp>
#include <amdis/common/ForEach.hpp>
#include <amdis/common/Index.hpp>
#include <amdis/common/Tags.hpp>
namespace AMDiS
......@@ -18,10 +12,6 @@ namespace AMDiS
struct FiniteElementTypeImpl
{
using type = tag::unknown;
static int order(Node const& node)
{
return 1;
}
};
}
......@@ -32,13 +22,6 @@ namespace AMDiS
template <class Node>
using FiniteElementType_t = typename FiniteElementType<Node>::type;
template <class Node>
auto order(Node const& node)
-> decltype(FiniteElementType<Node>::order(node))
{
return FiniteElementType<Node>::order(node);
}
namespace Impl
{
// Leaf node
......@@ -54,12 +37,6 @@ namespace AMDiS
{
using ChildNode = typename Node::template Child<0>::type;
using type = FiniteElementType_t<ChildNode>;
static int order(Node const& node)
{
using AMDiS::order;
return order(node.child(0u));
}
};
// Composite node
......@@ -67,16 +44,6 @@ namespace AMDiS
struct FiniteElementTypeImpl<Node, Dune::TypeTree::CompositeNodeTag>
{
using type = tag::unknown; // no common FiniteElement type
static int order(Node const& node)
{
using AMDiS::order;
int degree = 0;
Tools::for_range<0,Node::CHILDREN>([&](auto const _i) {
degree = std::max(degree, order(node.child(_i)));
});
return degree;
}
};
} // end namespace Impl
......
......@@ -5,8 +5,7 @@
#include <dune/geometry/quadraturerules.hh>
#include <dune/geometry/type.hh>
#include <amdis/common/PolynomialDegree.hpp>
#include <amdis/gridfunctions/Order.hpp>
#include <amdis/common/Order.hpp>
namespace AMDiS
{
......@@ -49,7 +48,9 @@ namespace AMDiS
public:
void bind(LocalFunction const& localFct) final
{
order_ = polynomialDegree(localFct).value();
using AMDiS::order;
if constexpr (Concepts::Polynomial<LocalFunction>)
order_ = order(localFct);
}
int order() const final { return order_; }
......
......@@ -4,7 +4,7 @@
#include <dune/functions/functionspacebases/powerbasis.hh>
#include <dune/functions/functionspacebases/lagrangebasis.hh>
#include <amdis/common/PolynomialDegree.hpp>
#include <amdis/common/Order.hpp>
#include <amdis/functions/Order.hpp>
#include <amdis/typetree/FiniteElementType.hpp>
#include "Tests.hpp"
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment