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
11namespace 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
STL namespace.
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.111.3 (Jul 15, 22:36, 2024)