1#ifndef DUNE_FEM_FUNCTION_BLOCKVECTORS_TUPLE_HH
2#define DUNE_FEM_FUNCTION_BLOCKVECTORS_TUPLE_HH
8#include <dune/common/hybridutilities.hh>
10#include <dune/fem/common/forloop.hh>
11#include <dune/fem/common/utility.hh>
12#include <dune/fem/function/blockvectors/defaultblockvectors.hh>
13#include <dune/fem/function/common/functor.hh>
26 template<
class ... DofVectors >
28 :
public IsBlockVector,
29 public std::tuple< DofVectors& ... >
31 typedef TupleDofVector< DofVectors ... > ThisType;
32 typedef std::tuple< DofVectors & ... > BaseType;
34 static_assert(
sizeof ... ( DofVectors ) > 0,
"TupleDofVector needs at least one DofVector." );
36 typedef std::tuple< DofVectors ... > DofVectorTuple;
38 typedef decltype ( std::index_sequence_for< DofVectors ... >() ) Sequence;
41 static_assert( Std::are_all_same<
typename DofVectors::FieldType ... >::value,
"All blocks need to have the same FieldType." );
42 typedef typename std::tuple_element< 0, DofVectorTuple >::type::FieldType FieldType;
47 typedef Iterator IteratorType;
48 typedef ConstIterator ConstIteratorType;
50 typedef std::size_t SizeType;
51 typedef FieldType value_type;
52 typedef SizeType size_type;
54 static const int blockSize = 1;
56 typedef FieldType *DofBlockType;
57 typedef const FieldType *ConstDofBlockType;
59 typedef Fem::Envelope< DofBlockType > DofBlockPtrType;
60 typedef Fem::Envelope< ConstDofBlockType > ConstDofBlockPtrType;
62 TupleDofVector ( DofVectors & ... dofVectors )
63 : BaseType(
std::forward_as_tuple( dofVectors ... ) )
67 TupleDofVector ( BaseType data ) : BaseType( data ) {}
68 TupleDofVector (
const ThisType & ) =
default;
69 TupleDofVector ( ThisType && ) =
default;
71 const ThisType &operator= (
const ThisType &other )
73 assign( other, Sequence() );
77 const ThisType &operator+= (
const ThisType &other )
79 axpy( 1.0, other, Sequence() );
83 const ThisType &operator-= (
const ThisType &other )
85 axpy( -1.0, other, Sequence() );
93 static void apply(
const ThisType &a,
const ThisType& b, FieldType& result )
95 result += (a.template subDofVector< i >() * b.template subDofVector<i>());
100 FieldType operator* (
const ThisType &other )
const
102 FieldType result( 0 );
103 static const int length = std::tuple_size< BaseType >::value;
104 Dune::Fem::ForLoop<Acc, 0, length-1>::apply(*
this, other, result);
108 const ThisType &operator*= (
const FieldType &scalar )
110 scale( scalar, Sequence() );
114 const ThisType &operator/= (
const FieldType &scalar )
116 scale( 1.0 / scalar, Sequence() );
120 void axpy (
const FieldType &scalar,
const ThisType &other )
122 axpy( scalar, other, Sequence() );
125 void clear () { clear( Sequence() ); }
127 SizeType
size ()
const {
return size( Sequence() ); }
131 IteratorType begin () {
return IteratorType( *
this, 0 ); }
132 ConstIteratorType begin ()
const {
return ConstIteratorType( *
this, 0 ); }
134 IteratorType end () {
return IteratorType( *
this,
size() ); }
135 ConstIteratorType end ()
const {
return ConstIteratorType( *
this,
size() ); }
137 DofBlockType operator[] ( std::size_t index )
139 return blockAccess( index, std::integral_constant< std::size_t, 0 >() );
141 ConstDofBlockType operator[] ( std::size_t index )
const
143 return blockAccess( index, std::integral_constant< std::size_t, 0 >() );
146 DofBlockPtrType blockPtr ( std::size_t index )
148 return DofBlockPtrType( this->
operator[]( index ) );
150 ConstDofBlockType blockPtr ( std::size_t index )
const
152 return ConstDofBlockPtrType( this->
operator[]( index ) );
157 void reserve ( SizeType
size ) {}
158 void resize ( SizeType
size ) {}
160 constexpr std::size_t blocks ()
const {
return sizeof ... ( DofVectors ); }
163 const typename std::tuple_element< i, DofVectorTuple >::type &
164 subDofVector()
const {
return std::get< i >( *
this ); }
167 typename std::tuple_element< i, DofVectorTuple >::type &
169 return std::get< i >( *
this );
173 template< std::size_t ... i >
174 void scale ( FieldType scale, std::index_sequence< i ... > )
176 std::ignore = std::make_tuple( (std::get< i >( *
this ) *= scale, i ) ... );
179 template< std::size_t ... i >
180 void axpy ( FieldType a,
const ThisType &other, std::index_sequence< i ... > )
182 std::ignore = std::make_tuple( ( std::get< i >( *this ).axpy( a, std::get< i >( other ) ), i ) ... );
185 template< std::size_t ... i >
186 void assign (
const ThisType &other, std::index_sequence< i ... > )
188 std::ignore = std::make_tuple( ( std::get< i >( *
this ) = std::get< i >( other ), i ) ... );
191 template< std::size_t ... i >
192 SizeType
size ( std::index_sequence< i ... > )
const
194 return Std::sum( std::get< i >( *this ).size() *
195 std::tuple_element< i, DofVectorTuple >::type::blockSize ... );
198 template< std::size_t ... I >
199 void clear ( std::index_sequence< I ... > )
201 std::ignore = std::make_tuple( ( std::get< I >( *this ).clear(), I ) ... );
204 template< std::
size_t i >
205 FieldType *blockAccess ( std::size_t index, std::integral_constant< std::size_t, i > )
207 const std::size_t thisBlockSize = std::tuple_element< i, DofVectorTuple >::type::blockSize;
208 std::size_t offset = std::get< i >( *this ).size() * thisBlockSize;
210 return &std::get< i >( *
this )[ index / thisBlockSize ][ index % thisBlockSize ];
212 return blockAccess( index - offset, std::integral_constant< std::size_t, i +1 >() );
215 FieldType *blockAccess ( std::size_t index, std::integral_constant< std::size_t,
sizeof ... ( DofVectors ) > )
217 DUNE_THROW( RangeError,
"Index out of range" );
220 template< std::
size_t i >
221 const FieldType *blockAccess ( std::size_t index, std::integral_constant< std::size_t, i > )
const
223 const std::size_t thisBlockSize = std::tuple_element< i, DofVectorTuple >::type::blockSize;
224 std::size_t offset = std::get< i >( *this ).size() * thisBlockSize;
226 return &std::get< i >( *
this )[ index / thisBlockSize ][ index % thisBlockSize ];
228 return blockAccess( index - offset, std::integral_constant< std::size_t, i +1 >() );
231 const FieldType *blockAccess ( std::size_t index, std::integral_constant< std::size_t,
sizeof ... ( DofVectors ) > )
const
233 DUNE_THROW( RangeError,
"Index out of range" );
239 template<
class ... DofVectors >
240 struct TupleDofVector< DofVectors ... >::
243 Iterator( TupleDofVector< DofVectors ... > &container, std::size_t it = 0 )
244 : container_( container ), iterator_( it ) {}
246 Iterator(
const Iterator & ) =
default;
247 Iterator &operator= (
const Iterator & ) =
default;
249 FieldType &operator* () {
return *container_[ iterator_ ]; }
250 FieldType *operator-> () {
return container_[ iterator_ ]; }
252 Iterator &operator++ () { iterator_++;
return *
this; }
253 Iterator operator++ (
int )
255 ThisType copy( *
this );
260 bool operator== (
const Iterator &other )
const {
return iterator_ == other.iterator_; }
261 bool operator!= (
const Iterator &other )
const {
return iterator_ != other.iterator_; }
264 TupleDofVector< DofVectors ... > &container_;
265 std::size_t iterator_;
268 template<
class ... DofVectors >
269 struct TupleDofVector< DofVectors ... >::
272 ConstIterator(
const TupleDofVector< DofVectors ... > &container, std::size_t it = 0 )
273 : container_( container ), iterator_( it ) {}
275 ConstIterator(
const ConstIterator & ) =
default;
277 const FieldType &operator* ()
const {
return *container_[ iterator_ ]; }
278 FieldType *operator-> ()
const {
return container_[ iterator_ ]; }
280 ConstIterator &operator++ () { iterator_++;
return *
this; }
281 ConstIterator operator++ (
int )
283 ThisType copy( *
this );
288 bool operator== (
const ConstIterator &other )
const {
return iterator_ == other.iterator_; }
289 bool operator!= (
const ConstIterator &other )
const {
return iterator_ != other.iterator_; }
292 const TupleDofVector< DofVectors ... > &container_;
293 std::size_t iterator_;
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
EnableIfInterOperable< T1, T2, bool >::type operator==(const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for equality.
Definition: iteratorfacades.hh:238
EnableIfInterOperable< T1, T2, bool >::type operator!=(const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for inequality.
Definition: iteratorfacades.hh:260
Dune namespace.
Definition: alignedallocator.hh:13
constexpr std::integral_constant< std::size_t, sizeof...(II)> size(std::integer_sequence< T, II... >)
Return the size of the sequence.
Definition: integersequence.hh:75
void assign(T &dst, const T &src, bool mask)
masked Simd assignment (scalar version)
Definition: simd.hh:447