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>
79 void resize_vector(tags::block_vector, Vector& v, std::size_t size,
bool copy_values)
84 template<
typename Vector>
85 void resize_vector(tags::field_vector, Vector& v, std::size_t size,
bool copy_values)
89 template<
typename DI,
typename CI,
typename Container>
90 void allocate_vector(tags::field_vector,
const OrderingBase<DI,CI>& ordering, Container& c)
94 template<
typename DI,
typename CI,
typename Container>
95 void allocate_vector(tags::block_vector,
const OrderingBase<DI,CI>& ordering, Container& c)
97 for (std::size_t i = 0; i < ordering.childOrderingCount(); ++i)
99 if (ordering.containerBlocked())
101 resize_vector(container_tag(c[i]),c[i],ordering.childOrdering(i).blockCount(),
false);
102 allocate_vector(container_tag(c[i]),ordering.childOrdering(i),c[i]);
105 allocate_vector(container_tag(c),ordering.childOrdering(i),c);
109 template<
typename Ordering,
typename Container>
110 void dispatch_vector_allocation(
const Ordering& ordering, Container& c, HierarchicContainerAllocationTag tag)
112 allocate_vector(container_tag(c),ordering,c);
115 template<
typename Ordering,
typename Container>
116 void dispatch_vector_allocation(
const Ordering& ordering, Container& c, FlatContainerAllocationTag tag)
118 resize_vector(container_tag(c),c,ordering.blockCount(),
false);
127 template<typename E,typename Node, typename Tag, bool isLeafTag = std::is_base_of<LeafGridFunctionSpaceTag,Tag>::value >
128 struct vector_descriptor_helper
136 template<
typename E,
typename GFS>
137 struct leaf_vector_descriptor
140 using Backend =
typename GFS::Traits::Backend;
141 using FEM =
typename GFS::Traits::FiniteElementMap;
143 static_assert(Backend::Traits::block_type != Blocking::bcrs,
144 "Dynamically blocked leaf spaces are not supported by this backend.");
147 static const bool support_no_blocking =
true;
154 static const bool support_cascaded_blocking =
155 Backend::Traits::block_type == Blocking::none;
163 std::integral_constant<std::size_t,0>,
164 FiniteElementMapBlockSize,
169 static const std::size_t cumulative_block_size = Backend::Traits::block_size > 0
170 ? Backend::Traits::block_size
171 : detected_cumulative_block_size;
173 static constexpr bool have_valid_block_size = cumulative_block_size > 0;
176 Backend::Traits::block_size == 0 or (detected_cumulative_block_size % cumulative_block_size) == 0,
177 "The vector block size you specified is not compatible with the finite element map"
181 Backend::Traits::block_type != Blocking::fixed or have_valid_block_size,
182 "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."
186 static const std::size_t block_size =
187 Backend::Traits::block_type == Blocking::fixed ? cumulative_block_size : 1;
190 typedef E element_type;
198 template<
typename E,
typename Node,
typename Tag>
199 struct vector_descriptor_helper<E,Node,Tag, true>
201 typedef leaf_vector_descriptor<E,Node> type;
206 struct extract_vector_descriptor
209 template<
typename Node,
typename TreePath>
213 static const bool value =
true;
216 template<
typename Node,
typename TreePath>
220 typedef typename vector_descriptor_helper<E,Node,TypeTree::ImplementationTag<Node>>::type type;
226 template<
typename Sibling,
typename Child>
227 struct cascading_vector_descriptor
231 static const bool support_cascaded_blocking =
232 Sibling::support_cascaded_blocking &&
233 Child::support_cascaded_blocking;
238 static const bool support_no_blocking =
239 (Sibling::support_no_blocking &&
241 typename Sibling::vector_type,
242 typename Child::vector_type
245 static constexpr bool have_valid_block_size =
246 Sibling::have_valid_block_size and Child::have_valid_block_size;
249 static const std::size_t block_size =
250 support_no_blocking ? Sibling::block_size : 1;
253 typedef typename Sibling::element_type element_type;
256 static const std::size_t cumulative_block_size =
257 Sibling::cumulative_block_size + Child::cumulative_block_size;
267 template<
typename D1,
typename D2>
268 struct initial_reduction_switch
270 typedef cascading_vector_descriptor<D1,D2> type;
274 template<
typename D2>
275 struct initial_reduction_switch<void,D2>
281 struct combine_vector_descriptor_siblings
284 template<
typename D1,
typename D2>
286 :
public initial_reduction_switch<D1,D2>
292 template<
typename Child,
typename GFS>
293 struct parent_child_vector_descriptor_data
296 using Backend =
typename GFS::Traits::Backend;
298 static constexpr bool have_valid_block_size = Child::have_valid_block_size;
302 static const bool support_no_blocking =
303 Child::support_no_blocking;
307 static const bool support_cascaded_blocking =
308 Child::support_cascaded_blocking &&
309 Backend::Traits::block_type == Blocking::none;
313 Backend::Traits::block_size == 0,
314 "You cannot specify a block size on interior nodes of the function space tree."
319 static_assert((Backend::Traits::block_type != Blocking::fixed) ||
320 Child::support_cascaded_blocking,
321 "invalid blocking structure.");
324 Backend::Traits::block_type != Blocking::fixed or have_valid_block_size,
325 "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."
330 static const std::size_t block_size =
331 Backend::Traits::block_type == Blocking::fixed
332 ? Child::cumulative_block_size
336 static const std::size_t cumulative_block_size =
337 Child::cumulative_block_size;
340 typedef typename Child::element_type element_type;
343 typedef typename Child::vector_type child_vector_type;
348 template<
typename Data, Blocking>
349 struct parent_child_vector_descriptor;
352 template<
typename Data>
353 struct parent_child_vector_descriptor<
359 static_assert(Data::support_no_blocking,
360 "Cannot combine incompatible child block structures without static blocking. "
361 "Did you want to apply static blocking at this level?");
364 typedef typename Data::child_vector_type vector_type;
368 template<
typename Data>
369 struct parent_child_vector_descriptor<
375 static_assert(Data::support_no_blocking,
376 "Incompatible child block structures detected, cannot perform dynamic blocking. "
377 "Did you want to apply static blocking at this level?");
384 template<
typename Data>
385 struct parent_child_vector_descriptor<
394 typename Data::element_type,
401 struct combine_vector_descriptor_parent
404 template<
typename Child,
typename GFS>
409 :
public parent_child_vector_descriptor<parent_child_vector_descriptor_data<
412 GFS::Traits::Backend::Traits::block_type
421 struct vector_creation_policy
422 :
public TypeTree::TypeAccumulationPolicy<extract_vector_descriptor<E>,
423 combine_vector_descriptor_siblings,
425 combine_vector_descriptor_parent,
426 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:403
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:384
constexpr GeometryType none(unsigned int dim)
Returns a GeometryType representing a singular of dimension dim.
Definition: type.hh:785
Dune namespace.
Definition: alignedallocator.hh:14