Dune-Functions 2.11
Loading...
Searching...
No Matches
nodes.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
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_NODES_HH
8#define DUNE_FUNCTIONS_FUNCTIONSPACEBASES_NODES_HH
9
10#include <cassert>
11#include <memory>
12#include <vector>
13#include <array>
14#include <optional>
15
16#include <dune/common/indices.hh>
17#include <dune/common/tuplevector.hh>
18#include <dune/common/typelist.hh>
19
20#include <dune/common/hybridmultiindex.hh>
21#include <dune/common/typetree/traversal.hh>
22
23#ifdef HAVE_DUNE_TYPETREE
24#include <dune/typetree/nodetags.hh>
25#endif
26
27namespace Dune {
28 namespace Functions {
29
30
31 namespace Impl {
32
33 // This class encapsulates the access to the setOffset()
34 // and setTreeIndex() methods of a node. This way we
35 // can hide the methods from the user but still provide
36 // access where this is needed.
37 struct BasisNodeSetupHelper
38 {
39
40 template<class Node, class size_type>
41 static void setSize(Node& node, const size_type size)
42 {
43 node.setSize(size);
44 }
45
46 template<class Node, class size_type>
47 static void setOffset(Node& node, const size_type offset)
48 {
49 node.setOffset(offset);
50 }
51
52 template<class Node, class size_type>
53 static void setTreeIndex(Node& node, const size_type index)
54 {
55 node.setTreeIndex(index);
56 }
57
58 };
59
60
61
62 // A mixin class for generalized child access from
63 // multiple indices or a tree path. The derived class
64 // only has to provide the child(i) method with
65 // a single index for accessing direct children.
66 template<class Impl>
67 class ChildAccessMixIn
68 {
69
70 Impl& asImpl()
71 {
72 return static_cast<Impl&>(*this);
73 }
74
75 const Impl& asImpl() const
76 {
77 return static_cast<const Impl&>(*this);
78 }
79
80 public:
81
87 template<class... II>
88 const auto& child(II... ii) const
89 requires (sizeof...(II) != 1)
90 {
91 return Dune::TypeTree::child(asImpl(), ii...);
92 }
93
99
100 template<class... II>
101 auto& child(II... ii)
102 requires (sizeof...(II) != 1)
103 {
104 return Dune::TypeTree::child(asImpl(), ii...);
105 }
106
112 template<class... II>
113 const auto& child(Dune::HybridMultiIndex<II...> treePath) const
114 {
115 return Dune::TypeTree::child(asImpl(), treePath);
116 }
117
123 template<class... II>
124 auto& child(Dune::HybridMultiIndex<II...> treePath)
125 {
126 return Dune::TypeTree::child(asImpl(), treePath);
127 }
128
129 };
130
131 } // end namespace Impl
132
133
135 {
136
137 friend struct Impl::BasisNodeSetupHelper;
138
139 public:
140
141 using size_type = std::size_t;
142
144 offset_(0),
145 size_(0),
146 treeIndex_(0)
147 {}
148
150 {
151 assert(i < size_);
152 return offset_ + i;
153 }
154
163 {
164 return size_;
165 }
166
175 bool empty() const
176 {
177 return (size_ == 0);
178 }
179
181 {
182 return treeIndex_;
183 }
184
185 protected:
186
188 {
189 return offset_;
190 }
191
193 {
194 offset_ = offset;
195 }
196
198 {
199 size_ = size;
200 }
201
203 {
204 treeIndex_ = treeIndex;
205 }
206
207 private:
208
209 size_type offset_;
210 size_type size_;
211 size_type treeIndex_;
212
213 };
214
215
217 public BasisNodeMixin
218 {
219 public:
220
221 // Begin of node interface
222
223 static constexpr auto degree()
224 {
225 return Dune::index_constant<0>{};
226 }
227
228 // Historic node interface
229
230 static const bool isLeaf [[deprecated]] = true;
231 static const bool isPower [[deprecated]] = false;
232 static const bool isComposite [[deprecated]] = false;
233#ifdef HAVE_DUNE_TYPETREE
234 using NodeTag [[deprecated]] = Dune::TypeTree::LeafNodeTag;
235#endif
236
237 // End of node interface
238
239 };
240
241
242
243 template<typename Node, typename Element>
245 : public BasisNodeMixin
246 {
247 public:
248
249 void bind(const Element& entity)
250 {
251 Node& self = *static_cast<Node*>(this);
252 std::size_t offset = this->offset();
253 Dune::Hybrid::forEach(Dune::range(self.degree()), [&](auto i) {
254 bindTree(self.child(i), entity, offset);
255 offset += self.child(i).size();
256 });
257 this->setSize(offset - this->offset());
258 }
259
260 };
261
262
263
264 template<typename T, std::size_t n>
266 public InnerBasisNodeMixin<PowerBasisNode<T, n>, typename T::Element>,
267 public Impl::ChildAccessMixIn<PowerBasisNode<T, n>>
268 {
269 public:
270
271 // Begin of node interface
272
273 static constexpr auto degree()
274 {
275 return Dune::index_constant<n>{};
276 }
277
278 template<class Index>
279 requires (std::is_convertible_v<Index, std::size_t>)
280 const auto& child(Index i) const
281 {
282 return children_[i].value();
283 }
284
285 template<class Index>
286 requires (std::is_convertible_v<Index, std::size_t>)
287 auto& child(Index i)
288 {
289 return children_[i].value();
290 }
291
292 using Impl::ChildAccessMixIn<PowerBasisNode<T, n>>::child;
293
294 // Historic node interface
295
296 using ChildType [[deprecated]] = T;
297
298 static const bool isLeaf [[deprecated]] = false;
299 static const bool isPower [[deprecated]] = true;
300 static const bool isComposite [[deprecated]] = false;
301#ifdef HAVE_DUNE_TYPETREE
302 using NodeTag [[deprecated]] = Dune::TypeTree::PowerNodeTag;
303#endif
304
305 // End of node interface
306
307 using Element = typename T::Element;
308
309 PowerBasisNode() = default;
310
311 const Element& element() const
312 {
313 return child(Dune::Indices::_0).element();
314 }
315
316 template<class Index, class TT>
317 void setChild(Index i, TT&& t)
318 {
319 children_[i].emplace(std::forward<TT>(t));
320 }
321
322 private:
323 std::array<std::optional<T>, n> children_;
324 };
325
326
327
328 template<typename T>
330 public InnerBasisNodeMixin<DynamicPowerBasisNode<T>, typename T::Element>,
331 public Impl::ChildAccessMixIn<DynamicPowerBasisNode<T>>
332 {
333 public:
334
335 // Begin of node interface
336
337 std::size_t degree() const
338 {
339 return children_.size();
340 }
341
342 template<class Index>
343 requires (std::is_convertible_v<Index, std::size_t>)
344 const auto& child(Index i) const
345 {
346 return children_[i].value();
347 }
348
349 template<class Index>
350 requires (std::is_convertible_v<Index, std::size_t>)
351 auto& child(Index i)
352 {
353 return children_[i].value();
354 }
355
356 using Impl::ChildAccessMixIn<DynamicPowerBasisNode<T>>::child;
357
358 // Historic node interface
359
360 using ChildType [[deprecated]] = T;
361
362 static const bool isLeaf [[deprecated]] = false;
363 static const bool isPower [[deprecated]] = true;
364 static const bool isComposite [[deprecated]] = false;
365#ifdef HAVE_DUNE_TYPETREE
366 using NodeTag [[deprecated]] = Dune::TypeTree::DynamicPowerNodeTag;
367#endif
368
369 // End of node interface
370
371 using Element = typename T::Element;
372
373 DynamicPowerBasisNode (std::size_t children)
374 : children_(children)
375 {}
376
377 const Element& element() const
378 {
379 return child(Dune::Indices::_0).element();
380 }
381
382 template<class Index, class TT>
383 void setChild(Index i, TT&& t)
384 {
385 children_[i].emplace(std::forward<TT>(t));
386 }
387
388 private:
389 std::vector<std::optional<T>> children_;
390 };
391
392
393 template<typename... T>
395 public InnerBasisNodeMixin<CompositeBasisNode<T...>, typename TypeListEntry_t<0, TypeList<T...>>::Element>,
396 public Impl::ChildAccessMixIn<CompositeBasisNode<T...>>
397 {
398 public:
399
400 // Begin of node interface
401
402 static constexpr auto degree()
403 {
404 return Dune::index_constant<sizeof...(T)>{};
405 }
406
407 template<std::size_t i>
408 const auto& child(Dune::index_constant<i> ii) const
409 {
410 return children_[ii].value();
411 }
412
413 template<std::size_t i>
414 auto& child(Dune::index_constant<i> ii)
415 {
416 return children_[ii].value();
417 }
418
419 using Impl::ChildAccessMixIn<CompositeBasisNode<T...>>::child;
420
421 // Historic node interface
422
423 using ChildTypes [[deprecated]] = std::tuple<T...>;
424
425 static const bool isLeaf [[deprecated]] = false;
426 static const bool isPower [[deprecated]] = false;
427 static const bool isComposite [[deprecated]] = true;
428#ifdef HAVE_DUNE_TYPETREE
429 using NodeTag [[deprecated]] = Dune::TypeTree::CompositeNodeTag;
430#endif
431
432 template<std::size_t k>
433 struct [[deprecated]] Child {
434 static_assert((k < degree()), "child index out of range");
435
437 using Type = typename std::tuple_element_t<k, std::tuple<T...>>;
438
439 using type = Type;
440 };
441
442 // End of node interface
443
444 using Element = typename std::tuple_element_t<0, std::tuple<T...>>::Element;
445
447
448 explicit CompositeBasisNode(const T&... children) :
449 children_(children...)
450 {}
451
452 const Element& element() const
453 {
454 return child(Dune::Indices::_0).element();
455 }
456
457 template<std::size_t i, class TT>
458 void setChild (TT&& t, Dune::index_constant<i> ii = {})
459 {
460 children_[ii].emplace(std::forward<TT>(t));
461 }
462
463 private:
464 Dune::TupleVector<std::optional<T>...> children_;
465 };
466
467
468 template<typename Tree, typename Entity>
469 void bindTree(Tree& tree, const Entity& entity, std::size_t offset = 0)
470 {
471 Impl::BasisNodeSetupHelper::setOffset(tree, offset);
472 tree.bind(entity);
473 }
474
475 template<typename Tree>
476 void initializeTree(Tree& tree, std::size_t treeIndexOffset = 0)
477 {
478 Dune::TypeTree::forEachNode(tree, [&](auto& node, const auto& treePath) {
479 Impl::BasisNodeSetupHelper::setTreeIndex(node, treeIndexOffset);
480 ++treeIndexOffset;
481 });
482 }
483
484
485 } // namespace Functions
486
487} // namespace Dune
488
489#endif // DUNE_FUNCTIONS_FUNCTIONSPACEBASES_NODES_HH
Definition monomialset.hh:19
Definition monomialset.hh:19
void bindTree(Tree &tree, const Entity &entity, std::size_t offset=0)
Definition nodes.hh:469
void initializeTree(Tree &tree, std::size_t treeIndexOffset=0)
Definition nodes.hh:476
size_type treeIndex() const
Definition nodes.hh:180
size_type localIndex(size_type i) const
Definition nodes.hh:149
size_type offset() const
Definition nodes.hh:187
bool empty() const
Check if the node is empty.
Definition nodes.hh:175
size_type size() const
Obtain the number of basis function in the local node.
Definition nodes.hh:162
void setOffset(const size_type offset)
Definition nodes.hh:192
std::size_t size_type
Definition nodes.hh:141
BasisNodeMixin()
Definition nodes.hh:143
void setSize(const size_type size)
Definition nodes.hh:197
void setTreeIndex(size_type treeIndex)
Definition nodes.hh:202
Definition nodes.hh:218
static const bool isLeaf
Definition nodes.hh:230
static const bool isComposite
Definition nodes.hh:232
static const bool isPower
Definition nodes.hh:231
static constexpr auto degree()
Definition nodes.hh:223
void bind(const Element &entity)
Definition nodes.hh:249
Definition nodes.hh:268
auto & child(Index i)
Definition nodes.hh:287
const Element & element() const
Definition nodes.hh:311
typename T::Element Element
Definition nodes.hh:307
const auto & child(Index i) const
Definition nodes.hh:280
static constexpr auto degree()
Definition nodes.hh:273
static const bool isComposite
Definition nodes.hh:300
void setChild(Index i, TT &&t)
Definition nodes.hh:317
const Element & element() const
Definition nodes.hh:377
void setChild(Index i, TT &&t)
Definition nodes.hh:383
const auto & child(Index i) const
Definition nodes.hh:344
DynamicPowerBasisNode(std::size_t children)
Definition nodes.hh:373
auto & child(Index i)
Definition nodes.hh:351
std::size_t degree() const
Definition nodes.hh:337
typename typename SubPreBasis::Node::Element Element
Definition nodes.hh:371
static constexpr auto degree()
Definition nodes.hh:402
static const bool isLeaf
Definition nodes.hh:425
auto & child(Dune::index_constant< i > ii)
Definition nodes.hh:414
static const bool isPower
Definition nodes.hh:426
typename std::tuple_element_t< 0, std::tuple< T... > >::Element Element
Definition nodes.hh:444
const Element & element() const
Definition nodes.hh:452
const auto & child(Dune::index_constant< i > ii) const
Definition nodes.hh:408
static const bool isComposite
Definition nodes.hh:427
void setChild(TT &&t, Dune::index_constant< i > ii={})
Definition nodes.hh:458
CompositeBasisNode(const T &... children)
Definition nodes.hh:448
typename std::tuple_element_t< k, std::tuple< T... > > Type
The type of the child.
Definition nodes.hh:437
Type type
Definition nodes.hh:439