1#ifndef __DUNE_ACFEM_TENSORS_MODULES_LINEARSTORAGE_HH__
2#define __DUNE_ACFEM_TENSORS_MODULES_LINEARSTORAGE_HH__
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"
17 using ACFem::operator<<;
18 using Dune::operator<<;
29 template<
class Container,
class Signature>
32 template<
class T,
class SFINAE =
void>
33 struct IsLinearStorageTensor
38 struct IsLinearStorageTensor<T,
std::enable_if_t<!IsDecay<T>::value> >
39 : IsLinearStorageTensor<std::decay_t<T> >
42 template<
class Container,
class Signature>
43 struct IsLinearStorageTensor<LinearStorageTensor<Container, Signature> >
49 template<
class Container, std::size_t... Dimensions>
51 :
public TensorBase<typename std::decay_t<Container>::value_type, Seq<Dimensions...>, LinearStorageTensor<Container, Seq<Dimensions...> > >
53 ,
public MPL::UniqueTags<ConditionalType<IsConstantExprArg<Container>::value, ConstantExpression, void> >
60 using typename BaseType::FieldType;
61 using typename BaseType::Signature;
64 template<class Arg, std::enable_if_t<std::is_constructible<Container, Arg>::value,
int> = 0 >
66 : data_(std::forward<Arg>(data))
71 assert(data_.size() == dim());
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 >
80 assert(data_.size() == dim());
81 assert(list.size() == dim());
96 assert(data_.size() == dim());
103 LinearStorageTensor(LinearStorageTensor&& other)
104 : data_(
std::move(other).data_)
106 assert(data_.size() == dim());
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
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),
130 forLoop<dim()>([&](
auto i) {
131 data_[i.value] = other(
multiIndex(Signature{}, i));
140 template<
class... Indices,
141 std::enable_if_t<(
sizeof...(Indices) == rank
145 constexpr decltype(
auto)
operator()(Indices... indices)
155 template<
class... Indices,
156 std::enable_if_t<(
sizeof...(Indices) == rank
160 constexpr decltype(
auto)
operator()(Indices... indices)
const
168 template<std::size_t... Indices,
169 std::enable_if_t<
sizeof...(Indices) == rank,
int> = 0>
172 static_assert(
sizeof...(Indices) == rank,
"Number of indices differs from tensor rank.");
173 return (*
this)(Indices...);
177 template<std::size_t... Indices,
178 std::enable_if_t<
sizeof...(Indices) == rank,
int> = 0>
181 static_assert(
sizeof...(Indices) == rank,
"Number of indices differs from tensor rank.");
182 return (*
this)(Indices...);
185 std::string name()
const
187 return "LST(" + refPrefix() + name<Signature>() +
")";
191 std::string refPrefix()
const
193 constexpr bool isRef = std::is_lvalue_reference<Container>::value;
194 constexpr bool isConst = std::is_const<std::remove_reference_t<Container> >::value;
196 return isRef ? (isConst ?
"cref" :
"ref") :
"";
199 template<
class Sig, std::enable_if_t<Sig::size() == 0,
int> = 0>
200 std::string name()
const
202 return toString(data_);
205 template<
class Sig, std::enable_if_t<Sig::size() == 1,
int> = 0>
206 std::string name()
const
208 return "[" + toString(data_) +
"]";
211 template<
class Sig, std::enable_if_t<(Sig::size() > 1),
int> = 0>
212 std::string name()
const
214 return "<" + toString(Sig{}) +
">";
220 template<std::size_t... Dimensions,
class T>
221 auto linearStorageTensor(T&& t, Seq<Dimensions...> = Seq<Dimensions...>{})
223 return expressionClosure(LinearStorageTensor<T, Seq<Dimensions...> >(std::forward<T>(t)));
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> >
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
Base class for all tensors.
Definition: tensorbase.hh:144