DUNE-FUNCTIONS (unstable)

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