4 #ifndef DUNE_ISTL_BLOCKLEVEL_HH
5 #define DUNE_ISTL_BLOCKLEVEL_HH
10 #include <dune/common/indices.hh>
11 #include <dune/common/typetraits.hh>
12 #include <dune/common/hybridutilities.hh>
21 template<
typename... Args>
22 class MultiTypeBlockVector;
23 template<
typename FirstRow,
typename... Args>
24 class MultiTypeBlockMatrix;
27 namespace Dune::Impl {
30 template<
typename T>
struct MaxBlockLevel;
31 template<
typename T>
struct MinBlockLevel;
34 template<
typename M,
template<
typename B>
typename BlockLevel,
typename Op>
35 constexpr std::size_t blockLevelMultiTypeBlockMatrix(
const Op& op)
38 using namespace Dune::Indices;
39 using Block00 =
typename std::decay_t<decltype(std::declval<M>()[_0][_0])>;
40 std::size_t
blockLevel = BlockLevel<Block00>::value() + 1;
42 using namespace Dune::Hybrid;
43 forEach(integralRange(index_constant<M::N()>()), [&](
auto&& i) {
44 using namespace Dune::Hybrid;
45 forEach(integralRange(index_constant<M::M()>()), [&](
auto&& j) {
46 using Block =
typename std::decay_t<decltype(std::declval<M>()[i][j])>;
54 template<
typename V,
template<
typename B>
typename BlockLevel,
typename Op>
55 constexpr std::size_t blockLevelMultiTypeBlockVector(
const Op& op)
58 using namespace Dune::Indices;
59 using Block0 =
typename std::decay_t<decltype(std::declval<V>()[_0])>;
60 std::size_t
blockLevel = BlockLevel<Block0>::value() + 1;
62 using namespace Dune::Hybrid;
63 forEach(integralRange(index_constant<V::size()>()), [&](
auto&& i) {
64 using Block =
typename std::decay_t<decltype(std::declval<V>()[i])>;
73 static constexpr std::size_t value(){
74 if constexpr (IsNumber<T>::value)
77 return MaxBlockLevel<typename T::block_type>::value() + 1;
85 static constexpr std::size_t value()
86 {
return MaxBlockLevel<T>::value(); }
90 template<
typename FirstRow,
typename... Args>
91 struct MaxBlockLevel<MultiTypeBlockMatrix<FirstRow, Args...>>
93 static constexpr std::size_t value()
95 using M = MultiTypeBlockMatrix<FirstRow, Args...>;
96 constexpr
auto max = [](
const auto& a,
const auto& b){
return std::max(a,b); };
97 return blockLevelMultiTypeBlockMatrix<M, MaxBlockLevel>(max);
102 template<
typename FirstRow,
typename... Args>
103 struct MinBlockLevel<MultiTypeBlockMatrix<FirstRow, Args...>>
105 static constexpr std::size_t value()
107 using M = MultiTypeBlockMatrix<FirstRow, Args...>;
108 constexpr
auto min = [](
const auto& a,
const auto& b){
return std::min(a,b); };
109 return blockLevelMultiTypeBlockMatrix<M, MinBlockLevel>(min);
114 template<
typename... Args>
115 struct MaxBlockLevel<MultiTypeBlockVector<Args...>>
117 static constexpr std::size_t value()
119 using V = MultiTypeBlockVector<Args...>;
120 constexpr
auto max = [](
const auto& a,
const auto& b){
return std::max(a,b); };
121 return blockLevelMultiTypeBlockVector<V, MaxBlockLevel>(max);
126 template<
typename... Args>
127 struct MinBlockLevel<MultiTypeBlockVector<Args...>>
129 static constexpr std::size_t value()
131 using V = MultiTypeBlockVector<Args...>;
132 constexpr
auto min = [](
const auto& a,
const auto& b){
return std::min(a,b); };
133 return blockLevelMultiTypeBlockVector<V, MinBlockLevel>(min);
139 struct MaxBlockLevel<MultiTypeBlockVector<>>
141 static constexpr std::size_t value()
147 struct MinBlockLevel<MultiTypeBlockVector<>>
149 static constexpr std::size_t value()
160 {
return Impl::MaxBlockLevel<T>::value(); }
165 {
return Impl::MinBlockLevel<T>::value(); }
170 {
return maxBlockLevel<T>() == minBlockLevel<T>(); }
176 static_assert(hasUniqueBlockLevel<T>(),
"Block level cannot be uniquely determined!");
177 return Impl::MaxBlockLevel<T>::value();
Definition: allocator.hh:9
constexpr bool hasUniqueBlockLevel()
Determine if a vector/matrix has a uniquely determinable block level.
Definition: blocklevel.hh:169
constexpr std::size_t maxBlockLevel()
Determine the maximum block level of a possibly nested vector/matrix type.
Definition: blocklevel.hh:159
constexpr std::size_t blockLevel()
Determine the block level of a possibly nested vector/matrix type.
Definition: blocklevel.hh:174
constexpr std::size_t minBlockLevel()
Determine the minimum block level of a possibly nested vector/matrix type.
Definition: blocklevel.hh:164