Loading [MathJax]/extensions/tex2jax.js

DUNE-FUNCTIONS (unstable)

containerdescriptors.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_CONTAINERDESCRIPTORS_HH
8#define DUNE_FUNCTIONS_FUNCTIONSPACEBASES_CONTAINERDESCRIPTORS_HH
9
10#include <array>
11#include <cassert>
12#include <functional>
13#include <type_traits>
14#include <vector>
15
16#include <dune/common/filledarray.hh>
17#include <dune/common/tuplevector.hh>
18#include <dune/common/typeutilities.hh>
19#include <dune/common/hybridutilities.hh>
20#include <dune/common/rangeutilities.hh>
21
22#include <dune/functions/common/type_traits.hh>
23#include <dune/functions/functionspacebases/basistags.hh>
24
48namespace Dune::Functions {
49namespace ContainerDescriptors {
50
52struct Unknown {};
53
54} // end namespace ContainerDescriptors
55
56namespace Impl {
57
58template<class PreBasis>
59auto containerDescriptorImpl(const PreBasis& preBasis, Dune::PriorityTag<1>)
60 -> decltype(preBasis.containerDescriptor())
61{
62 return preBasis.containerDescriptor();
63}
64
65template<class PreBasis>
66auto containerDescriptorImpl(const PreBasis& preBasis, Dune::PriorityTag<0>)
67{
68 return ContainerDescriptors::Unknown{};
69}
70
71} // end namespace Impl
72
74template<class PreBasis>
75auto containerDescriptor(const PreBasis& preBasis)
76{
77 return Impl::containerDescriptorImpl(preBasis, Dune::PriorityTag<2>{});
78}
79
80
81namespace ContainerDescriptors {
82
84struct Value
85{
87 template<class Index>
88 Value operator[] (const Index&) const { return {}; }
89
91 static constexpr std::size_t size () { return 0; }
92};
93
95template<class... Children>
96using Tuple = Dune::TupleVector<Children...>;
97
100template<class Child0, class... Children,
101 std::enable_if_t<(sizeof...(Children) > 0), int> = 0,
102 std::enable_if_t<(...|| (not std::is_same_v<Child0, Children>)), int> = 0>
103auto makeDescriptor (Child0 child0, Children... children)
104{
105 using Descriptor = Tuple<Child0,Children...>;
106 return Descriptor{std::move(child0),std::move(children)...};
107}
108
109
111template<class Child, std::size_t n>
112using Array = std::array<Child, n>;
113
115template<class Child0, class... Children,
116 std::enable_if_t<(std::is_same_v<Child0, Children> &&...), int> = 0>
117auto makeDescriptor (Child0 child, Children... children)
118{
119 using Descriptor = Array<Child0,1+sizeof...(Children)>;
120 return Descriptor{std::move(child),std::move(children)...};
121}
122
123
125template<class Child>
126using Vector = std::vector<Child>;
127
129template<class Child, std::size_t n>
131{
133 template<class C = Child,
134 std::enable_if_t<std::is_default_constructible_v<C>, int> = 0>
136 : child_{}
137 {}
138
140 explicit UniformArray (Child child)
141 : child_{std::move(child)}
142 {}
143
145 template<class Index>
146 const Child& operator[] (const Index& /*i*/) const { return child_; }
147
149 static constexpr std::size_t size () { return n; }
150
151private:
152 Child child_;
153};
154
156template<std::size_t n>
157using FlatArray = UniformArray<Value,n>;
158
160template<class Child, std::size_t n>
161auto makeUniformDescriptor (std::integral_constant<std::size_t,n>, Child child)
162{
163 return UniformArray<Child,n>{std::move(child)};
164}
165
166
168template<class Child>
170{
172 template<class C = Child,
173 std::enable_if_t<std::is_default_constructible_v<C>, int> = 0>
174 explicit UniformVector (std::size_t size)
175 : size_{size}
176 , child_{}
177 {}
178
180 UniformVector (std::size_t size, Child child)
181 : size_{size}
182 , child_{std::move(child)}
183 {}
184
186 template<class Index>
187 const Child& operator[] (const Index& /*i*/) const { return child_; }
188
190 std::size_t size () const { return size_; }
191
192private:
193 std::size_t size_;
194 Child child_;
195};
196
198using FlatVector = UniformVector<Value>;
199
201template<class Child>
202auto makeUniformDescriptor (std::size_t n, Child child)
203{
204 return UniformVector<Child>{n,std::move(child)};
205}
206
207namespace Impl {
208
209template<class InnerFunc, class LeafFunc>
210struct TreeTransform
211{
212 TreeTransform (const InnerFunc& innerFunc, const LeafFunc& leafFunc)
213 : innerFunc_(innerFunc)
214 , leafFunc_(leafFunc)
215 {}
216
217 Unknown operator() (const Unknown& tree) const
218 {
219 return tree;
220 }
221
222 auto operator() (const Value& tree) const
223 {
224 return leafFunc_(tree);
225 }
226
227 template<class... V>
228 auto operator() (const Tuple<V...>& tree) const
229 {
230 return unpackIntegerSequence([&](auto... ii) {
231 return makeDescriptor(innerFunc_(tree[ii])...);
232 }, std::make_index_sequence<sizeof...(V)>());
233 }
234
235 template<class V, std::size_t n>
236 auto operator() (const Array<V,n>& tree) const
237 {
238 return unpackIntegerSequence([&](auto... ii) {
239 return makeDescriptor(innerFunc_(tree[ii])...);
240 }, std::make_index_sequence<n>());
241 }
242
243 template<class V>
244 auto operator() (const Vector<V>& tree) const
245 {
246 using W = decltype(innerFunc_(tree[0]));
247 Vector<W> result;
248 result.reserve(tree.size());
249 for (std::size_t i = 0; i < tree.size(); ++i)
250 result.emplace_back(innerFunc_(tree[i]));
251 return result;
252 }
253
254 template<class V, std::size_t n>
255 auto operator() (const UniformArray<V,n>& tree) const
256 {
257 return makeUniformDescriptor(Dune::index_constant<n>{}, innerFunc_(tree[0]));
258 }
259
260 template<class V>
261 auto operator() (const UniformVector<V>& tree) const
262 {
263 return makeUniformDescriptor(tree.size(), innerFunc_(tree[0]));
264 }
265
266private:
267 InnerFunc innerFunc_;
268 LeafFunc leafFunc_;
269};
270
271
282template<class Size, class T>
283auto appendToTree (Size s, const T& tree)
284{
285 auto transform = TreeTransform(
286 [s](auto&& node) { return appendToTree(s, node); },
287 [s](auto&& node) { return makeUniformDescriptor(s, node); });
288 return transform(tree);
289}
290
292template<class... Child>
293auto flatLexicographic (Child... child)
294{
295 if constexpr ((std::is_same_v<Child, FlatVector> && ...))
296 return FlatVector((child.size() + ...));
297 else
298 return Unknown{};
299}
300
302template<class N, class Child>
303auto flatLexicographicN (N n, Child child)
304{
305 return Unknown{};
306}
307
309template<class N, class GrandChild>
310auto flatLexicographicN (N n, UniformVector<GrandChild> child)
311{
312 return UniformVector<GrandChild>{child.size()*n, child[0]};
313}
314
316template<class N, class GrandChild, std::size_t m>
317auto flatLexicographicN (N n, UniformArray<GrandChild, m> child)
318{
319 if constexpr (std::is_same_v<N, std::size_t>)
320 return UniformVector<GrandChild>{n*m, child[0]};
321 else
322 return UniformArray<GrandChild, N::value*m>{child[0]};
323}
324
326template<class N, class GrandChild>
327auto flatLexicographicN (N n, Vector<GrandChild> child)
328{
329 auto result = Vector<GrandChild>{};
330 result.reserve(child.size()*n);
331 for (auto j : Dune::range(n))
332 for (auto i : Dune::range(child.size()))
333 result.emplace_back(child[i]);
334 return result;
335}
336
338template<class N, class GrandChild, std::size_t m>
339auto flatLexicographicN (N n, Array<GrandChild, m> child)
340{
341 if constexpr (std::is_same_v<N, std::size_t>)
342 {
343 auto result = Vector<GrandChild>{};
344 result.reserve(child.size()*n);
345 for (auto j : Dune::range(n))
346 for (auto i : Dune::range(child.size()))
347 result.emplace_back(child[i]);
348 return result;
349 }
350 else
351 {
352 auto result = Array<GrandChild, N::value*m>{};
353 for (auto j : Dune::range(n))
354 for (auto i : Dune::range(child.size()))
355 result.emplace_back(child[i]);
356 return result;
357 }
358}
359
361template<class N, class... GrandChild>
362auto flatLexicographicN (N n, Tuple<GrandChild...> child)
363{
364 constexpr std::size_t m = sizeof...(GrandChild);
365 return Dune::unpackIntegerSequence([&](auto... i) {
366 return makeDescriptor(std::get<i%m>(child)...);
367 }, std::make_index_sequence<n*m>{});
368}
369
371template<class N, class Child>
372auto flatInterleavedN (N n, Child child)
373{
374 return Unknown{};
375}
376
378template<class N, class GrandChild>
379auto flatInterleavedN (N n, UniformVector<GrandChild> child)
380{
381 return UniformVector<GrandChild>{child.size()*n, child[0]};
382}
383
385template<class N, class GrandChild, std::size_t m>
386auto flatInterleavedN (N n, UniformArray<GrandChild, m> child)
387{
388 if constexpr (std::is_integral_v<N>)
389 return UniformVector<GrandChild>{n*m, child[0]};
390 else
391 return UniformArray<GrandChild, N::value*m>{child[0]};
392}
393
395template<class N, class GrandChild>
396auto flatInterleavedN (N n, Vector<GrandChild> child)
397{
398 auto result = Vector<GrandChild>{};
399 result.reserve(child.size()*n);
400 for (auto i : Dune::range(child.size()))
401 for (auto j : Dune::range(n))
402 result.emplace_back(child[i]);
403 return result;
404}
405
407template<class N, class GrandChild, std::size_t m>
408auto flatInterleavedN (N n, Array<GrandChild, m> child)
409{
410 if constexpr (std::is_integral_v<N>)
411 {
412 auto result = Vector<GrandChild>{};
413 result.reserve(child.size()*n);
414 for (auto i : Dune::range(child.size()))
415 for (auto j : Dune::range(n))
416 result.emplace_back(child[i]);
417 return result;
418 }
419 else
420 {
421 auto result = Array<GrandChild, N::value*m>{};
422 for (auto i : Dune::range(child.size()))
423 for (auto j : Dune::range(n))
424 result.emplace_back(child[i]);
425 return result;
426 }
427}
428
430template<class N, class... GrandChild>
431auto flatInterleavedN (N n, Tuple<GrandChild...> child)
432{
433 constexpr std::size_t m = sizeof...(GrandChild);
434 return Dune::unpackIntegerSequence([&](auto... i) {
435 return makeDescriptor(std::get<i/n>(child)...);
436 }, std::make_index_sequence<n*m>{});
437}
438
439} // end namespace Impl
440} // end namespace ContainerDescriptors
441} // end namespace Dune::Functions
442
443#endif // DUNE_FUNCTIONS_FUNCTIONSPACEBASES_CONTAINERDESCRIPTORS_HH
constexpr FlatLexicographic flatLexicographic()
Creates a lexicographic merging of direct children without blocking.
Definition: basistags.hh:192
Descriptor for arrays with all children identical and the number of children a static size.
Definition: containerdescriptors.hh:131
static constexpr std::size_t size()
The static size information, i.e., number of children.
Definition: containerdescriptors.hh:149
UniformArray()
Default constructor. Is enable if the child-type is default constructible.
Definition: containerdescriptors.hh:135
UniformArray(Child child)
Constructor that stores a single child only.
Definition: containerdescriptors.hh:140
const Child & operator[](const Index &) const
Access the i'th child that is always the same, i.e., child_.
Definition: containerdescriptors.hh:146
Uniform descriptor with dynamic size.
Definition: containerdescriptors.hh:170
UniformVector(std::size_t size, Child child)
Constructor that stores the size and a single child only.
Definition: containerdescriptors.hh:180
std::size_t size() const
The dynamic size information, i.e., number of children.
Definition: containerdescriptors.hh:190
UniformVector(std::size_t size)
Default constructor with size. Is enable if the child-type is default constructible.
Definition: containerdescriptors.hh:174
const Child & operator[](const Index &) const
Access the i'th child that is always the same, i.e., child_.
Definition: containerdescriptors.hh:187
Fallback container descriptor if nothing else fits.
Definition: containerdescriptors.hh:52
The node in the descriptor tree representing a value placeholder.
Definition: containerdescriptors.hh:85
static constexpr std::size_t size()
A value placeholder does not have any sub-descriptors, thus its size is zero.
Definition: containerdescriptors.hh:91
Value operator[](const Index &) const
The child access method is only available for the interface, but should not be called.
Definition: containerdescriptors.hh:88
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden & Uni Heidelberg  |  generated with Hugo v0.111.3 (Mar 12, 23:28, 2025)