dune-functions  2.6-dev
hierarchicvectorwrapper.hh
Go to the documentation of this file.
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 #include <dune/common/concept.hh>
7 #include <dune/common/hybridutilities.hh>
8 
9 #include <dune/typetree/utility.hh>
10 
15 
16 
17 namespace Dune {
18 namespace Functions {
19 
20 
21 
22 namespace Imp {
23 
24  // Construct default coefficent type from vector and multiindex type
25  // This requires that MultiIndex has a static size. Otherwise the
26  // vector type itself is returned.
27  template<class V, class MultiIndex>
28  struct CoefficientType
29  {
30  template<class E, std::size_t size>
31  struct DefaultCoefficientTypeHelper
32  {
33  using E0 = decltype(std::declval<E>()[Dune::TypeTree::Indices::_0]);
34  using type = typename DefaultCoefficientTypeHelper<E0, size-1>::type;
35  };
36 
37  template<class E>
38  struct DefaultCoefficientTypeHelper<E, 0>
39  {
40  using type = E;
41  };
42 
43  template<class MI,
44  typename std::enable_if<HasStaticSize<MI>::value, int>::type = 0>
45  static constexpr std::size_t getStaticSizeOrZero()
46  {
47  return StaticSize<MI>::value;
48  }
49 
50  template<class MI,
51  typename std::enable_if<not HasStaticSize<MI>::value, int>::type = 0>
52  static constexpr std::size_t getStaticSizeOrZero()
53  {
54  return 0;
55  }
56 
57  using type = typename DefaultCoefficientTypeHelper<V, getStaticSizeOrZero<MultiIndex>()>::type;
58  };
59 
60 } // namespace Imp
61 
62 
63 
84 template<class V, class CO=void>
86 {
87  template<class MultiIndex>
88  using Coefficient = typename std::conditional< std::is_same<void,CO>::value and HasStaticSize<MultiIndex>::value,
89  typename Imp::CoefficientType<V, MultiIndex>::type,
90  CO
91  >::type;
92 
93 
94  using size_type = std::size_t;
95 
96  template<class C, class SizeProvider,
97  typename std::enable_if< not models<Concept::HasResize, C>(), int>::type = 0,
98  typename std::enable_if< not models<Concept::HasSizeMethod, C>(), int>::type = 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  typename std::enable_if< not models<Concept::HasResize, C>(), int>::type = 0,
118  typename std::enable_if< models<Concept::HasSizeMethod, C>(), int>::type = 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  typename std::enable_if< models<Concept::HasResize, C>(), int>::type = 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 
159 public:
160 
161  using Vector = V;
162 
163  template<class MultiIndex>
164  using Entry = Coefficient<MultiIndex>;
165 
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  return hybridMultiIndexAccess<const Entry<MultiIndex>&>(*vector_, index);
182  }
183 
184  template<class MultiIndex>
185  Entry<MultiIndex>& operator[](const MultiIndex& index)
186  {
187  return hybridMultiIndexAccess<Entry<MultiIndex>&>(*vector_, index);
188  }
189 
190  template<class MultiIndex>
191  const Entry<MultiIndex>& operator()(const MultiIndex& index) const
192  {
193  return (*this)[index];
194  }
195 
196  template<class MultiIndex>
197  Entry<MultiIndex>& operator()(const MultiIndex& index)
198  {
199  return (*this)[index];
200  }
201 
202  const Vector& vector() const
203  {
204  return *vector_;
205  }
206 
208  {
209  return *vector_;
210  }
211 
212 private:
213 
214  Vector* vector_;
215 };
216 
217 
218 
219 
220 template<class V>
222 {
223  return HierarchicVectorWrapper<V>(v);
224 }
225 
226 
227 
228 template<class MultiIndex, class V,
229  typename std::enable_if< models<Concept::HasIndexAccess, V, MultiIndex>(), int>::type = 0>
231 {
232  return v;
233 }
234 
235 
236 
237 template<class MultiIndex, class V,
238  typename std::enable_if< not models<Concept::HasIndexAccess, V, MultiIndex>(), int>::type = 0>
240 {
241  return HierarchicVectorWrapper<V>(v);
242 }
243 
244 
245 
246 } // namespace Dune::Functions
247 } // namespace Dune
248 
249 
250 #endif // DUNE_FUNCTIONS_FUNCTIONSPACEBASES_HIERARCHICVECTORWRAPPER_HH
Dune
Definition: polynomial.hh:7
Dune::Functions::makeHierarchicVectorForMultiIndex
V & makeHierarchicVectorForMultiIndex(V &v)
Definition: hierarchicvectorwrapper.hh:230
Dune::Functions::HierarchicVectorWrapper::HierarchicVectorWrapper
HierarchicVectorWrapper(Vector &vector)
Definition: hierarchicvectorwrapper.hh:166
Dune::Functions::HierarchicVectorWrapper::resize
void resize(const SizeProvider &sizeProvider)
Definition: hierarchicvectorwrapper.hh:171
Dune::Functions::HierarchicVectorWrapper::Vector
V Vector
Definition: hierarchicvectorwrapper.hh:161
concepts.hh
Dune::Functions::HierarchicVectorWrapper::vector
Vector & vector()
Definition: hierarchicvectorwrapper.hh:207
indexaccess.hh
Dune::Functions::HierarchicVectorWrapper::operator[]
const Entry< MultiIndex > & operator[](const MultiIndex &index) const
Definition: hierarchicvectorwrapper.hh:179
Dune::Functions::HierarchicVectorWrapper
A wrapper providing multiindex access to vector entries.
Definition: hierarchicvectorwrapper.hh:85
Dune::Functions::hierarchicVector
HierarchicVectorWrapper< V > hierarchicVector(V &v)
Definition: hierarchicvectorwrapper.hh:221
Dune::Functions::HierarchicVectorWrapper::operator()
Entry< MultiIndex > & operator()(const MultiIndex &index)
Definition: hierarchicvectorwrapper.hh:197
utility.hh
type_traits.hh
Dune::Functions::HierarchicVectorWrapper::vector
const Vector & vector() const
Definition: hierarchicvectorwrapper.hh:202
Dune::Functions::HasStaticSize
Check if type is a statically sized container.
Definition: type_traits.hh:81
Dune::Functions::HierarchicVectorWrapper::operator()
const Entry< MultiIndex > & operator()(const MultiIndex &index) const
Definition: hierarchicvectorwrapper.hh:191
Dune::Functions::HierarchicVectorWrapper::operator[]
Entry< MultiIndex > & operator[](const MultiIndex &index)
Definition: hierarchicvectorwrapper.hh:185
Dune::Functions::HierarchicVectorWrapper::Entry
Coefficient< MultiIndex > Entry
Definition: hierarchicvectorwrapper.hh:164