6#ifndef DUNE_ISTL_BLOCKLEVEL_HH
7#define DUNE_ISTL_BLOCKLEVEL_HH
12#include <dune/common/indices.hh>
13#include <dune/common/typetraits.hh>
14#include <dune/common/hybridutilities.hh>
23template<
typename... Args>
24class MultiTypeBlockVector;
25template<
typename FirstRow,
typename... Args>
26class MultiTypeBlockMatrix;
29namespace Dune {
namespace Impl {
32template<
typename T>
struct MaxBlockLevel;
33template<
typename T>
struct MinBlockLevel;
36template<
typename M,
template<
typename B>
typename BlockLevel,
typename Op>
37constexpr 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])>;
56template<
typename V,
template<
typename B>
typename BlockLevel,
typename Op>
57constexpr 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(); }
92template<
typename FirstRow,
typename... Args>
93struct 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);
104template<
typename FirstRow,
typename... Args>
105struct 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);
116template<
typename... Args>
117struct 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);
128template<
typename... Args>
129struct 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);
141struct MaxBlockLevel<
Dune::MultiTypeBlockVector<>>
143 static constexpr std::size_t value()
149struct MinBlockLevel<
Dune::MultiTypeBlockVector<>>
151 static constexpr std::size_t value()
162{
return Impl::MaxBlockLevel<T>::value(); }
167{
return Impl::MinBlockLevel<T>::value(); }
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