DUNE-ACFEM (unstable)

linearstorage.hh
1 #ifndef __DUNE_ACFEM_TENSORS_MODULES_LINEARSTORAGE_HH__
2 #define __DUNE_ACFEM_TENSORS_MODULES_LINEARSTORAGE_HH__
3 
4 #include <initializer_list>
5 #include "../../common/fractionconstant.hh"
6 #include "../../common/ostream.hh"
7 #include "../../expressions/terminal.hh"
8 #include "../tensorbase.hh"
9 #include "../bindings.hh"
10 
11 namespace Dune {
12 
13  namespace ACFem {
14 
15  namespace Tensor {
16 
17  using ACFem::operator<<;
18  using Dune::operator<<;
19 
29  template<class Container, class Signature>
31 
32  template<class T, class SFINAE = void>
33  struct IsLinearStorageTensor
34  : FalseType
35  {};
36 
37  template<class T>
38  struct IsLinearStorageTensor<T, std::enable_if_t<!IsDecay<T>::value> >
39  : IsLinearStorageTensor<std::decay_t<T> >
40  {};
41 
42  template<class Container, class Signature>
43  struct IsLinearStorageTensor<LinearStorageTensor<Container, Signature> >
44  : TrueType
45  {};
46 
47 
49  template<class Container, std::size_t... Dimensions>
50  class LinearStorageTensor<Container, Seq<Dimensions...> >
51  : public TensorBase<typename std::decay_t<Container>::value_type, Seq<Dimensions...>, LinearStorageTensor<Container, Seq<Dimensions...> > >
52  , public Expressions::SelfExpression<LinearStorageTensor<Container, Seq<Dimensions...> > >
53  , public MPL::UniqueTags<ConditionalType<IsConstantExprArg<Container>::value, ConstantExpression, void> >
54  {
56  using BaseType = TensorBase<typename std::decay_t<Container>::value_type, Seq<Dimensions...>, LinearStorageTensor<Container, Seq<Dimensions...> > >;
57  public:
58  using BaseType::rank;
59  using BaseType::dim;
60  using typename BaseType::FieldType;
61  using typename BaseType::Signature;
62 
63  // This really should not take part in implicit type conversions.
64  template<class Arg, std::enable_if_t<std::is_constructible<Container, Arg>::value, int> = 0 >
65  explicit LinearStorageTensor(Arg&& data)
66  : data_(std::forward<Arg>(data))
67  {
68  if constexpr (HasResize<Container>::value) {
69  data_.resize(dim());
70  }
71  assert(data_.size() == dim());
72  }
73 
74  template<class T, std::enable_if_t<std::is_constructible<FieldType, T>::value && !std::is_constructible<Container, std::initializer_list<T> >::value, int> = 0 >
75  LinearStorageTensor(std::initializer_list<T> list)
76  {
77  if constexpr (HasResize<Container>::value) {
78  data_.resize(dim());
79  }
80  assert(data_.size() == dim());
81  assert(list.size() == dim());
82  int i =0;
83  for(T el : list )
84  {
85  data_[i] = el;
86  ++i;
87  }
88  }
89 
92  {
93  if constexpr (HasResize<Container>::value) {
94  data_.resize(dim());
95  }
96  assert(data_.size() == dim());
97  }
98 
100  : data_(other.data_)
101  {}
102 
103  LinearStorageTensor(LinearStorageTensor&& other)
104  : data_(std::move(other).data_)
105  {
106  assert(data_.size() == dim());
107  }
108 
110  template<class Tensor,
111  std::enable_if_t<(IsTensor<Tensor>::value
112  && !RefersConst<Container>::value
113  && !std::is_same<Tensor, LinearStorageTensor>::value
114  && std::is_same<typename Tensor::Signature, Signature>::value
115  ), int> = 0>
116  explicit LinearStorageTensor(const Tensor& other)
117  {
118  (*this) = other;
119  }
120 
122  template<class T,
123  std::enable_if_t<(IsTensor<T>::value
125  && !std::is_same<T, LinearStorageTensor>::value
126  && std::is_same<Signature, typename TensorTraits<T>::Signature>::value),
127  int> = 0>
128  LinearStorageTensor& operator=(T&& other)
129  {
130  forLoop<dim()>([&](auto i) {
131  data_[i.value] = other(multiIndex(Signature{}, i));
132  //std::clog << "i " << i.value << " <- " << multiIndex(Signature{}, i) << std::endl;
133  });
134  return *this;
135  }
136 
140  template<class... Indices,
141  std::enable_if_t<(sizeof...(Indices) == rank
142  &&
144  , int> = 0>
145  constexpr decltype(auto) operator()(Indices... indices)
146  {
147  const std::size_t index = flattenMultiIndex(IndexSequence<Dimensions...>{}, indices...);
148  //std::clog << "index " << index << " <- " << std::array<std::size_t, rank>({{ (std::size_t)indices... }}) << std::endl;
149  return data_[index];
150  }
151 
155  template<class... Indices,
156  std::enable_if_t<(sizeof...(Indices) == rank
157  &&
159  , int> = 0>
160  constexpr decltype(auto) operator()(Indices... indices) const
161  {
162  const std::size_t index = flattenMultiIndex(IndexSequence<Dimensions...>{}, indices...);
163  //std::clog << "index " << index << " <- " << std::array<std::size_t, rank>({{ (std::size_t)indices... }}) << std::endl;
164  return data_[index];
165  }
166 
168  template<std::size_t... Indices,
169  std::enable_if_t<sizeof...(Indices) == rank, int> = 0>
170  decltype(auto) constexpr operator()(Seq<Indices...>) const
171  {
172  static_assert(sizeof...(Indices) == rank, "Number of indices differs from tensor rank.");
173  return (*this)(Indices...);
174  }
175 
177  template<std::size_t... Indices,
178  std::enable_if_t<sizeof...(Indices) == rank, int> = 0>
179  decltype(auto) constexpr operator()(Seq<Indices...>)
180  {
181  static_assert(sizeof...(Indices) == rank, "Number of indices differs from tensor rank.");
182  return (*this)(Indices...);
183  }
184 
185  std::string name() const
186  {
187  return "LST(" + refPrefix() + name<Signature>() + ")";
188  }
189 
190  private:
191  std::string refPrefix() const
192  {
193  constexpr bool isRef = std::is_lvalue_reference<Container>::value;
194  constexpr bool isConst = std::is_const<std::remove_reference_t<Container> >::value;
195 
196  return isRef ? (isConst ? "cref" : "ref") : "";
197  }
198 
199  template<class Sig, std::enable_if_t<Sig::size() == 0, int> = 0>
200  std::string name() const
201  {
202  return toString(data_);
203  }
204 
205  template<class Sig, std::enable_if_t<Sig::size() == 1, int> = 0>
206  std::string name() const
207  {
208  return "[" + toString(data_) + "]";
209  }
210 
211  template<class Sig, std::enable_if_t<(Sig::size() > 1), int> = 0>
212  std::string name() const
213  {
214  return "<" + toString(Sig{}) + ">";
215  }
216 
217  Container data_;
218  };
219 
220  template<std::size_t... Dimensions, class T>
221  auto linearStorageTensor(T&& t, Seq<Dimensions...> = Seq<Dimensions...>{})
222  {
223  return expressionClosure(LinearStorageTensor<T, Seq<Dimensions...> >(std::forward<T>(t)));
224  }
225 
227 
229 
230  } // NS Tensor
231 
232  } // NS ACFem
233 
234  template<class Container, class Signature>
235  struct FieldTraits<ACFem::Tensor::LinearStorageTensor<Container, Signature> >
236  : FieldTraits<std::decay_t<typename std::decay_t<Container>::value_type> >
237  {};
238 
239 } // NS Dune
240 
241 #endif // __DUNE_ACFEM_TENSORS_MODULES_LINEARSTORAGE_HH__
decltype(auto) constexpr operator()(Seq< Indices... >) const
Constant access from index-sequence.
Definition: linearstorage.hh:170
LinearStorageTensor(const Tensor &other)
Copy from any other tensor.
Definition: linearstorage.hh:116
LinearStorageTensor()
Allow default construction.
Definition: linearstorage.hh:91
decltype(auto) constexpr operator()(Seq< Indices... >)
Constant access from index-sequence.
Definition: linearstorage.hh:179
A tensor wrapping an object with an operator[].
Definition: linearstorage.hh:30
constexpr decltype(auto) expressionClosure(T &&t)
Do-nothing default implementation for pathologic cases.
Definition: interface.hh:93
decltype(isIntegralPack(std::declval< T >()...)) IsIntegralPack
Decide whether the given parameter pack contains only integral types.
Definition: compare.hh:377
Sequence< std::size_t, V... > IndexSequence
Sequence of std::size_t values.
Definition: types.hh:64
BoolConstant<(std::is_const< T >::value||std::is_const< std::remove_reference_t< T > >::value)> RefersConst
TrueType if const or a reference to a const.
Definition: types.hh:133
BoolConstant< false > FalseType
Alias for std::false_type.
Definition: types.hh:110
BoolConstant< true > TrueType
Alias for std::true_type.
Definition: types.hh:107
constexpr auto multiIndex(IndexSequence< Dims... >, IndexConstant< I >=IndexConstant< I >{})
Generate the multi-index corresponding to the flattened index I where the multiindex varies between t...
Definition: multiindex.hh:60
constexpr std::size_t flattenMultiIndex(Dims, const std::array< std::size_t, N > &indices)
Flatten run-time variable std::array.
Definition: multiindex.hh:111
Terminals may derive from this class to express that they are expressions.
Definition: terminal.hh:25
Definition: types.hh:422
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 7, 22:32, 2024)