3#ifndef DUNE_FUNCTIONS_FUNCTIONSPACEBASES_HIERARCHICVECTORWRAPPER_HH
4#define DUNE_FUNCTIONS_FUNCTIONSPACEBASES_HIERARCHICVECTORWRAPPER_HH
6#include <dune/common/concept.hh>
7#include <dune/common/hybridutilities.hh>
9#include <dune/typetree/utility.hh>
11#include <dune/functions/common/indexaccess.hh>
12#include <dune/functions/common/utility.hh>
13#include <dune/functions/common/type_traits.hh>
14#include <dune/functions/functionspacebases/concepts.hh>
27 template<
class V,
class MultiIndex>
28 struct CoefficientType
30 template<
class E, std::
size_t size>
31 struct DefaultCoefficientTypeHelper
33 using E0 =
decltype(std::declval<E>()[Dune::TypeTree::Indices::_0]);
34 using type =
typename DefaultCoefficientTypeHelper<E0, size-1>::type;
38 struct DefaultCoefficientTypeHelper<E, 0>
44 typename std::enable_if<HasStaticSize<MI>::value,
int>::type = 0>
45 static constexpr std::size_t getStaticSizeOrZero()
47 return StaticSize<MI>::value;
51 typename std::enable_if<not HasStaticSize<MI>::value,
int>::type = 0>
52 static constexpr std::size_t getStaticSizeOrZero()
57 using type =
typename DefaultCoefficientTypeHelper<V, getStaticSizeOrZero<MultiIndex>()>::type;
65 struct DeducedCoefficientTag {};
91template<
class V,
class CO=Imp::DeducedCoefficientTag>
94 template<
class MultiIndex>
96 typename Imp::CoefficientType<V, MultiIndex>::type,
101 using size_type = std::size_t;
103 template<
class C,
class SizeProvider,
104 typename std::enable_if< not models<Concept::HasResize, C>(),
int>::type = 0,
105 typename std::enable_if< not models<Concept::HasSizeMethod, C>(),
int>::type = 0>
106 static void resizeHelper(C& c,
const SizeProvider& sizeProvider,
typename SizeProvider::SizePrefix prefix)
108 auto size = sizeProvider.size(prefix);
110 DUNE_THROW(RangeError,
"Can't resize scalar vector entry v[" << prefix <<
"] to size(" << prefix <<
")=" << size);
113 struct StaticResizeHelper
115 template<
class I,
class C,
class SizeProv
ider>
116 static void apply(I&& i, C& c,
const SizeProvider& sizeProvider,
typename SizeProvider::SizePrefix prefix)
119 resizeHelper(c[i], sizeProvider, prefix);
123 template<
class C,
class SizeProvider,
124 typename std::enable_if< not models<Concept::HasResize, C>(),
int>::type = 0,
125 typename std::enable_if< models<Concept::HasSizeMethod, C>(),
int>::type = 0>
126 static void resizeHelper(C& c,
const SizeProvider& sizeProvider,
typename SizeProvider::SizePrefix prefix)
128 auto size = sizeProvider.size(prefix);
132 if (c.size() != size)
133 DUNE_THROW(RangeError,
"Can't resize statically sized vector entry v[" << prefix <<
"] of size " << c.size() <<
" to size(" << prefix <<
")=" << size);
135 using namespace Dune::Hybrid;
137 forEach(integralRange(Hybrid::size(c)), [&](
auto&& i) {
138 StaticResizeHelper::apply(i, c, sizeProvider, prefix);
142 template<
class C,
class SizeProvider,
143 typename std::enable_if< models<Concept::HasResize, C>(),
int>::type = 0>
144 static void resizeHelper(C& c,
const SizeProvider& sizeProvider,
typename SizeProvider::SizePrefix prefix)
146 auto size = sizeProvider.size(prefix);
150 DUNE_THROW(RangeError,
"Can't resize dynamically sized vector entry v[" << prefix <<
"]. Its size is 0 but the target size is unknown due to size(" << prefix <<
")=0.");
157 for(std::size_t i=0; i<size; ++i)
160 resizeHelper(c[i], sizeProvider, prefix);
170 template<
class MultiIndex>
171 using Entry = Coefficient<MultiIndex>;
177 template<
class SizeProv
ider>
178 void resize(
const SizeProvider& sizeProvider)
180 typename SizeProvider::SizePrefix prefix;
182 resizeHelper(*vector_, sizeProvider, prefix);
185 template<
class MultiIndex>
186 const Entry<MultiIndex>& operator[](
const MultiIndex& index)
const
188 static_assert(not std::is_same<Imp::DeducedCoefficientTag,Entry<MultiIndex>>::value,
"Coefficient type for HierarchicVectorWrapper and given multi-index type cannot be determined automatically!");
189 return hybridMultiIndexAccess<const Entry<MultiIndex>&>(*vector_, index);
192 template<
class MultiIndex>
193 Entry<MultiIndex>& operator[](
const MultiIndex& index)
195 static_assert(not std::is_same<Imp::DeducedCoefficientTag,Entry<MultiIndex>>::value,
"Coefficient type for HierarchicVectorWrapper and given multi-index type cannot be determined automatically!");
196 return hybridMultiIndexAccess<Entry<MultiIndex>&>(*vector_, index);
199 template<
class MultiIndex>
200 const Entry<MultiIndex>& operator()(
const MultiIndex& index)
const
202 static_assert(not std::is_same<Imp::DeducedCoefficientTag,Entry<MultiIndex>>::value,
"Coefficient type for HierarchicVectorWrapper and given multi-index type cannot be determined automatically!");
203 return (*
this)[index];
206 template<
class MultiIndex>
207 Entry<MultiIndex>& operator()(
const MultiIndex& index)
209 static_assert(not std::is_same<Imp::DeducedCoefficientTag,Entry<MultiIndex>>::value,
"Coefficient type for HierarchicVectorWrapper and given multi-index type cannot be determined automatically!");
210 return (*
this)[index];
213 const Vector& vector()
const
239template<
class MultiIndex,
class V,
240 typename std::enable_if< models<Concept::HasIndexAccess, V, MultiIndex>(),
int>::type = 0>
241V& makeHierarchicVectorForMultiIndex(V& v)
248template<
class MultiIndex,
class V,
249 typename std::enable_if< not models<Concept::HasIndexAccess, V, MultiIndex>(),
int>::type = 0>
250HierarchicVectorWrapper< V > makeHierarchicVectorForMultiIndex(V& v)
252 return HierarchicVectorWrapper<V>(v);
A wrapper providing multiindex access to vector entries.
Definition: hierarchicvectorwrapper.hh:93
Definition: polynomial.hh:10
Check if type is a statically sized container.
Definition: type_traits.hh:83