6 #ifndef DUNE_ISTL_BLOCKLEVEL_HH
7 #define DUNE_ISTL_BLOCKLEVEL_HH
10 #include <type_traits>
12 #include <dune/common/indices.hh>
13 #include <dune/common/typetraits.hh>
14 #include <dune/common/hybridutilities.hh>
23 template<
typename... Args>
24 class MultiTypeBlockVector;
25 template<
typename FirstRow,
typename... Args>
26 class MultiTypeBlockMatrix;
29 namespace Dune {
namespace Impl {
32 template<
typename T>
struct MaxBlockLevel;
33 template<
typename T>
struct MinBlockLevel;
36 template<
typename M,
template<
typename B>
typename BlockLevel,
typename Op>
37 constexpr std::size_t blockLevelMultiTypeBlockMatrix(
const Op& op)
40 using namespace Dune::Indices;
41 using Block00 =
typename std::decay_t<decltype(std::declval<M>()[_0][_0])>;
42 std::size_t
blockLevel = BlockLevel<Block00>::value() + 1;
44 using namespace Dune::Hybrid;
45 forEach(integralRange(index_constant<M::N()>()), [&](
auto&& i) {
46 using namespace Dune::Hybrid;
47 forEach(integralRange(index_constant<M::M()>()), [&](
auto&& j) {
48 using Block =
typename std::decay_t<decltype(std::declval<M>()[i][j])>;
56 template<
typename V,
template<
typename B>
typename BlockLevel,
typename Op>
57 constexpr std::size_t blockLevelMultiTypeBlockVector(
const Op& op)
60 using namespace Dune::Indices;
61 using Block0 =
typename std::decay_t<decltype(std::declval<V>()[_0])>;
62 std::size_t
blockLevel = BlockLevel<Block0>::value() + 1;
64 using namespace Dune::Hybrid;
65 forEach(integralRange(index_constant<V::size()>()), [&](
auto&& i) {
66 using Block =
typename std::decay_t<decltype(std::declval<V>()[i])>;
75 static constexpr std::size_t value(){
76 if constexpr (IsNumber<T>::value)
79 return MaxBlockLevel<typename T::block_type>::value() + 1;
87 static constexpr std::size_t value()
88 {
return MaxBlockLevel<T>::value(); }
92 template<
typename FirstRow,
typename... Args>
93 struct MaxBlockLevel<
Dune::MultiTypeBlockMatrix<FirstRow, Args...>>
95 static constexpr std::size_t value()
97 using M = MultiTypeBlockMatrix<FirstRow, Args...>;
98 constexpr
auto max = [](
const auto& a,
const auto& b){
return std::max(a,b); };
99 return blockLevelMultiTypeBlockMatrix<M, MaxBlockLevel>(max);
104 template<
typename FirstRow,
typename... Args>
105 struct MinBlockLevel<
Dune::MultiTypeBlockMatrix<FirstRow, Args...>>
107 static constexpr std::size_t value()
109 using M = MultiTypeBlockMatrix<FirstRow, Args...>;
110 constexpr
auto min = [](
const auto& a,
const auto& b){
return std::min(a,b); };
111 return blockLevelMultiTypeBlockMatrix<M, MinBlockLevel>(min);
116 template<
typename... Args>
117 struct MaxBlockLevel<
Dune::MultiTypeBlockVector<Args...>>
119 static constexpr std::size_t value()
121 using V = MultiTypeBlockVector<Args...>;
122 constexpr
auto max = [](
const auto& a,
const auto& b){
return std::max(a,b); };
123 return blockLevelMultiTypeBlockVector<V, MaxBlockLevel>(max);
128 template<
typename... Args>
129 struct MinBlockLevel<
Dune::MultiTypeBlockVector<Args...>>
131 static constexpr std::size_t value()
133 using V = MultiTypeBlockVector<Args...>;
134 constexpr
auto min = [](
const auto& a,
const auto& b){
return std::min(a,b); };
135 return blockLevelMultiTypeBlockVector<V, MinBlockLevel>(min);
141 struct MaxBlockLevel<
Dune::MultiTypeBlockVector<>>
143 static constexpr std::size_t value()
149 struct MinBlockLevel<
Dune::MultiTypeBlockVector<>>
151 static constexpr std::size_t value()
162 {
return Impl::MaxBlockLevel<T>::value(); }
167 {
return Impl::MinBlockLevel<T>::value(); }
172 {
return maxBlockLevel<T>() == minBlockLevel<T>(); }
178 static_assert(hasUniqueBlockLevel<T>(),
"Block level cannot be uniquely determined!");
179 return Impl::MaxBlockLevel<T>::value();
Definition: allocator.hh:11
constexpr bool hasUniqueBlockLevel()
Determine if a vector/matrix has a uniquely determinable block level.
Definition: blocklevel.hh:171
constexpr std::size_t maxBlockLevel()
Determine the maximum block level of a possibly nested vector/matrix type.
Definition: blocklevel.hh:161
constexpr std::size_t blockLevel()
Determine the block level of a possibly nested vector/matrix type.
Definition: blocklevel.hh:176
constexpr std::size_t minBlockLevel()
Determine the minimum block level of a possibly nested vector/matrix type.
Definition: blocklevel.hh:166