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 
8 namespace 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);
169  } else if (IsTypedValue<ValueType>::value) {
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
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.80.0 (May 15, 22:30, 2024)