DUNE PDELab (git)

hierarchicvectorwrapper.hh
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3#ifndef DUNE_FUNCTIONS_FUNCTIONSPACEBASES_HIERARCHICVECTORWRAPPER_HH
4#define DUNE_FUNCTIONS_FUNCTIONSPACEBASES_HIERARCHICVECTORWRAPPER_HH
5
6#ifndef DUNE_FUNCTIONS_HIERARCHICVECTORWRAPPER_TEST_NO_DEPRECATION
7#warning The header dune/functions/functionspacebases/hierarchicvectorwrapper.hh is deprecated and will be removed after release 2.10.
8#endif
9
11#include <dune/common/hybridutilities.hh>
12#include <dune/common/indices.hh>
13
14#include <dune/functions/common/indexaccess.hh>
15#include <dune/functions/common/utility.hh>
16#include <dune/functions/common/type_traits.hh>
17#include <dune/functions/functionspacebases/concepts.hh>
18
19
20namespace Dune {
21namespace Functions {
22
23
24
25namespace Imp {
26
27 // Construct default coefficient type from vector and multiindex type
28 // This requires that MultiIndex has a static size. Otherwise the
29 // vector type itself is returned.
30 template<class V, class MultiIndex>
31 struct CoefficientType
32 {
33 template<class E, std::size_t size>
34 struct DefaultCoefficientTypeHelper
35 {
36 using E0 = decltype(std::declval<E>()[Dune::Indices::_0]);
37 using type = typename DefaultCoefficientTypeHelper<E0, size-1>::type;
38 };
39
40 template<class E>
41 struct DefaultCoefficientTypeHelper<E, 0>
42 {
43 using type = E;
44 };
45
46 using type = typename DefaultCoefficientTypeHelper<V, StaticSizeOrZero<MultiIndex>::value>::type;
47 };
48
49
50
51 // This tag class is used as Coefficient template parameter
52 // for HierarchicVectorWrapper if the coefficient type should
53 // be deduced.
54 struct DeducedCoefficientTag {};
55
56} // namespace Imp
57
58
59
82template<class V, class CO=Imp::DeducedCoefficientTag>
83class
84[[deprecated("HierarchicVectorWrapper is deprecated and will be removed after release 2.10.")]]
86{
87 template<class MultiIndex>
88 using Coefficient = std::conditional_t< std::is_same_v<Imp::DeducedCoefficientTag,CO> and HasStaticSize_v<MultiIndex>,
89 typename Imp::CoefficientType<V, MultiIndex>::type,
90 CO
91 >;
92
93
94 using size_type = std::size_t;
95
96 template<class C, class SizeProvider,
97 std::enable_if_t< not models<Concept::HasResize, C>(), int> = 0,
98 std::enable_if_t< not models<Concept::HasSizeMethod, C>(), int> = 0>
99 static void resizeHelper(C& c, const SizeProvider& sizeProvider, typename SizeProvider::SizePrefix prefix)
100 {
101 auto size = sizeProvider.size(prefix);
102 if (size != 0)
103 DUNE_THROW(RangeError, "Can't resize scalar vector entry v[" << prefix << "] to size(" << prefix << ")=" << size);
104 }
105
106 struct StaticResizeHelper
107 {
108 template<class I, class C, class SizeProvider>
109 static void apply(I&& i, C& c, const SizeProvider& sizeProvider, typename SizeProvider::SizePrefix prefix)
110 {
111 prefix.back() = i;
112 resizeHelper(c[i], sizeProvider, prefix);
113 }
114 };
115
116 template<class C, class SizeProvider,
117 std::enable_if_t< not models<Concept::HasResize, C>(), int> = 0,
118 std::enable_if_t< models<Concept::HasSizeMethod, C>(), int> = 0>
119 static void resizeHelper(C& c, const SizeProvider& sizeProvider, typename SizeProvider::SizePrefix prefix)
120 {
121 auto size = sizeProvider.size(prefix);
122 if (size == 0)
123 return;
124
125 if (c.size() != size)
126 DUNE_THROW(RangeError, "Can't resize statically sized vector entry v[" << prefix << "] of size " << c.size() << " to size(" << prefix << ")=" << size);
127
128 using namespace Dune::Hybrid;
129 prefix.push_back(0);
130 forEach(integralRange(Hybrid::size(c)), [&](auto&& i) {
131 StaticResizeHelper::apply(i, c, sizeProvider, prefix);
132 });
133 }
134
135 template<class C, class SizeProvider,
136 std::enable_if_t< models<Concept::HasResize, C>(), int> = 0>
137 static void resizeHelper(C& c, const SizeProvider& sizeProvider, typename SizeProvider::SizePrefix prefix)
138 {
139 auto size = sizeProvider.size(prefix);
140 if (size==0)
141 {
142 if (c.size()==0)
143 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.");
144 else
145 return;
146 }
147
148 c.resize(size);
149 prefix.push_back(0);
150 for(std::size_t i=0; i<size; ++i)
151 {
152 prefix.back() = i;
153 resizeHelper(c[i], sizeProvider, prefix);
154 }
155 }
156
157
158
159public:
160
161 using Vector = V;
162
163 template<class MultiIndex>
164 using Entry = Coefficient<MultiIndex>;
165
166 HierarchicVectorWrapper(Vector& vector) :
167 vector_(&vector)
168 {}
169
170 template<class SizeProvider>
171 void resize(const SizeProvider& sizeProvider)
172 {
173 typename SizeProvider::SizePrefix prefix;
174 prefix.resize(0);
175 resizeHelper(*vector_, sizeProvider, prefix);
176 }
177
178 template<class MultiIndex>
179 const Entry<MultiIndex>& operator[](const MultiIndex& index) const
180 {
181 static_assert(not std::is_same_v<Imp::DeducedCoefficientTag,Entry<MultiIndex>>, "Coefficient type for HierarchicVectorWrapper and given multi-index type cannot be determined automatically!");
182 return hybridMultiIndexAccess<const Entry<MultiIndex>&>(*vector_, index);
183 }
184
185 template<class MultiIndex>
186 Entry<MultiIndex>& operator[](const MultiIndex& index)
187 {
188 static_assert(not std::is_same_v<Imp::DeducedCoefficientTag,Entry<MultiIndex>>, "Coefficient type for HierarchicVectorWrapper and given multi-index type cannot be determined automatically!");
189 return hybridMultiIndexAccess<Entry<MultiIndex>&>(*vector_, index);
190 }
191
192 template<class MultiIndex>
193 const Entry<MultiIndex>& operator()(const MultiIndex& index) const
194 {
195 static_assert(not std::is_same_v<Imp::DeducedCoefficientTag,Entry<MultiIndex>>, "Coefficient type for HierarchicVectorWrapper and given multi-index type cannot be determined automatically!");
196 return (*this)[index];
197 }
198
199 template<class MultiIndex>
200 Entry<MultiIndex>& operator()(const MultiIndex& index)
201 {
202 static_assert(not std::is_same_v<Imp::DeducedCoefficientTag,Entry<MultiIndex>>, "Coefficient type for HierarchicVectorWrapper and given multi-index type cannot be determined automatically!");
203 return (*this)[index];
204 }
205
206 const Vector& vector() const
207 {
208 return *vector_;
209 }
210
211 Vector& vector()
212 {
213 return *vector_;
214 }
215
216private:
217
218 Vector* vector_;
219};
220
221
222
226template<class V>
227HierarchicVectorWrapper< V > hierarchicVector(V& v)
228{
230}
231
232
233
237template<class MultiIndex, class V,
238 std::enable_if_t< models<Concept::HasIndexAccess, V, MultiIndex>(), int> = 0>
239V& makeHierarchicVectorForMultiIndex(V& v)
240{
241 return v;
242}
243
244
245
249template<class MultiIndex, class V,
250 std::enable_if_t< not models<Concept::HasIndexAccess, V, MultiIndex>(), int> = 0>
251HierarchicVectorWrapper< V > makeHierarchicVectorForMultiIndex(V& v)
252{
253 return HierarchicVectorWrapper<V>(v);
254}
255
256
257
258} // namespace Dune::Functions
259} // namespace Dune
260
261
262#endif // DUNE_FUNCTIONS_FUNCTIONSPACEBASES_HIERARCHICVECTORWRAPPER_HH
A wrapper providing multiindex access to vector entries.
Definition: hierarchicvectorwrapper.hh:86
Default exception class for range errors.
Definition: exceptions.hh:254
Infrastructure for concepts.
constexpr index_constant< 0 > _0
Compile time index with value 0.
Definition: indices.hh:52
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
constexpr void forEach(Range &&range, F &&f)
Range based for loop.
Definition: hybridutilities.hh:256
constexpr auto integralRange(const Begin &begin, const End &end)
Create an integral range.
Definition: hybridutilities.hh:172
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
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)