1#ifndef __DUNE_ACFEM_TENSORS_BINDINGS_DUNE_FIELDTENSOR_HH__
2#define __DUNE_ACFEM_TENSORS_BINDINGS_DUNE_FIELDTENSOR_HH__
4#include <dune/common/fvector.hh>
5#include <dune/common/fmatrix.hh>
6#include <dune/common/hybridutilities.hh>
8#include "../../../expressions/terminal.hh"
9#include "../../tensorbase.hh"
10#include "../../operations/assign.hh"
11#include "../../optimization/policy.hh"
12#include "fieldvectortraits.hh"
13#include "densevectorview.hh"
22 class FieldVectorTensor
23 :
public TensorBase<typename FieldTraits<std::decay_t<FV> >::field_type,
24 FieldVectorSignature<FV>,
25 FieldVectorTensor<FV> >
26 ,
public Expressions::SelfExpression<FieldVectorTensor<FV> >
27 ,
public MPL::UniqueTags<ConditionalType<
28 !std::is_reference<FV>::value,
29 IndependentExpression,
32 using ThisType = FieldVectorTensor;
34 using ArrayType = std::decay_t<FV>;
35 using BaseType = TensorBase<typename FieldTraits<ArrayType>::field_type,
36 FieldVectorSignature<ArrayType>,
37 FieldVectorTensor<FV> >;
39 using typename BaseType::Signature;
40 using typename BaseType::FieldType;
49 template<class T, std::enable_if_t<SameDecay<T, ArrayType>::value,
int> = 0>
50 FieldVectorTensor(T&& t)
51 : data_(
std::forward<T>(t))
55 std::enable_if_t<(std::is_constructible<DataType, T>::value
56 && !SameDecay<T, ArrayType>::value
58 explicit FieldVectorTensor(T&& t)
59 : data_(
std::forward<T>(t))
63 template<
class Tensor,
64 std::enable_if_t<(IsTensor<Tensor>::value
65 && !Expressions::IsClosure<Tensor>::value
66 && !std::is_const<DataType>::value
67 && !std::is_same<Tensor, FieldVectorTensor>::value
68 && std::is_same<typename Tensor::Signature, Signature>::value
70 explicit FieldVectorTensor(
const Tensor& other)
71 : data_(DenseVectorView<const Tensor&>(other))
76 std::enable_if_t<(IsTensor<T>::value
77 && !RefersConst<DataType>::value
78 && std::is_same<Signature, typename TensorTraits<T>::Signature>::value),
80 FieldVectorTensor&
operator=(T&& other)
83 return assign(*
this, std::forward<T>(other), [](
auto& dst,
auto&& src) { dst = src; });
86 FieldVectorTensor& operator=(
const ArrayType& other)
92 template<
class... Dims,
93 std::enable_if_t<(
sizeof...(Dims) == rank
95 IsIntegralPack<Dims...>::value),
int> = 0>
96 decltype(
auto)
operator()(Dims... indices)
98 return value(data_, indices...);
101 template<
class... Dims,
102 std::enable_if_t<(
sizeof...(Dims) == rank
104 IsIntegralPack<Dims...>::value),
int> = 0>
105 const FieldType& operator()(Dims... indices)
const
107 return value(data_, indices...);
111 template<std::size_t... Indices, std::enable_if_t<
sizeof...(Indices) == rank,
int> = 0>
112 decltype(
auto)
constexpr operator()(Seq<Indices...>)
114 return (*
this)(Indices...);
118 template<std::size_t... Indices, std::enable_if_t<
sizeof...(Indices) == rank,
int> = 0>
119 decltype(
auto)
constexpr operator()(Seq<Indices...>)
const
121 return (*
this)(Indices...);
124 operator DataType () &&
129 operator ConditionalType<RefersConst<DataType>::value, DataType, ArrayType>& () &
134 operator const ArrayType& ()
const&
139 std::string name()
const
141 return "FT(" + refPrefix() + name<Signature>() +
")";
145 std::string refPrefix()
const
147 constexpr bool isRef = std::is_lvalue_reference<DataType>::value;
148 constexpr bool isConst = std::is_const<std::remove_reference_t<DataType> >::value;
150 return isRef ? (isConst ?
"cref" :
"ref") :
"";
153 template<
class Sig, std::enable_if_t<Sig::size() == 0,
int> = 0>
154 std::string name()
const
159 template<
class Sig, std::enable_if_t<Sig::size() == 1,
int> = 0>
160 std::string name()
const
165 template<
class Sig, std::enable_if_t<(Sig::size() > 1),
int> = 0>
166 std::string name()
const
172 FieldType& value(Data& data)
177 const FieldType& value(
const Data& data)
182 const FieldType& value(
const Data& data)
const
188 FieldType& value(FieldVector<FieldType, Dim>& data,
const std::size_t& index)
193 const FieldType& value(
const FieldVector<FieldType, Dim>& data,
const std::size_t& index)
198 const FieldType& value(
const FieldVector<FieldType, Dim>& data,
const std::size_t& index)
const
203 template<
int rows,
int cols>
204 FieldType& value(FieldMatrix<FieldType, rows, cols>& data,
const std::size_t& i,
const std::size_t& j)
208 template<
int rows,
int cols>
209 const FieldType& value(
const FieldMatrix<FieldType, rows, cols>& data,
const std::size_t& i,
const std::size_t& j)
213 template<
int rows,
int cols>
214 const FieldType& value(
const FieldMatrix<FieldType, rows, cols>& data,
const std::size_t& i,
const std::size_t& j)
const
219 template<
class Data,
class... Dims>
220 FieldType& value(Data& data,
const std::size_t& index0, Dims... rest)
222 return value(data[index0], rest...);
224 template<
class Data,
class... Dims>
225 const FieldType& value(
const Data& data,
const std::size_t& index0, Dims... rest)
227 return value(data[index0], rest...);
229 template<
class Data,
class... Dims>
230 const FieldType& value(
const Data& data,
const std::size_t& index0, Dims... rest)
const
232 return value(data[index0], rest...);
238 template<
class Field, std::size_t... Dimensions>
239 using FieldTensor = FieldVectorTensor<FieldVectorType<Field, Dimensions...> >;
243 template<
class Field,
class Seq>
244 struct MatchingFieldTensorHelper;
246 template<
class Field, std::size_t... Dimensions>
247 struct MatchingFieldTensorHelper<Field, Seq<Dimensions...> >
249 using Type = FieldTensor<Field, Dimensions...>;
254 using MatchingFieldTensor =
typename MatchingFieldTensorHelper<FloatingPointClosure<typename TensorTraits<T>::FieldType>,
typename TensorTraits<T>::Signature>::Type;
259 struct ScalarDecayFieldTensorHelper
261 using Type = FieldVectorTensor<FV>;
265 struct ScalarDecayFieldTensorHelper<FieldVector<Data, 1> >
267 using Type = FieldVectorTensor<Data>;
271 struct ScalarDecayFieldTensorHelper<Fem::ExplicitFieldVector<Data, 1> >
273 using Type = FieldVectorTensor<Data>;
276 template<
int NCols,
class Data>
277 struct ScalarDecayFieldTensorHelper<FieldMatrix<Data, 1, NCols> >
279 using Type = FieldVectorTensor<FieldVector<Data, NCols> >;
286 using ScalarDecayFieldTensor =
typename ScalarDecayFieldTensorHelper<FV>::Type;
288 template<
class T,
class SFINAE =
void>
289 struct IsFieldVectorTensor
294 struct IsFieldVectorTensor<T,
std::enable_if_t<!IsDecay<T>::value> >
295 : IsFieldVectorTensor<std::decay_t<T> >
299 struct IsFieldVectorTensor<FieldVectorTensor<FV> >
304 using IsFieldTensor = IsFieldVectorTensor<T>;
307 struct TensorTraits<FV,
std::enable_if_t<(IsFieldObject<FV>::value && IsDecay<FV>::value)> >
308 :
public TensorTraits<FieldVectorTensor<FV> >
311 static constexpr auto toTensor(T&& t)
313 return FieldVectorTensor<T>(std::forward<T>(t));
318 struct IsTensorOperand<FV,
std::enable_if_t<(IsFieldObject<FV>::value && IsDecay<FV>::value)> >
323 struct IsUnaryTensorOperand;
325 template<
class T1,
class T2,
class SFINAE>
326 struct AreBinaryTensorOperands;
332 template<
class T1,
class T2>
335 std::enable_if_t<(IsFieldObject<T1>::value
336 && IsFieldObject<T2>::value
337 && IsUnaryTensorOperand<T1>::value
338 && IsUnaryTensorOperand<T2>::value
348 struct FieldTraits<ACFem::Tensor::FieldVectorTensor<FV> >
349 : FieldTraits<std::decay_t<FV> >
auto & assign(T1 &t1, T2 &&t2)
Assign one tuple-alike to another by looping over the elements.
Definition: assign.hh:40
auto toString(Sequence< T, I0 >)
Generate a compact string representation as a comma separated list of the values, without spaces.
Definition: tostring.hh:28
BoolConstant< false > FalseType
Alias for std::false_type.
Definition: types.hh:110
BoolConstant< true > TrueType
Alias for std::true_type.
Definition: types.hh:107
Definition: expressiontraits.hh:67