1#ifndef DUNE_FEM_FUNCTION_HIERARCHICAL_DOFVECTOR_HH
2#define DUNE_FEM_FUNCTION_HIERARCHICAL_DOFVECTOR_HH
11#include <dune/istl/multitypeblockvector.hh>
14#include <dune/fem/common/hybrid.hh>
15#include <dune/fem/common/utility.hh>
16#include <dune/fem/function/blockvectors/defaultblockvectors.hh>
28 struct BlockIndicesFor;
31 template<
class K,
int dim,
class A >
32 struct BlockIndicesFor< BlockVector< FieldVector< K, dim >, A > >
34 typedef Hybrid::IndexRange< int, dim > Type;
37 template<
class... V >
38 struct BlockIndicesFor< MultiTypeBlockVector< V... > >
40 typedef Hybrid::CompositeIndexRange< typename BlockIndicesFor< V >::Type... > Type;
44 struct BlockIndicesFor< const T >
46 typedef typename BlockIndicesFor< T >::Type Type;
58 template<
class DofContainer >
59 struct HierarchicalDofBlock
61 friend struct HierarchicalDofBlock< const DofContainer >;
63 typedef typename Impl::BlockIndicesFor< DofContainer >::Type BlockIndices;
64 static constexpr std::size_t blockSize = Hybrid::size( BlockIndices() );
66 HierarchicalDofBlock ( DofContainer &data, std::size_t baseIndex )
67 : data_( data ), baseIndex_( baseIndex )
70 HierarchicalDofBlock (
const HierarchicalDofBlock< std::remove_const_t< DofContainer > > &other )
71 : data_( other.data_ ), baseIndex_( other.baseIndex_ )
74 template<
class Index >
75 decltype( auto )
operator[] (
const Index &index )
const
77 return access( data_, baseIndex_, index );
80 template<
class Index >
81 decltype( auto )
operator[] (
const Index &index )
83 return access( data_, baseIndex_, index );
88 template<
class... V, std::size_t component,
class I, I offset,
class SI >
89 static decltype( auto ) access (
const MultiTypeBlockVector< V... > &data, std::size_t baseIndex,
const Hybrid::CompositeIndex< component, I, offset, SI > &index )
91 return access( data[ std::integral_constant< std::size_t, component >() ], baseIndex, index.subIndex() );
94 template<
class... V, std::size_t component,
class I, I offset,
class SI >
95 static decltype( auto ) access ( MultiTypeBlockVector< V... > &data, std::size_t baseIndex,
const Hybrid::CompositeIndex< component, I, offset, SI > &index )
97 return access( data[ std::integral_constant< std::size_t, component >() ], baseIndex, index.subIndex() );
100 template<
class K,
int n,
class A >
101 static const K &access (
const BlockVector<
FieldVector< K, n >, A > &data, std::size_t baseIndex,
int index )
103 return data[ baseIndex ][ index ];
106 template<
class K,
int n,
class A >
107 static K &access ( BlockVector<
FieldVector< K, n >, A > &data, std::size_t baseIndex,
int index )
109 return data[ baseIndex ][ index ];
114 std::size_t baseIndex_;
122 struct SpecialArrayFeatures;
129 class HierarchicalDofVector
130 :
public IsBlockVector
132 typedef HierarchicalDofVector< DC > ThisType;
135 typedef DC DofContainerType;
137 typedef typename FieldTraits< DofContainerType >::field_type FieldType;
139 typedef std::size_t SizeType;
141 typedef FieldType value_type;
142 typedef SizeType size_type;
144 typedef typename Impl::BlockIndicesFor< DC >::Type BlockIndices;
145 static constexpr std::size_t blockSize = Hybrid::size( BlockIndices() );
147 typedef HierarchicalDofBlock< const DofContainerType > ConstDofBlockType;
148 typedef HierarchicalDofBlock< DofContainerType > DofBlockType;
150 explicit HierarchicalDofVector ( SizeType
size ) { resize(
size ); }
152 ConstDofBlockType operator[] ( SizeType i )
const {
return ConstDofBlockType( data_, i ); }
153 DofBlockType operator[] ( SizeType i ) {
return DofBlockType( data_, i ); }
155 ThisType &operator+= (
const ThisType &other ) { data_ += other.data_;
return *
this; }
156 ThisType &operator-= (
const ThisType &other ) { data_ -= other.data_;
return *
this; }
157 ThisType &operator*= (
const FieldType &scalar ) { data_ *= scalar;
return *
this; }
159 FieldType operator* (
const ThisType &other )
const {
return data_ * other.data_; }
161 void axpy (
const FieldType &scalar,
const ThisType &other ) { data_.axpy( scalar, other.data_ ); }
163 void clear () { data_ = FieldType( 0 ); }
166 const DofContainerType &array () const noexcept {
return data_; }
168 DofContainerType &array () noexcept {
return data_; }
170 void reserve ( SizeType
size ) { reserve( data_,
size ); }
171 void resize ( SizeType
size ) { resize( data_,
size ); }
173 SizeType
size ()
const {
return size( data_ ); }
177 typedef const FieldType *ConstIteratorType;
178 typedef FieldType *IteratorType;
180 ConstIteratorType begin ()
const {
DUNE_THROW( NotImplemented,
"HierarchicalDofVector does not provide iterators" ); }
181 IteratorType begin () {
DUNE_THROW( NotImplemented,
"HierarchicalDofVector does not provide iterators" ); }
183 ConstIteratorType end ()
const {
DUNE_THROW( NotImplemented,
"HierarchicalDofVector does not provide iterators" ); }
184 IteratorType end () {
DUNE_THROW( NotImplemented,
"HierarchicalDofVector does not provide iterators" ); }
186 std::size_t usedMemorySize()
const
188 return SpecialArrayFeatures< ThisType >::used( *
this );
191 void setMemoryFactor (
double memFactor )
194 void memMoveBackward (
int length,
int oldStartIdx,
int newStartIdx )
196 SpecialArrayFeatures< ThisType >::memMoveBackward( *
this, length, oldStartIdx, newStartIdx );
199 void memMoveForward (
int length,
int oldStartIdx,
int newStartIdx )
201 SpecialArrayFeatures< ThisType >::memMoveForward( *
this, length, oldStartIdx, newStartIdx );
204 void copyContent (
int newIndex,
int oldIndex )
211 template<
class... V >
212 static void reserve ( MultiTypeBlockVector< V... > &data, SizeType
size )
214 Hybrid::forEach( std::index_sequence_for< V... >(), [ &data,
size ] (
auto &&i ) { ThisType::reserve( data[ i ],
size ); } );
217 template<
class B,
class A >
218 static void reserve ( BlockVector< B, A > &data, SizeType
size )
220 data.reserve(
size );
223 template<
class... V >
224 static void resize ( MultiTypeBlockVector< V... > &data, SizeType
size )
226 Hybrid::forEach( std::index_sequence_for< V... >(), [ &data,
size ] (
auto &&i ) { ThisType::resize( data[ i ],
size ); } );
229 template<
class B,
class A >
230 static void resize ( BlockVector< B, A > &data, SizeType
size )
235 template<
class... V >
236 static SizeType
size (
const MultiTypeBlockVector< V... > &data )
238 return data[ std::integral_constant< std::size_t, 0 > () ].size();
241 template<
class B,
class A >
242 static SizeType
size (
const BlockVector< B, A > &data )
248 DofContainerType data_;
257 struct SpecialArrayFeatures;
260 struct SpecialArrayFeatures< HierarchicalDofVector< DC > >
262 static std::size_t used (
const HierarchicalDofVector< DC > &array )
264 return used( array.array() );
267 static void setMemoryFactor ( HierarchicalDofVector< DC > &array,
double memFactor )
270 static void memMoveBackward ( HierarchicalDofVector< DC > &array,
int length,
int oldStartIdx,
int newStartIdx )
272 memMoveBackward( array.array(), length, oldStartIdx, newStartIdx );
275 static void memMoveForward ( HierarchicalDofVector< DC > &array,
int length,
int oldStartIdx,
int newStartIdx )
277 memMoveForward( array.array(), length, oldStartIdx, newStartIdx );
280 static void assign ( HierarchicalDofVector< DC > &array,
int newIndex,
int oldIndex )
282 assign( array.array(), newIndex, oldIndex );
287 template<
class... V >
288 static std::size_t used (
const MultiTypeBlockVector< V... > &array )
290 std::size_t used( 0 );
291 Hybrid::forEach( std::index_sequence_for< V... >(), [ &array, &used ] (
auto &&i ) {
292 used += SpecialArrayFeatures< HierarchicalDofVector< DC > >::used( array[ i ] );
297 template<
class B,
class A >
298 static std::size_t used (
const BlockVector< B, A > &array )
300 return array.size() *
sizeof( B );
303 template<
class... V >
304 static void memMoveBackward ( MultiTypeBlockVector< V... > &array,
int length,
int oldStartIdx,
int newStartIdx )
306 Hybrid::forEach( std::index_sequence_for< V... >(), [ &array, length, oldStartIdx, newStartIdx ] (
auto &&i ) {
307 SpecialArrayFeatures< HierarchicalDofVector< DC > >::memMoveBackward( array[ i ], length, oldStartIdx, newStartIdx );
311 template<
class B,
class A >
312 static void memMoveBackward ( BlockVector< B, A > &array,
int length,
int oldStartIdx,
int newStartIdx )
314 for(
int oldIdx = oldStartIdx+length-1, newIdx = newStartIdx + length-1; oldIdx >= oldStartIdx; --oldIdx, --newIdx )
315 array[ newIdx ] = array[ oldIdx ];
318 template<
class... V >
319 static void memMoveForward ( MultiTypeBlockVector< V... > &array,
int length,
int oldStartIdx,
int newStartIdx )
321 Hybrid::forEach( std::index_sequence_for< V... >(), [ &array, length, oldStartIdx, newStartIdx ] (
auto &&i ) {
322 SpecialArrayFeatures< HierarchicalDofVector< DC > >::memMoveForward( array[ i ], length, oldStartIdx, newStartIdx );
326 template<
class B,
class A >
327 static void memMoveForward ( BlockVector< B, A > &array,
int length,
int oldStartIdx,
int newStartIdx )
329 for(
int oldIdx = oldStartIdx, newIdx = newStartIdx; oldIdx < oldStartIdx+length; ++oldIdx, ++newIdx )
330 array[ newIdx ] = array[ oldIdx ];
333 template<
class... V >
334 static void assign ( MultiTypeBlockVector< V... > &array,
int newIndex,
int oldIndex )
336 Hybrid::forEach( std::index_sequence_for< V... >(), [ &array, newIndex, oldIndex ] (
auto &&i ) {
337 SpecialArrayFeatures< HierarchicalDofVector< DC > >
::assign( array[ i ], newIndex, oldIndex );
341 template<
class B,
class A >
342 static void assign ( BlockVector< B, A > &array,
int newIndex,
int oldIndex )
344 array[ newIndex ] = array[ oldIndex ];
This file implements a vector space as a tensor product of a given vector space. The number of compon...
Type traits to determine the type of reals (when working with complex numbers)
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
constexpr void forEach(Range &&range, F &&f)
Range based for loop.
Definition: hybridutilities.hh:256
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