DUNE-ACFEM (unstable)

blockeye.hh
1#ifndef __DUNE_ACFEM_TENSORS_MODULES_BLOCKEYE_HH__
2#define __DUNE_ACFEM_TENSORS_MODULES_BLOCKEYE_HH__
3
4#include "../tensorbase.hh"
5#include "constant.hh"
6#include "eye.hh"
7
8namespace Dune {
9
10 namespace ACFem {
11
12 namespace Tensor {
13
22 template<std::size_t BlockRank, class BlockSignature, class Field = IntFraction<1> >
23 class BlockEye;
24
25 template<std::size_t BlockRank, class BlockSignature, class Field>
26 struct HasSpecializedExpressionTraits<BlockEye<BlockRank, BlockSignature, Field> >
27 : TrueType
28 {};
29
30 template<class T>
31 struct IsBlockEye
32 : FalseType
33 {};
34
35 template<class T>
36 struct IsBlockEye<T&>
37 : IsBlockEye<std::decay_t<T> >
38 {};
39
40 template<class T>
41 struct IsBlockEye<T&&>
42 : IsBlockEye<std::decay_t<T> >
43 {};
44
46 template<std::size_t BlockRank, class BlockSignature, class Field>
47 struct IsBlockEye<BlockEye<BlockRank, BlockSignature, Field> >
48 : TrueType
49 {};
50
51 template<class T, class SFINAE = void>
52 struct BlockEyeTraits
53 {
54 using ValueType = void;
55 static constexpr std::size_t blockRank_ = 0;
56 using BlockSignature = Seq<>;
57 static constexpr std::size_t blockSize_ = 0;
58 };
59
60 template<class T>
61 struct BlockEyeTraits<T, std::enable_if_t<!IsDecay<T>::value> >
62 : BlockEyeTraits<std::decay_t<T> >
63 {};
64
65 template<std::size_t Rank, class Signature, class Field>
66 struct BlockEyeTraits<BlockEye<Rank, Signature, Field> >
67 {
68 using ValueType = Field;
69 static constexpr std::size_t blockRank_ = Rank;
70 using BlockSignature = Signature;
71 static constexpr std::size_t blockSize_ = BlockSignature::size();
72 };
73
92 template<class Pos, std::size_t BlockRank, class Dims, class SFINAE = void>
93 constexpr inline bool IsBlockEyePositionsV = false;
94
95 template<std::size_t... P, std::size_t BlockRank, class Dims>
96 constexpr inline bool IsBlockEyePositionsV<Seq<P...>, BlockRank, Dims, std::enable_if_t<(sizeof...(P) % Dims::size() == 0)> > = std::is_same<
97 typename SortSequence<Seq<(P % Dims::size())...> >::Result,
98 MakeIndexSequence<Dims::size(), 0, 1, sizeof...(P) / Dims::size()> >::value;
99
111 template<std::size_t BlockRank, std::size_t... Dimensions, class Field>
112 class BlockEye<BlockRank, Seq<Dimensions...>, Field>
113 : public TensorBase<FloatingPointClosure<Field>, SequenceProd<BlockRank, Seq<Dimensions...> >,
114 BlockEye<BlockRank, Seq<Dimensions...>, Field> >
115 , public Expressions::SelfExpression<BlockEye<BlockRank, Seq<Dimensions...>, Field > >
116 , public MPL::UniqueTags<ConstantExpression,
117 ConditionalType<IsTypedValue<Field>::value, TypedValueExpression, void>
118 >
119 {
120 using BaseType = TensorBase<FloatingPointClosure<Field>, SequenceProd<BlockRank, Seq<Dimensions...> >,
121 BlockEye<BlockRank, Seq<Dimensions...>, Field> >;
122 static constexpr std::size_t blockSize_ = sizeof...(Dimensions);
123 public:
124 using BaseType::rank;
125 using typename BaseType::FieldType;
126 using typename BaseType::Signature;
127 using ValueType = Field;
128 using BlockSignature = Seq<Dimensions...>;
129 static constexpr std::size_t blockRank_ = BlockRank;
130
134 template<class... Dims,
135 std::enable_if_t<(sizeof...(Dims) == rank
136 &&
138 , int> = 0>
139 FieldType operator()(Dims... indices) const
140 {
141 bool isConstant = true;
142#if __GNUC__ <= 7 && !defined(__clang__)
143 const auto indexArray = std::array<std::size_t, sizeof...(Dims)>({{ (std::size_t)indices... }});
144 for (unsigned i = 0; i < blockSize_; ++i) {
145 const auto first = indexArray[i];
146 for (unsigned j = 1; j < BlockRank; ++j) {
147 const auto next = indexArray[i+j*blockSize_];
148 if (next != first) {
149 return FieldType(0);
150 }
151 }
152 }
153#else
154 // GCC does not like the following and catches an internal compiler error:
155 forLoop<blockSize_>([&](auto i) {
156 using I = decltype(i);
157 std::size_t first = get<I::value>(std::forward_as_tuple(indices...));
158 forEach(MakeIndexSequence<BlockRank-1, 1>{}, [&](auto j) {
159 using J = decltype(j);
160 std::size_t next = std::get<I::value+J::value*blockSize_>(std::forward_as_tuple(indices...));
161 if (next != first) {
162 isConstant = false;
163 }
164 });
165 });
166#endif
167 if (!isConstant) {
168 return FieldType(0);
170 return FieldType(ValueType{});
171 } else {
172 return FieldType(1);
173 }
174 }
175
177 template<std::size_t... Indices, std::enable_if_t<sizeof...(Indices) == rank, int> = 0>
178 decltype(auto) operator()(Seq<Indices...>) const
179 {
180 using ReturnType = ConditionalType<isZero<Indices...>(),
181 IntFraction<0>,
182 ConditionalType<IsTypedValue<ValueType>::value,
183 ValueType,
184 IntFraction<1> > >;
185 return ReturnType{};
186 }
187
188 private:
189 template<class Indices, class Pos>
190 struct IsZeroFunctor
191 {
192 // Get sequence of positions equal to index nr. N.*/
193 template<std::size_t N>
194 using PositionsOf = TransformSequence<
196
197 // The following must yield a constant sequence.
198 template<std::size_t N>
199 using IndexBlock = SequenceSlice<Indices, PositionsOf<N> >;
200
201 template<std::size_t N>
202 using ZeroMatch = BoolConstant<!isConstant(IndexBlock<N>{})>;
203 };
204
205 template<class Indices, class Pos, std::size_t... N>
206 static bool constexpr isZeroExpander(Indices, Pos, Seq<N...>)
207 {
208 return (... || (IsZeroFunctor<Indices, Pos>::template ZeroMatch<N>::value));
209 }
210
211 public:
212 template<std::size_t... Indices, class Pos = MakeIndexSequence<sizeof...(Indices)> >
213 static bool constexpr isZero(Seq<Indices...> = Seq<Indices...>{}, Pos = Pos{})
214 {
215 // Truncate Pos to size of Indices...
216 using RealPos = HeadPart<sizeof...(Indices), Pos>;
217
218 return isZeroExpander(Seq<Indices...>{}, RealPos{}, MakeSequenceFor<RealPos>{});
219 }
220
221 std::string name() const
222 {
223 return "blockEye<"+std::to_string(blockRank_)+"|"+toString(BlockSignature{})+">";
224 }
225 };
226
227 // blockEye<2>(TensorTraits<T>::signature())
228
230 template<std::size_t Rank, std::size_t... Dimensions, class F = Expressions::Closure>
231 auto blockEye(Seq<Dimensions...> = Seq<Dimensions...>{}, F closure = F{})
232 {
233 if constexpr (Rank > 0) {
234 if constexpr (sizeof...(Dimensions) == 1) {
235 return eye(MakeConstantSequence<Rank, Head<Seq<Dimensions...> >::value>{}, F{});
236 } else {
237 return closure(BlockEye<Rank, Seq<Dimensions...>, IntFraction<1> >{});
238 }
239 } else {
240 return constantTensor(1_f, Seq<>{}, F{});
241 }
242 }
243
245 template<std::size_t Rank, class T, class F = Expressions::Closure,
246 std::enable_if_t<!IsSequence<T>::value, int> = 0>
247 auto blockEye(T&&, F = F{})
248 {
249 return blockEye<Rank>(typename TensorTraits<T>::Signature{}, F{});
250 }
251
253
255
256 } // NS Tensor
257
258 template<class Field, std::size_t BlockRank, class BlockSignature>
259 struct ExpressionTraits<Tensor::BlockEye<BlockRank, BlockSignature, Field> >
260 : ExpressionTraits<Field>
261 {
262 private:
263 using BaseType = ExpressionTraits<Field>;
264 public:
265 using ExpressionType = Tensor::BlockEye<BlockRank, BlockSignature, Field>;
266 static constexpr bool isOne = BaseType::isOne && ExpressionType::rank == 0;
267 static constexpr bool isMinusOne = BaseType::isMinusOne && ExpressionType::rank == 0;
268 static constexpr bool isNonZero = BaseType::isNonZero && ExpressionType::rank == 0;
269 static constexpr bool isPositive = BaseType::isPositive && ExpressionType::rank == 0;
270 static constexpr bool isNegative = BaseType::isNegative && ExpressionType::rank == 0;
271 using Sign = ExpressionSign<isNonZero, BaseType::isSemiPositive, BaseType::isSemiNegative>;
272 };
273
274 } // NS ACFem
275
276 template<class Field, std::size_t N, class Signature>
277 struct FieldTraits<ACFem::Tensor::BlockEye<N, Signature, Field> >
278 : FieldTraits<std::decay_t<Field> >
279 {};
280
281} // NS Dune
282
283#endif // __DUNE_ACFEM_TENSORS_MODULES_BLOCKEYE_HH__
FieldType operator()(Dims... indices) const
Insert the current view-indices at their proper positions and foward to the underlying "host" tensor.
Definition: blockeye.hh:139
decltype(auto) operator()(Seq< Indices... >) const
Constant access with index sequence.
Definition: blockeye.hh:178
decltype(operate(std::declval< OptOrF >(), std::declval< Rest >()...)) ExpressionType
Generate the type of an expression by calling operate().
Definition: optimizationbase.hh:256
BoolConstant< ExpressionTraits< T >::isTypedValue > IsTypedValue
Compile-time true if T is a "typed value", e.g. a std::integral_constant.
Definition: expressiontraits.hh:90
typename GetHeadPartHelper< Cnt, Seq >::Type HeadPart
Extract Cnt many consecutive elements from the front of Seq.
Definition: access.hh:217
constexpr std::size_t size()
Gives the number of elements in tuple-likes and std::integer_sequence.
Definition: size.hh:73
MakeSequence< std::size_t, N, Offset, Stride, Repeat > MakeIndexSequence
Make a sequence of std::size_t elements.
Definition: generators.hh:34
MakeIndexSequence< N, Value, 0 > MakeConstantSequence
Generate a constant index sequence of the given size.
Definition: generators.hh:45
typename TransformSequenceHelper< SeqIn, SeqOut, TransformFunctor, AcceptFunctor >::Type TransformSequence
General sequence transformation alias.
Definition: transform.hh:172
typename SequenceProdHelper< N, Seq, Sequence< typename Seq::value_type > >::Type SequenceProd
Compute the "product" multi index of N identical copies.
Definition: transform.hh:252
auto blockEye(T &&, F=F{})
Return the blockEye with the block-signature taken from T.
Definition: blockeye.hh:247
constexpr bool IsBlockEyePositionsV
Definition: blockeye.hh:93
constexpr bool isConstant(Sequence< T, T0, Ts... >)
Definition: compare.hh:285
decltype(isIntegralPack(std::declval< T >()...)) IsIntegralPack
Decide whether the given parameter pack contains only integral types.
Definition: compare.hh:377
Constant< bool, V > BoolConstant
Short-cut for integral constant of type bool.
Definition: types.hh:48
BoolConstant< false > FalseType
Alias for std::false_type.
Definition: types.hh:110
BoolConstant< true > TrueType
Alias for std::true_type.
Definition: types.hh:107
STL namespace.
Accept if input-value MOD P = R.
Definition: transform.hh:511
Terminals may derive from this class to express that they are expressions.
Definition: terminal.hh:25
Index functor.
Definition: transform.hh:346
Base class for all tensors.
Definition: tensorbase.hh:144
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)