1#ifndef __DUNE_ACFEM_TENSORS_OPERATIONS_RESTRICTION_HH__
2#define __DUNE_ACFEM_TENSORS_OPERATIONS_RESTRICTION_HH__
4#include "../../expressions/storage.hh"
5#include "../../expressions/operationtraits.hh"
6#include "../../mpl/insertat.hh"
7#include "../../mpl/toarray.hh"
8#include "../tensorbase.hh"
9#include "../expressiontraits.hh"
10#include "restrictiondetail.hh"
17 template<
class Dims,
class Pivot>
18 struct RestrictionOperation;
52 template<
class Tensor,
class Dims,
class Indices = Seq<> >
56 template<
class Tensor, std::size_t... IndexPositions, std::size_t... PivotIndices>
57 class Restriction<Tensor, Seq<IndexPositions...>, Seq<PivotIndices...> >
58 :
public TensorBase<typename TensorTraits<Tensor>::FieldType,
59 ACFem::SubSequenceComplement<typename TensorTraits<Tensor>::Signature, IndexPositions...>,
60 Restriction<Tensor, Seq<IndexPositions...>, Seq<PivotIndices...> > >
61 ,
public Expressions::Storage<OperationTraits<RestrictionOperation<Seq<IndexPositions...>, Seq<PivotIndices...> > >, Tensor>
63 static_assert(
isSorted(Seq<IndexPositions...>{}),
64 "Index positions must be sorted.");
67 using DefectPositions = Seq<IndexPositions...>;
68 using PivotSequence = Seq<PivotIndices...>;
69 using FunctorType = OperationTraits<RestrictionOperation<DefectPositions, PivotSequence> >;
71 using ArgType = Tensor;
72 using HostType = std::decay_t<Tensor>;
74 ACFem::SubSequenceComplement<
typename HostType::Signature, IndexPositions...>,
76 using StorageType = Expressions::Storage<FunctorType, Tensor>;
78 using DefectSignature = SequenceSlice<typename HostType::Signature, DefectPositions>;
82 using typename BaseType::Signature;
83 using typename BaseType::FieldType;
84 using StorageType::operand;
85 using StorageType::operation;
86 using BaseType::operator[];
92 std::enable_if_t<std::is_constructible<ArgType, Arg>::value,
int> = 0>
94 : StorageType(std::forward<Arg>(host))
100 std::enable_if_t<(
sizeof...(Dummy) == 0
103 : StorageType(ArgType{})
109 using Positions = JoinedDefects<DefectPositions, Seq<0> >;
110 using Injections = JoinedInjections<DefectPositions, Seq<0> >;
124 using Positions = JoinedDefects<DefectPositions, Seq<0> >;
125 using Injections = JoinedInjections<DefectPositions, Seq<0> >;
133 template<
class... Dims,
134 std::enable_if_t<(
sizeof...(Dims) == rank
138 decltype(
auto)
operator()(Dims... indices)
140 return tensorValue(operand(0_c), insertAt<IndexPositions...>(std::forward_as_tuple(indices...),
toArray(PivotSequence{})));
146 template<
class... Dims,
147 std::enable_if_t<(
sizeof...(Dims) == rank
151 decltype(
auto)
operator()(Dims... indices)
const
153 return tensorValue(operand(0_c), insertAt<IndexPositions...>(std::forward_as_tuple(indices...),
toArray(PivotSequence{})));
157 template<std::size_t... Indices,
158 std::enable_if_t<(
sizeof...(Indices) == rank
160 decltype(
auto)
constexpr operator()(Seq<Indices...>)
162 return operand(0_c)(
InsertAt<Seq<Indices...>, PivotSequence, DefectPositions>{});
166 template<std::size_t... Indices,
167 std::enable_if_t<(
sizeof...(Indices) == rank
169 decltype(
auto)
constexpr operator()(Seq<Indices...>)
const
171 return operand(0_c)(
InsertAt<Seq<Indices...>, PivotSequence, DefectPositions>{});
174 template<std::size_t... Indices,
class Pos =
MakeIndexSequence<
sizeof...(Indices)> >
175 static bool constexpr isZero(Seq<Indices...> = Seq<Indices...>{}, Pos = Pos{})
179 using TruncatedPos =
HeadPart<
sizeof...(Indices), Pos>;
180 using RealPos =
typename SortSequence<TruncatedPos>::Result;
181 using Permutation =
typename SortSequence<TruncatedPos>::Permutation;
184 using Positions = JoinedDefects<DefectPositions, RealPos>;
185 using Injections = JoinedInjections<DefectPositions, RealPos>;
187 return HostType::isZero(InsertAt<PivotSequence, RealIndices, Injections>{}, Positions{});
193 return PivotSequence{};
196 std::string name()
const
206 template<
class Tensor, std::size_t... IndexPositions>
208 :
public TensorBase<typename TensorTraits<Tensor>::FieldType,
209 ACFem::SubSequenceComplement<typename TensorTraits<Tensor>::Signature, IndexPositions...>,
210 Restriction<Tensor, Seq<IndexPositions...>, Seq<> > >
211 ,
public Expressions::Storage<OperationTraits<RestrictionOperation<Seq<IndexPositions...>, Seq<> > >, Tensor>
214 using DefectPositions = Seq<IndexPositions...>;
215 using PivotSequence = Seq<>;
218 using ArgType = Tensor;
219 using HostType = std::decay_t<Tensor>;
221 ACFem::SubSequenceComplement<
typename HostType::Signature, IndexPositions...>,
222 Restriction<Tensor, Seq<IndexPositions...>, Seq<> > >;
223 using StorageType = Expressions::Storage<FunctorType, Tensor>;
224 using StorageType::functor_;
226 using StorageType::operation;
227 using StorageType::operand;
228 using DefectSignature = SequenceSlice<typename HostType::Signature, DefectPositions>;
231 using BaseType::rank;
232 using typename BaseType::Signature;
233 using typename BaseType::FieldType;
234 using PivotIndexType =
typename FunctorType::IndexType;
238 template<
class Arg,
class T, std::size_t... Idx,
239 std::enable_if_t<std::is_constructible<ArgType, Arg>::value,
int> = 0>
241 : StorageType(std::forward<Arg>(host), FunctorType({{ get<Idx>(std::forward<T>(t))... }}))
253 template<
class Arg,
class T,
254 std::enable_if_t<(std::is_constructible<ArgType, Arg>::value
256 && size<T>() ==
sizeof...(IndexPositions)
260 : StorageType(FunctorType(tuple),
std::forward<Arg>(host))
271 template<
class Arg,
class T, std::size_t N,
272 std::enable_if_t<(std::is_constructible<ArgType, Arg>::value
274 && (N ==
sizeof...(IndexPositions) || N == 0)
275 && std::is_integral<T>::value)
278 : StorageType(std::forward<Arg>(host), FunctorType(t))
282 template<
class Arg,
class T,
283 std::enable_if_t<(std::is_constructible<ArgType, Arg>::value
289 : StorageType(std::forward<Arg>(host))
299 template<
class Arg,
class... Indices,
300 std::enable_if_t<(std::is_constructible<ArgType, Arg>::value
301 &&
sizeof...(Indices) != 0
302 &&
sizeof...(Indices) ==
sizeof...(IndexPositions)
306 : StorageType(
std::forward<Arg>(host), FunctorType({{{ (PivotIndexType)indices... }}}))
315 template<
class Arg, std::size_t... Pivots,
316 std::enable_if_t<(std::is_constructible<ArgType, Arg>::value
317 &&
sizeof...(Pivots) != 0
326 template<class Arg, std::enable_if_t<std::is_constructible<ArgType, Arg>::value,
int> = 0>
328 : StorageType(std::forward<Arg>(host))
334 using Positions = JoinedDefects<DefectPositions, Seq<0> >;
335 using Injections = JoinedInjections<DefectPositions, Seq<0> >;
343 using Positions = JoinedDefects<DefectPositions, Seq<0> >;
344 using Injections = JoinedInjections<DefectPositions, Seq<0> >;
352 template<
class... Dims,
353 std::enable_if_t<(
sizeof...(Dims) == rank
357 decltype(
auto)
operator()(Dims... indices)
359 return tensorValue(operand(0_c), insertAt<IndexPositions...>(std::forward_as_tuple(indices...), lookAt()));
365 template<
class... Dims,
366 std::enable_if_t<(
sizeof...(Dims) == rank
370 decltype(
auto)
operator()(Dims... indices)
const
372 return tensorValue(operand(0_c), insertAt<IndexPositions...>(std::forward_as_tuple(indices...), lookAt()));
376 template<std::size_t... Indices,
377 std::enable_if_t<(
sizeof...(Indices) == rank
379 decltype(
auto)
constexpr operator()(Seq<Indices...>)
381 return (*
this)(Indices...);
385 template<std::size_t... Indices,
386 std::enable_if_t<(
sizeof...(Indices) == rank
388 decltype(
auto)
constexpr operator()(Seq<Indices...>)
const
390 return (*
this)(Indices...);
394 template<
class Indices,
class Positions,
class Injections, std::size_t... N>
395 static bool constexpr isZeroExpander(Indices, Positions, Injections, Seq<N...>)
401 template<std::size_t... Indices,
class Pos =
MakeIndexSequence<
sizeof...(Indices)> >
402 static bool constexpr isZero(Seq<Indices...> = Seq<Indices...>{}, Pos = Pos{})
406 using TruncatedPos =
HeadPart<
sizeof...(Indices), Pos>;
407 using RealPos =
typename SortSequence<TruncatedPos>::Result;
408 using Permutation =
typename SortSequence<TruncatedPos>::Permutation;
411 using Positions = JoinedDefects<DefectPositions, RealPos>;
412 using Injections = JoinedInjections<DefectPositions, RealPos>;
417 return isZeroExpander(RealIndices{}, Positions{}, Injections{},
425 template<
class... Indices,
426 std::enable_if_t<((
sizeof...(Indices) > 0)
431 static_assert(
sizeof...(Indices) <= defectRank_,
432 "The number of pivot indices must match the co-dimension.");
433 auto indexList = { (std::size_t)indices... };
434 std::copy(indexList.begin(), indexList.end(), functor_.pivotIndices_.end() - indexList.size());
447 static_assert(size<T>() <= defectRank_,
448 "The number of pivot indices must match the co-dimension.");
449 std::copy(tuple.begin(), tuple.end(), functor_.pivotIndices_.end() - tuple.size());
455 return functor_.pivotIndices_;
461 return functor_.pivotIndices_;
464 std::string name()
const
485 struct IsRestriction<T&&>
486 : IsRestriction<std::decay_t<T> >
489 template<
class T,
class DefectPositions,
class PivotIndices>
490 struct IsRestriction<Restriction<T, DefectPositions, PivotIndices> >
494 template<
class T,
class SFINAE =
void>
495 struct IsConstRestriction
500 struct IsConstRestriction<T,
std::enable_if_t<!IsDecay<T>::value> >
501 : IsConstRestriction<std::decay_t<T> >
507 template<
class T,
class Pos,
class Pivots>
509 std::enable_if_t<Pos::size() == Pivots::size()> >
514 struct IsDynamicRestriction
519 struct IsDynamicRestriction<T&>
520 : IsDynamicRestriction<std::decay_t<T> >
524 struct IsDynamicRestriction<T&&>
525 : IsDynamicRestriction<std::decay_t<T> >
531 template<
class T, std::size_t P0, std::size_t... PRest>
532 struct IsDynamicRestriction<
Restriction<T, Seq<P0, PRest...>, Seq<> > >
536 template<
class Pos,
class Ind,
class T>
539 DUNE_ACFEM_RECORD_OPTIMIZATION;
544 using Expressions::finalize;
547 template<std::size_t... IndexPositions,
class T, std::size_t... Indices,
548 std::enable_if_t<(IsProperTensor<T>::value
549 &&
sizeof...(IndexPositions) ==
sizeof...(Indices)
551 auto restriction(T&& t, Seq<Indices...>, Seq<IndexPositions...> = Seq<IndexPositions...>{})
554 return finalize<Operation>(std::forward<T>(t));
560 template<std::size_t... IndexPositions,
class T,
class Indices,
561 std::enable_if_t<(IsTupleLike<Indices>::value
562 && IsProperTensor<T>::value
564 auto restriction(T&& t, Indices&& indices, Seq<IndexPositions...> = Seq<IndexPositions...>{})
566 static_assert(
sizeof...(IndexPositions) == size<Indices>() || size<Indices>() == 0,
567 "The number of pivot indices must match the number of defect positions.");
569 using Functor = OperationTraits<RestrictionOperation<Seq<IndexPositions...>, Seq<> > >;
571 return finalize(Functor(indices), std::forward<T>(t));
577 template<std::size_t... IndexPositions,
class T,
class I, std::size_t N, std::enable_if_t<IsProperTensor<T>::value,
int> = 0>
578 auto restriction(T&& t,
const I (&l)[N], Seq<IndexPositions...> = Seq<IndexPositions...>{})
580 static_assert(
sizeof...(IndexPositions) == N || N == 0,
581 "Either all or no pivot indices must be given.");
583 using Functor = OperationTraits<RestrictionOperation<Seq<IndexPositions...>, Seq<> > >;
585 return finalize(Functor(l), std::forward<T>(t));
590 template<std::size_t... IndexPositions,
class T, std::enable_if_t<IsProperTensor<T>::value,
int> = 0>
593 using Operation = RestrictionOperation<Seq<IndexPositions...>, Seq<> >;
594 return finalize<Operation>(std::forward<T>(t));
599 template<class T, class DefectPositions, std::enable_if_t<IsProperTensor<T>::value,
int> = 0>
602 using Operation = RestrictionOperation<DefectPositions, Seq<> >;
603 return finalize<Operation>(std::forward<T>(t));
610 namespace Expressions {
613 constexpr inline std::size_t WeightV<T, std::enable_if_t<Tensor::IsConstRestriction<T>::value> > =
614 ExpressionWeightV<Operand<0, T> > + prod(
typename std::decay_t<T>::DefectPositions{}) + prod(std::decay_t<T>::lookAt());
620 template<
class Tensor,
class Pos,
class Indices>
621 struct FieldTraits<ACFem::Tensor::Restriction<Tensor, Pos, Indices> >
622 : FieldTraits<Tensor>
A meta-tensor restricting a given tensor w.r.t.
Definition: restriction.hh:53
OptimizeTag< 0 > DontOptimize
Bottom level is overloaded to do nothing.
Definition: optimizationbase.hh:74
std::string operationName(F &&f, const std::string &arg)
Verbose print of an operation, helper function to produce noise.
Definition: operationtraits.hh:601
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
auto insertAt(SrcTuple &&src, DataTuple &&data, BoolConstant< AssumeSorted >=BoolConstant< AssumeSorted >{})
Insert the elements of data at positions given by pos into src in turn.
Definition: subtuple.hh:106
Restriction(Arg &&host, IndexSequence< Pivots... >)
Constructor from a given index sequence.
Definition: restriction.hh:319
auto & lookAt()
Return the array of indices currently looking at.
Definition: restriction.hh:459
Restriction(Arg &&host, T &&tuple)
Constructor from emtpy tuple like.
Definition: restriction.hh:288
auto operator[](std::size_t i) const
Implement kind of a nested vector interface via operator[].
Definition: restriction.hh:341
Restriction(Arg &&host, const T &tuple)
Constructor from a given tuple-like index collection.
Definition: restriction.hh:259
Restriction(Dummy &&...)
Allow default construction if contained types fulfill IsTypedValue.
Definition: restriction.hh:102
void lookAt(Indices... indices)
"Move" the view to the given index pack.
Definition: restriction.hh:429
auto restriction(T &&t, Seq< Indices... >, Seq< IndexPositions... >=Seq< IndexPositions... >{})
Generate a compile-time constant restriction.
Definition: restriction.hh:551
auto operator[](std::size_t i)
Implement kind of a nested vector interface via operator[].
Definition: restriction.hh:332
Restriction(Arg &&host, const T(&t)[N])
Constructor from a given C-array index collection.
Definition: restriction.hh:277
auto operator[](std::size_t i) const
Implement kind of a nested vector interface via operator[].
Definition: restriction.hh:122
Restriction(ArgType &&host, Seq<>=Seq<>{})
Constructor from a given host-tensor, looking at the sub-tensor at (0, ...).
Definition: restriction.hh:327
const auto & lookAt() const
Return the array of indices currently looking at.
Definition: restriction.hh:453
Restriction(Arg &&host, PivotSequence=PivotSequence{})
Constructor from a given host-tensor, looking at the pivot indices specified by the template argument...
Definition: restriction.hh:93
auto operator[](std::size_t i)
Implement kind of a nested vector interface via operator[].
Definition: restriction.hh:107
Restriction(Arg &&host, Indices... indices)
Constructor from a given index pack of lookAt() indices.
Definition: restriction.hh:305
static constexpr auto lookAt()
Return the array of indices currently looking at.
Definition: restriction.hh:191
void lookAt(T &&tuple)
"Move" the view to the given index tuple.
Definition: restriction.hh:445
auto toArray(Sequence< T, Ind... >)
Convert a compile-time constant integer sequence to a rutime-object with the same values.
Definition: toarray.hh:76
decltype(isIntegralTuple(std::declval< T >())) IsIntegralTuple
Decide whether the given tuple contains only integral types.
Definition: compare.hh:402
decltype(isIntegralPack(std::declval< T >()...)) IsIntegralPack
Decide whether the given parameter pack contains only integral types.
Definition: compare.hh:377
constexpr bool isSorted(Sequence< T, Ts... >)
Definition: compare.hh:318
std::decay_t< decltype(permute(Sequence{}, Perm{}))> PermuteSequence
Apply the given permutation to the positions of the given sequence.
Definition: permutation.hh:137
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
std::decay_t< decltype(multiIndex< I >(DimSeq{}))> MultiIndex
Generate the multi-index corresponding to the flattened index I where the multiindex varies between t...
Definition: multiindex.hh:68
static std::size_t constexpr multiDim(IndexSequence< Dimensions... >, IndexSequence< IndexPositions... >=IndexSequence< IndexPositions... >{})
Compute the "dimension" corresponding to the given signature, i.e.
Definition: multiindex.hh:171
Gets the type of the n-th element of a tuple-like or the std::integral_constant corresponding to the ...
Definition: access.hh:42
AutoDiff operation.
Definition: expressionoperations.hh:53
Traits in order to identify a Restriction class.
Definition: restriction.hh:477
Base class for all tensors.
Definition: tensorbase.hh:144