3#ifndef DUNE_PDELAB_BACKEND_ISTL_VECTORHELPERS_HH
4#define DUNE_PDELAB_BACKEND_ISTL_VECTORHELPERS_HH
10#include <dune/pdelab/backend/istl/tags.hh>
11#include <dune/pdelab/backend/istl/descriptors.hh>
12#include <dune/pdelab/finiteelementmap/utility.hh>
13#include <dune/pdelab/ordering/orderingbase.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)
117 allocate_vector(container_tag(c),ordering,c);
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);
133 template<typename E,typename Node, typename Tag, bool isLeafTag = std::is_base_of<LeafGridFunctionSpaceTag,Tag>::value >
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;
149 static_assert(Backend::Traits::block_type != Blocking::bcrs,
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 =
161 Backend::Traits::block_type == Blocking::none;
169 std::integral_constant<std::size_t,0>,
170 FiniteElementMapBlockSize,
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;
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;
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 &&
315 Backend::Traits::block_type == Blocking::none;
319 Backend::Traits::block_size == 0,
320 "You cannot specify a block size on interior nodes of the function space tree."
325 static_assert((Backend::Traits::block_type != Blocking::fixed) ||
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 =
337 Backend::Traits::block_type == Blocking::fixed
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?");
390 template<
typename Data>
391 struct parent_child_vector_descriptor<
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>
This file implements a vector space as a tensor product of a given vector space. The number of compon...
A vector of blocks with memory management.
Definition: bvector.hh:392
Traits for type conversions and type information.
typename detected_or< Default, Op, Args... >::type detected_or_t
Returns Op<Args...> if that is valid; otherwise returns the fallback type Default.
Definition: type_traits.hh:189
constexpr GeometryType none(unsigned int dim)
Returns a GeometryType representing a singular of dimension dim.
Definition: type.hh:471
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