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>
8#include <dune/common/indices.hh>
26 template<
class V,
class MultiIndex>
27 struct CoefficientType
29 template<
class E, std::
size_t size>
30 struct DefaultCoefficientTypeHelper
32 using E0 =
decltype(std::declval<E>()[Dune::Indices::_0]);
33 using type =
typename DefaultCoefficientTypeHelper<E0, size-1>::type;
37 struct DefaultCoefficientTypeHelper<E, 0>
43 typename std::enable_if<HasStaticSize<MI>::value,
int>::type = 0>
44 static constexpr std::size_t getStaticSizeOrZero()
46 return StaticSize<MI>::value;
50 typename std::enable_if<not HasStaticSize<MI>::value,
int>::type = 0>
51 static constexpr std::size_t getStaticSizeOrZero()
56 using type =
typename DefaultCoefficientTypeHelper<V, getStaticSizeOrZero<MultiIndex>()>::type;
64 struct DeducedCoefficientTag {};
90template<
class V,
class CO=Imp::DeducedCoefficientTag>
93 template<
class MultiIndex>
95 typename Imp::CoefficientType<V, MultiIndex>::type,
100 using size_type = std::size_t;
102 template<
class C,
class SizeProvider,
103 typename std::enable_if< not models<Concept::HasResize, C>(),
int>::type = 0,
104 typename std::enable_if< not models<Concept::HasSizeMethod, C>(),
int>::type = 0>
105 static void resizeHelper(C& c,
const SizeProvider& sizeProvider,
typename SizeProvider::SizePrefix prefix)
107 auto size = sizeProvider.size(prefix);
109 DUNE_THROW(RangeError,
"Can't resize scalar vector entry v[" << prefix <<
"] to size(" << prefix <<
")=" << size);
112 struct StaticResizeHelper
114 template<
class I,
class C,
class SizeProv
ider>
115 static void apply(I&& i, C& c,
const SizeProvider& sizeProvider,
typename SizeProvider::SizePrefix prefix)
118 resizeHelper(c[i], sizeProvider, prefix);
122 template<
class C,
class SizeProvider,
123 typename std::enable_if< not models<Concept::HasResize, C>(),
int>::type = 0,
124 typename std::enable_if< models<Concept::HasSizeMethod, C>(),
int>::type = 0>
125 static void resizeHelper(C& c,
const SizeProvider& sizeProvider,
typename SizeProvider::SizePrefix prefix)
127 auto size = sizeProvider.size(prefix);
131 if (c.size() != size)
132 DUNE_THROW(RangeError,
"Can't resize statically sized vector entry v[" << prefix <<
"] of size " << c.size() <<
" to size(" << prefix <<
")=" << size);
134 using namespace Dune::Hybrid;
136 forEach(integralRange(Hybrid::size(c)), [&](
auto&& i) {
137 StaticResizeHelper::apply(i, c, sizeProvider, prefix);
141 template<
class C,
class SizeProvider,
142 typename std::enable_if< models<Concept::HasResize, C>(),
int>::type = 0>
143 static void resizeHelper(C& c,
const SizeProvider& sizeProvider,
typename SizeProvider::SizePrefix prefix)
145 auto size = sizeProvider.size(prefix);
149 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.");
156 for(std::size_t i=0; i<size; ++i)
159 resizeHelper(c[i], sizeProvider, prefix);
169 template<
class MultiIndex>
170 using Entry = Coefficient<MultiIndex>;
176 template<
class SizeProv
ider>
177 void resize(
const SizeProvider& sizeProvider)
179 typename SizeProvider::SizePrefix prefix;
181 resizeHelper(*vector_, sizeProvider, prefix);
184 template<
class MultiIndex>
187 static_assert(not std::is_same<Imp::DeducedCoefficientTag,Entry<MultiIndex>>::value,
"Coefficient type for HierarchicVectorWrapper and given multi-index type cannot be determined automatically!");
188 return hybridMultiIndexAccess<const Entry<MultiIndex>&>(*vector_, index);
191 template<
class MultiIndex>
194 static_assert(not std::is_same<Imp::DeducedCoefficientTag,Entry<MultiIndex>>::value,
"Coefficient type for HierarchicVectorWrapper and given multi-index type cannot be determined automatically!");
195 return hybridMultiIndexAccess<Entry<MultiIndex>&>(*vector_, index);
198 template<
class MultiIndex>
201 static_assert(not std::is_same<Imp::DeducedCoefficientTag,Entry<MultiIndex>>::value,
"Coefficient type for HierarchicVectorWrapper and given multi-index type cannot be determined automatically!");
202 return (*
this)[index];
205 template<
class MultiIndex>
208 static_assert(not std::is_same<Imp::DeducedCoefficientTag,Entry<MultiIndex>>::value,
"Coefficient type for HierarchicVectorWrapper and given multi-index type cannot be determined automatically!");
209 return (*
this)[index];
238template<
class MultiIndex,
class V,
239 typename std::enable_if< models<Concept::HasIndexAccess, V, MultiIndex>(),
int>::type = 0>
247template<
class MultiIndex,
class V,
248 typename std::enable_if< not models<Concept::HasIndexAccess, V, MultiIndex>(),
int>::type = 0>
Definition: polynomial.hh:10
V & makeHierarchicVectorForMultiIndex(V &v)
Definition: hierarchicvectorwrapper.hh:240
HierarchicVectorWrapper< V > hierarchicVector(V &v)
Definition: hierarchicvectorwrapper.hh:231
Check if type is a statically sized container.
Definition: type_traits.hh:83
A wrapper providing multiindex access to vector entries.
Definition: hierarchicvectorwrapper.hh:92
Entry< MultiIndex > & operator()(const MultiIndex &index)
Definition: hierarchicvectorwrapper.hh:206
Entry< MultiIndex > & operator[](const MultiIndex &index)
Definition: hierarchicvectorwrapper.hh:192
const Entry< MultiIndex > & operator[](const MultiIndex &index) const
Definition: hierarchicvectorwrapper.hh:185
Vector & vector()
Definition: hierarchicvectorwrapper.hh:217
V Vector
Definition: hierarchicvectorwrapper.hh:167
Coefficient< MultiIndex > Entry
Definition: hierarchicvectorwrapper.hh:170
const Vector & vector() const
Definition: hierarchicvectorwrapper.hh:212
HierarchicVectorWrapper(Vector &vector)
Definition: hierarchicvectorwrapper.hh:172
const Entry< MultiIndex > & operator()(const MultiIndex &index) const
Definition: hierarchicvectorwrapper.hh:199
void resize(const SizeProvider &sizeProvider)
Definition: hierarchicvectorwrapper.hh:177