DUNE PDELab (2.8)

blocklevel.hh
Go to the documentation of this file.
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3
4#ifndef DUNE_ISTL_BLOCKLEVEL_HH
5#define DUNE_ISTL_BLOCKLEVEL_HH
6
7#include <algorithm>
8#include <type_traits>
9
10#include <dune/common/indices.hh>
12#include <dune/common/hybridutilities.hh>
13
19// forward declaration
20namespace Dune {
21template<typename... Args>
22class MultiTypeBlockVector;
23template<typename FirstRow, typename... Args>
24class MultiTypeBlockMatrix;
25} // end namespace Dune
26
27namespace Dune::Impl {
28
29// forward declaration
30template<typename T> struct MaxBlockLevel;
31template<typename T> struct MinBlockLevel;
32
34template<typename M, template<typename B> typename BlockLevel, typename Op>
35constexpr std::size_t blockLevelMultiTypeBlockMatrix(const Op& op)
36{
37 // inialize with zeroth diagonal block
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;
41 // iterate over all blocks to determine min/max block level
42 using namespace Dune::Hybrid;
43 forEach(integralRange(index_constant<M::N()>()), [&](auto&& i) {
44 using namespace Dune::Hybrid; // needed for icc, see issue #31
45 forEach(integralRange(index_constant<M::M()>()), [&](auto&& j) {
46 using Block = typename std::decay_t<decltype(std::declval<M>()[i][j])>;
47 blockLevel = op(blockLevel, BlockLevel<Block>::value() + 1);
48 });
49 });
50 return blockLevel;
51}
52
54template<typename V, template<typename B> typename BlockLevel, typename Op>
55constexpr std::size_t blockLevelMultiTypeBlockVector(const Op& op)
56{
57 // inialize with zeroth block
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;
61 // iterate over all blocks to determine min/max block level
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])>;
65 blockLevel = op(blockLevel, BlockLevel<Block>::value() + 1);
66 });
67 return blockLevel;
68}
69
70template<typename T>
71struct MaxBlockLevel
72{
73 static constexpr std::size_t value(){
74 if constexpr (IsNumber<T>::value)
75 return 0;
76 else
77 return MaxBlockLevel<typename T::block_type>::value() + 1;
78 }
79};
80
81template<typename T>
82struct MinBlockLevel
83{
84 // the default implementation assumes minBlockLevel == maxBlockLevel
85 static constexpr std::size_t value()
86 { return MaxBlockLevel<T>::value(); }
87};
88
89// max block level for MultiTypeBlockMatrix
90template<typename FirstRow, typename... Args>
91struct MaxBlockLevel<MultiTypeBlockMatrix<FirstRow, Args...>>
92{
93 static constexpr std::size_t value()
94 {
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);
98 }
99};
100
101// min block level for MultiTypeBlockMatrix
102template<typename FirstRow, typename... Args>
103struct MinBlockLevel<MultiTypeBlockMatrix<FirstRow, Args...>>
104{
105 static constexpr std::size_t value()
106 {
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);
110 }
111};
112
113// max block level for MultiTypeBlockVector
114template<typename... Args>
115struct MaxBlockLevel<MultiTypeBlockVector<Args...>>
116{
117 static constexpr std::size_t value()
118 {
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);
122 }
123};
124
125// min block level for MultiTypeBlockVector
126template<typename... Args>
127struct MinBlockLevel<MultiTypeBlockVector<Args...>>
128{
129 static constexpr std::size_t value()
130 {
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);
134 }
135};
136
137// special case: empty MultiTypeBlockVector
138template<>
139struct MaxBlockLevel<MultiTypeBlockVector<>>
140{
141 static constexpr std::size_t value()
142 { return 0; };
143};
144
145// special case: empty MultiTypeBlockVector
146template<>
147struct MinBlockLevel<MultiTypeBlockVector<>>
148{
149 static constexpr std::size_t value()
150 { return 0; };
151};
152
153} // end namespace Dune::Impl
154
155namespace Dune {
156
158template<typename T>
159constexpr std::size_t maxBlockLevel()
160{ return Impl::MaxBlockLevel<T>::value(); }
161
163template<typename T>
164constexpr std::size_t minBlockLevel()
165{ return Impl::MinBlockLevel<T>::value(); }
166
168template<typename T>
169constexpr bool hasUniqueBlockLevel()
170{ return maxBlockLevel<T>() == minBlockLevel<T>(); }
171
173template<typename T>
174constexpr std::size_t blockLevel()
175{
176 static_assert(hasUniqueBlockLevel<T>(), "Block level cannot be uniquely determined!");
177 return Impl::MaxBlockLevel<T>::value();
178}
179
180} // end namespace Dune
181
182#endif
A Matrix class to support different block types.
Definition: multitypeblockmatrix.hh:44
A Vector class to support different block types.
Definition: multitypeblockvector.hh:56
Traits for type conversions and type information.
constexpr index_constant< 0 > _0
Compile time index with value 0.
Definition: indices.hh:51
std::integral_constant< std::size_t, i > index_constant
An index constant with value i.
Definition: indices.hh:28
constexpr void forEach(Range &&range, F &&f)
Range based for loop.
Definition: hybridutilities.hh:266
constexpr auto integralRange(const Begin &begin, const End &end)
Create an integral range.
Definition: hybridutilities.hh:182
auto min(ADLTag< 0 >, const V &v1, const V &v2)
implements binary Simd::min()
Definition: defaults.hh:87
auto max(ADLTag< 0 >, const V &v1, const V &v2)
implements binary Simd::max()
Definition: defaults.hh:79
Namespace with predefined compile time indices for the range [0,19].
Definition: indices.hh:49
Dune namespace.
Definition: alignedallocator.hh:11
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
Whether this type acts as a scalar in the context of (hierarchically blocked) containers.
Definition: typetraits.hh:194
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 24, 22:29, 2024)