3 #ifndef DUNE_PDELAB_BACKEND_ISTL_VECTORHELPERS_HH
4 #define DUNE_PDELAB_BACKEND_ISTL_VECTORHELPERS_HH
6 #include <dune/common/typetraits.hh>
8 #include <dune/istl/bvector.hh>
24 template<
typename CI,
typename Block>
25 typename Block::field_type&
26 access_vector_element(tags::field_vector_1, Block& b,
const CI& ci,
int i)
31 assert(i == -1 || i == 0);
35 template<
typename CI,
typename Block>
36 typename Block::field_type&
37 access_vector_element(tags::field_vector_n, Block& b,
const CI& ci,
int i)
43 template<
typename CI,
typename Block>
44 typename Block::field_type&
45 access_vector_element(tags::block_vector, Block& b,
const CI& ci,
int i)
47 return access_vector_element(
container_tag(b[ci[i]]),b[ci[i]],ci,i-1);
51 template<
typename CI,
typename Block>
52 const typename Block::field_type&
53 access_vector_element(tags::field_vector_1,
const Block& b,
const CI& ci,
int i)
58 assert(i == -1 || i == 0);
62 template<
typename CI,
typename Block>
63 const typename Block::field_type&
64 access_vector_element(tags::field_vector_n,
const Block& b,
const CI& ci,
int i)
70 template<
typename CI,
typename Block>
71 const typename Block::field_type&
72 access_vector_element(tags::block_vector,
const Block& b,
const CI& ci,
int i)
74 return access_vector_element(
container_tag(b[ci[i]]),b[ci[i]],ci,i-1);
78 template<
typename Vector>
80 void resize_vector(tags::block_vector,
Vector& v, std::size_t size,
bool copy_values)
85 template<
typename Vector>
87 void resize_vector(tags::field_vector,
Vector& v, std::size_t size,
bool copy_values)
91 template<
typename DI,
typename CI,
typename Container>
93 void allocate_vector(tags::field_vector,
const OrderingBase<DI,CI>& ordering, Container& c)
97 template<
typename DI,
typename CI,
typename Container>
99 void allocate_vector(tags::block_vector,
const OrderingBase<DI,CI>& ordering, Container& c)
101 for (std::size_t i = 0; i < ordering.childOrderingCount(); ++i)
103 if (ordering.containerBlocked())
105 resize_vector(
container_tag(c[i]),c[i],ordering.childOrdering(i).blockCount(),
false);
106 allocate_vector(
container_tag(c[i]),ordering.childOrdering(i),c[i]);
109 allocate_vector(
container_tag(c),ordering.childOrdering(i),c);
113 template<
typename Ordering,
typename Container>
115 void dispatch_vector_allocation(
const Ordering& ordering, Container& c, HierarchicContainerAllocationTag tag)
120 template<
typename Ordering,
typename Container>
122 void dispatch_vector_allocation(
const Ordering& ordering, Container& c, FlatContainerAllocationTag tag)
124 resize_vector(
container_tag(c),c,ordering.blockCount(),
false);
134 struct vector_descriptor_helper
142 template<
typename E,
typename GFS>
143 struct leaf_vector_descriptor
146 using Backend =
typename GFS::Traits::Backend;
147 using FEM =
typename GFS::Traits::FiniteElementMap;
150 "Dynamically blocked leaf spaces are not supported by this backend.");
153 static const bool support_no_blocking =
true;
160 static const bool support_cascaded_blocking =
168 static const std::size_t detected_cumulative_block_size = Dune::Std::detected_or_t<
169 std::integral_constant<std::size_t,0>,
175 static const std::size_t cumulative_block_size = Backend::Traits::block_size > 0
176 ? Backend::Traits::block_size
177 : detected_cumulative_block_size;
179 static constexpr
bool have_valid_block_size = cumulative_block_size > 0;
182 Backend::Traits::block_size == 0 or (detected_cumulative_block_size % cumulative_block_size) == 0,
183 "The vector block size you specified is not compatible with the finite element map"
187 Backend::Traits::block_type !=
Blocking::fixed or have_valid_block_size,
188 "You requested static blocking, but we cannot extract a valid block size from the finite element map. Please specify the block size with the second template parameter of the vector backend."
192 static const std::size_t block_size =
193 Backend::Traits::block_type ==
Blocking::fixed ? cumulative_block_size : 1;
196 typedef E element_type;
199 typedef Dune::BlockVector<FieldVector<E,block_size> > vector_type;
204 template<
typename E,
typename Node,
typename Tag>
205 struct vector_descriptor_helper<E,Node,Tag, true>
207 typedef leaf_vector_descriptor<E,Node> type;
212 struct extract_vector_descriptor
215 template<
typename Node,
typename TreePath>
219 static const bool value =
true;
222 template<
typename Node,
typename TreePath>
226 typedef typename vector_descriptor_helper<E,Node,TypeTree::ImplementationTag<Node>>::type type;
232 template<
typename Sibling,
typename Child>
233 struct cascading_vector_descriptor
237 static const bool support_cascaded_blocking =
238 Sibling::support_cascaded_blocking &&
239 Child::support_cascaded_blocking;
244 static const bool support_no_blocking =
245 (Sibling::support_no_blocking &&
247 typename Sibling::vector_type,
248 typename Child::vector_type
251 static constexpr
bool have_valid_block_size =
252 Sibling::have_valid_block_size and Child::have_valid_block_size;
255 static const std::size_t block_size =
256 support_no_blocking ? Sibling::block_size : 1;
259 typedef typename Sibling::element_type element_type;
262 static const std::size_t cumulative_block_size =
263 Sibling::cumulative_block_size + Child::cumulative_block_size;
266 typedef Dune::BlockVector<FieldVector<element_type,block_size> > vector_type;
273 template<
typename D1,
typename D2>
274 struct initial_reduction_switch
276 typedef cascading_vector_descriptor<D1,D2> type;
280 template<
typename D2>
281 struct initial_reduction_switch<void,D2>
287 struct combine_vector_descriptor_siblings
290 template<
typename D1,
typename D2>
292 :
public initial_reduction_switch<D1,D2>
298 template<
typename Child,
typename GFS>
299 struct parent_child_vector_descriptor_data
302 using Backend =
typename GFS::Traits::Backend;
304 static constexpr
bool have_valid_block_size = Child::have_valid_block_size;
308 static const bool support_no_blocking =
309 Child::support_no_blocking;
313 static const bool support_cascaded_blocking =
314 Child::support_cascaded_blocking &&
319 Backend::Traits::block_size == 0,
320 "You cannot specify a block size on interior nodes of the function space tree."
326 Child::support_cascaded_blocking,
327 "invalid blocking structure.");
330 Backend::Traits::block_type !=
Blocking::fixed or have_valid_block_size,
331 "You requested static blocking, but at least one leaf space has a finite element that does not support automatic block size extraction. Please specify the block size with the second template parameter of that space's vector backend."
336 static const std::size_t block_size =
338 ? Child::cumulative_block_size
342 static const std::size_t cumulative_block_size =
343 Child::cumulative_block_size;
346 typedef typename Child::element_type element_type;
349 typedef typename Child::vector_type child_vector_type;
354 template<
typename Data, Blocking>
355 struct parent_child_vector_descriptor;
358 template<
typename Data>
359 struct parent_child_vector_descriptor<
365 static_assert(Data::support_no_blocking,
366 "Cannot combine incompatible child block structures without static blocking. "
367 "Did you want to apply static blocking at this level?");
370 typedef typename Data::child_vector_type vector_type;
374 template<
typename Data>
375 struct parent_child_vector_descriptor<
381 static_assert(Data::support_no_blocking,
382 "Incompatible child block structures detected, cannot perform dynamic blocking. "
383 "Did you want to apply static blocking at this level?");
386 typedef Dune::BlockVector<typename Data::child_vector_type> vector_type;
390 template<
typename Data>
391 struct parent_child_vector_descriptor<
398 typedef Dune::BlockVector<
400 typename Data::element_type,
407 struct combine_vector_descriptor_parent
410 template<
typename Child,
typename GFS>
415 :
public parent_child_vector_descriptor<parent_child_vector_descriptor_data<
418 GFS::Traits::Backend::Traits::block_type
427 struct vector_creation_policy
428 :
public TypeTree::TypeAccumulationPolicy<extract_vector_descriptor<E>,
429 combine_vector_descriptor_siblings,
431 combine_vector_descriptor_parent,
432 TypeTree::bottom_up_reduction>
For backward compatibility – Do not use this!
Definition: adaptivity.hh:28
std::integral_constant< std::size_t, finiteElementMapBlockSize< FEM >()> FiniteElementMapBlockSize
An alias template that encapsulates the result of finiteElementMapBlockSize<FEM>() in an integral con...
Definition: finiteelementmap/utility.hh:88
typename impl::BackendVectorSelector< GridFunctionSpace, FieldType >::Type Vector
alias of the return type of BackendVectorSelector
Definition: backend/interface.hh:106
tags::container< T >::type container_tag(const T &)
Gets instance of container tag associated with T.
Definition: backend/istl/tags.hh:234
Blocking
The type of blocking employed at this node in the function space tree.
Definition: istl/descriptors.hh:27
@ none
No blocking at this level.
@ bcrs
Creates one macro block for each child space, each block is a BlockVector / BCRS matrix.
@ fixed
Create fixed size blocks that each group together a fixed number of DOFs from each child space.
static const unsigned int value
Definition: gridfunctionspace/tags.hh:139