AMDiS 2.10
The Adaptive Multi-Dimensional Simulation Toolbox
RangeType.hpp
1#pragma once
2
3#include <type_traits>
4#include <utility>
5
6#include <dune/common/fvector.hh>
7#include <dune/common/tuplevector.hh>
8#include <dune/common/typetraits.hh>
9
10#include <amdis/common/Index.hpp>
11#include <amdis/common/TypeTraits.hpp>
12
13namespace Dune
14{
15 template <class... T>
16 struct FieldTraits<TupleVector<T...>>
17 {
18 using field_type = std::common_type_t<typename FieldTraits<T>::field_type...>;
19 using real_type = std::common_type_t<typename FieldTraits<T>::real_type...>;
20 };
21}
22
23namespace AMDiS
24{
25 namespace Impl
26 {
27 template <class Node, class R, class NodeTag>
28 struct RangeTypeImpl
29 {
30 static_assert( Dune::AlwaysFalse<NodeTag>::value, "Unknown node-type for range definition" );
31 };
32 }
33
36
45 template <class Node, class R = double>
46 using RangeType_t =
47 typename Impl::RangeTypeImpl<Node, R, typename Node::NodeTag>::type;
48
49
50 namespace Impl
51 {
52 // Leaf node
53 template <class Node, class R>
54 struct RangeTypeImpl<Node, R, Dune::TypeTree::LeafNodeTag>
55 {
56 using LocalBasis = typename Node::FiniteElement::Traits::LocalBasisType;
57 using T = typename LocalBasis::Traits::RangeType;
58 using type = remove_cvref_t<decltype(std::declval<R>() * std::declval<T>())>;
59 };
60
61 // Power node
62 template <class Node, class R>
63 struct RangeTypeImpl<Node, R, Dune::TypeTree::PowerNodeTag>
64 {
65 using ChildNode = typename Node::template Child<0>::type;
66
67 template <bool childIsLeaf, class ChildRangeType>
68 struct FlatType {
69 using type = Dune::FieldVector<ChildRangeType, int(Node::degree())>;
70 };
71
72 template <class T>
73 struct FlatType<true, Dune::FieldVector<T,1>> {
74 using type = Dune::FieldVector<T, int(Node::degree())>;
75 };
76
77 using type = typename FlatType<ChildNode::isLeaf, RangeType_t<ChildNode,R>>::type;
78 };
79
80 // Composite node
81 template <class Node, class R>
82 struct RangeTypeImpl<Node, R, Dune::TypeTree::CompositeNodeTag>
83 {
84 template <class Idx> struct RangeTypeGenerator;
85 template <std::size_t... I>
86 struct RangeTypeGenerator<Indices<I...>>
87 {
88 template <std::size_t J>
89 using ChildNode = typename Node::template Child<J>::type;
90 using type = Dune::TupleVector<RangeType_t<ChildNode<I>,R>...>;
91 };
92
93 using type = typename RangeTypeGenerator<std::make_index_sequence<std::size_t(Node::degree())>>::type;
94 };
95
96 } // end namespace Impl
97
98} // end namespace AMDiS