Skip to content
Snippets Groups Projects
Commit 9d4726b2 authored by Timo Koch's avatar Timo Koch
Browse files

[blocklevel] Make blockLevel work for vectors too

parent 8cb65bf9
No related branches found
No related tags found
No related merge requests found
......@@ -13,11 +13,13 @@
/*!
* \file
* \brief Helper functions for determining the matrix block level
* \brief Helper functions for determining the vector/matrix block level
*/
// forward declaration
namespace Dune {
template<typename... Args>
class MultiTypeBlockVector;
template<typename FirstRow, typename... Args>
class MultiTypeBlockMatrix;
} // end namespace Dune
......@@ -48,6 +50,23 @@ constexpr std::size_t blockLevelMultiTypeBlockMatrix(const Op& op)
return blockLevel;
}
//! recursively determine block level of a MultiTypeBlockVector
template<typename V, template<typename B> typename BlockLevel, typename Op>
constexpr std::size_t blockLevelMultiTypeBlockVector(const Op& op)
{
// inialize with zeroth block
using namespace Dune::Indices;
using Block0 = typename std::decay_t<decltype(std::declval<V>()[_0])>;
std::size_t blockLevel = BlockLevel<Block0>::value() + 1;
// iterate over all blocks to determine min/max block level
using namespace Dune::Hybrid;
forEach(integralRange(index_constant<V::size()>()), [&](auto&& i) {
using Block = typename std::decay_t<decltype(std::declval<V>()[i])>;
blockLevel = op(blockLevel, BlockLevel<Block>::value() + 1);
});
return blockLevel;
}
template<typename T>
struct MaxBlockLevel
{
......@@ -91,26 +110,66 @@ struct MinBlockLevel<MultiTypeBlockMatrix<FirstRow, Args...>>
}
};
// max block level for MultiTypeBlockVector
template<typename... Args>
struct MaxBlockLevel<MultiTypeBlockVector<Args...>>
{
static constexpr std::size_t value()
{
using V = MultiTypeBlockVector<Args...>;
constexpr auto max = [](const auto& a, const auto& b){ return std::max(a,b); };
return blockLevelMultiTypeBlockVector<V, MaxBlockLevel>(max);
}
};
// min block level for MultiTypeBlockVector
template<typename... Args>
struct MinBlockLevel<MultiTypeBlockVector<Args...>>
{
static constexpr std::size_t value()
{
using V = MultiTypeBlockVector<Args...>;
constexpr auto min = [](const auto& a, const auto& b){ return std::min(a,b); };
return blockLevelMultiTypeBlockVector<V, MinBlockLevel>(min);
}
};
// special case: empty MultiTypeBlockVector
template<>
struct MaxBlockLevel<MultiTypeBlockVector<>>
{
static constexpr std::size_t value()
{ return 0; };
};
// special case: empty MultiTypeBlockVector
template<>
struct MinBlockLevel<MultiTypeBlockVector<>>
{
static constexpr std::size_t value()
{ return 0; };
};
} // end namespace Dune::Impl
namespace Dune {
//! Determine the maximum block level of a possibly nested matrix type
//! Determine the maximum block level of a possibly nested vector/matrix type
template<typename T>
constexpr std::size_t maxBlockLevel()
{ return Impl::MaxBlockLevel<T>::value(); }
//! Determine the minimum block level of a possibly nested matrix type
//! Determine the minimum block level of a possibly nested vector/matrix type
template<typename T>
constexpr std::size_t minBlockLevel()
{ return Impl::MinBlockLevel<T>::value(); }
//! Determine if a matrix has a uniquely determinable block level
//! Determine if a vector/matrix has a uniquely determinable block level
template<typename T>
constexpr bool hasUniqueBlockLevel()
{ return maxBlockLevel<T>() == minBlockLevel<T>(); }
//! Determine the block level of a possibly nested matrix type
//! Determine the block level of a possibly nested vector/matrix type
template<typename T>
constexpr std::size_t blockLevel()
{
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment