Dune-Functions 2.12-git
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
19
22
23namespace Dune {
24 namespace Functions {
25
26
27 namespace Impl {
28
29 // This class encapsulates the access to the setOffset()
30 // and setTreeIndex() methods of a node. This way we
31 // can hide the methods from the user but still provide
32 // access where this is needed.
33 struct BasisNodeSetupHelper
34 {
35
36 template<class Node, class size_type>
37 static void setSize(Node& node, const size_type size)
38 {
39 node.setSize(size);
40 }
41
42 template<class Node, class size_type>
43 static void setOffset(Node& node, const size_type offset)
44 {
45 node.setOffset(offset);
46 }
47
48 template<class Node, class size_type>
49 static void setTreeIndex(Node& node, const size_type index)
50 {
51 node.setTreeIndex(index);
52 }
53
54 };
55
56
57
58 // A mixin class for generalized child access from
59 // multiple indices or a tree path. The derived class
60 // only has to provide the child(i) method with
61 // a single index for accessing direct children.
62 template<class Impl>
63 class ChildAccessMixIn
64 {
65
66 Impl& asImpl()
67 {
68 return static_cast<Impl&>(*this);
69 }
70
71 const Impl& asImpl() const
72 {
73 return static_cast<const Impl&>(*this);
74 }
75
76 public:
77
83 template<class... II>
84 const auto& child(II... ii) const
85 requires (sizeof...(II) != 1)
86 {
87 return Dune::TypeTree::child(asImpl(), ii...);
88 }
89
96 template<class... II>
97 auto& child(II... ii)
98 requires (sizeof...(II) != 1)
99 {
100 return Dune::TypeTree::child(asImpl(), ii...);
101 }
102
108 template<class... II>
109 const auto& child(Dune::HybridMultiIndex<II...> treePath) const
110 {
111 return Dune::TypeTree::child(asImpl(), treePath);
112 }
113
119 template<class... II>
121 {
122 return Dune::TypeTree::child(asImpl(), treePath);
123 }
124
125 };
126
127 } // end namespace Impl
128
129
131 {
132
133 friend struct Impl::BasisNodeSetupHelper;
134
135 public:
136
138
140 offset_(0),
141 size_(0),
142 treeIndex_(0)
143 {}
144
146 {
147 assert(i < size_);
148 return offset_ + i;
149 }
150
159 {
160 return size_;
161 }
162
171 bool empty() const
172 {
173 return (size_ == 0);
174 }
175
177 {
178 return treeIndex_;
179 }
180
181 protected:
182
184 {
185 return offset_;
186 }
187
189 {
190 offset_ = offset;
191 }
192
194 {
195 size_ = size;
196 }
197
199 {
200 treeIndex_ = treeIndex;
201 }
202
203 private:
204
205 size_type offset_;
206 size_type size_;
207 size_type treeIndex_;
208
209 };
210
211
213 public BasisNodeMixin
214 {
215 public:
216
217 // Begin of node interface
218
219 static constexpr auto degree()
220 {
222 }
223
224 // End of node interface
225
226 };
227
228
229
230 template<typename Node, typename Element>
232 : public BasisNodeMixin
233 {
234 public:
235
236 void bind(const Element& entity)
237 {
238 Node& self = *static_cast<Node*>(this);
239 std::size_t offset = this->offset();
240 Dune::Hybrid::forEach(Dune::range(self.degree()), [&](auto i) {
241 bindTree(self.child(i), entity, offset);
242 offset += self.child(i).size();
243 });
244 this->setSize(offset - this->offset());
245 }
246
247 };
248
249
250
251 template<typename T, std::size_t n>
253 public InnerBasisNodeMixin<PowerBasisNode<T, n>, typename T::Element>,
254 public Impl::ChildAccessMixIn<PowerBasisNode<T, n>>
255 {
256 public:
257
258 // Begin of node interface
259
260 static constexpr auto degree()
261 {
263 }
264
265 template<class Index>
266 requires (std::is_convertible_v<Index, std::size_t>)
267 const auto& child(Index i) const
268 {
269 return children_[i].value();
270 }
271
272 template<class Index>
273 requires (std::is_convertible_v<Index, std::size_t>)
274 auto& child(Index i)
275 {
276 return children_[i].value();
277 }
278
279 using Impl::ChildAccessMixIn<PowerBasisNode<T, n>>::child;
280
281 // End of node interface
282
283 using Element = typename T::Element;
284
285 PowerBasisNode() = default;
286
287 const Element& element() const
288 {
289 return child(Dune::Indices::_0).element();
290 }
291
292 template<class Index, class TT>
293 void setChild(Index i, TT&& t)
294 {
295 children_[i].emplace(std::forward<TT>(t));
296 }
297
298 private:
299 std::array<std::optional<T>, n> children_;
300 };
301
302
303
304 template<typename T>
306 public InnerBasisNodeMixin<DynamicPowerBasisNode<T>, typename T::Element>,
307 public Impl::ChildAccessMixIn<DynamicPowerBasisNode<T>>
308 {
309 public:
310
311 // Begin of node interface
312
314 {
315 return children_.size();
316 }
317
318 template<class Index>
319 requires (std::is_convertible_v<Index, std::size_t>)
320 const auto& child(Index i) const
321 {
322 return children_[i].value();
323 }
324
325 template<class Index>
326 requires (std::is_convertible_v<Index, std::size_t>)
327 auto& child(Index i)
328 {
329 return children_[i].value();
330 }
331
332 using Impl::ChildAccessMixIn<DynamicPowerBasisNode<T>>::child;
333
334 // End of node interface
335
336 using Element = typename T::Element;
337
339 : children_(children)
340 {}
341
342 const Element& element() const
343 {
344 return child(Dune::Indices::_0).element();
345 }
346
347 template<class Index, class TT>
348 void setChild(Index i, TT&& t)
349 {
350 children_[i].emplace(std::forward<TT>(t));
351 }
352
353 private:
355 };
356
357
358 template<typename... T>
360 public InnerBasisNodeMixin<CompositeBasisNode<T...>, typename TypeListEntry_t<0, TypeList<T...>>::Element>,
361 public Impl::ChildAccessMixIn<CompositeBasisNode<T...>>
362 {
363 public:
364
365 // Begin of node interface
366
367 static constexpr auto degree()
368 {
369 return Dune::index_constant<sizeof...(T)>{};
370 }
371
372 template<std::size_t i>
373 const auto& child(Dune::index_constant<i> ii) const
374 {
375 return children_[ii].value();
376 }
377
378 template<std::size_t i>
380 {
381 return children_[ii].value();
382 }
383
384 using Impl::ChildAccessMixIn<CompositeBasisNode<T...>>::child;
385
386 // End of node interface
387
388 using Element = typename std::tuple_element_t<0, std::tuple<T...>>::Element;
389
391
392 explicit CompositeBasisNode(const T&... children) :
393 children_(children...)
394 {}
395
396 const Element& element() const
397 {
398 return child(Dune::Indices::_0).element();
399 }
400
401 template<std::size_t i, class TT>
402 void setChild (TT&& t, Dune::index_constant<i> ii = {})
403 {
404 children_[ii].emplace(std::forward<TT>(t));
405 }
406
407 private:
409 };
410
411
412 template<typename Tree, typename Entity>
413 void bindTree(Tree& tree, const Entity& entity, std::size_t offset = 0)
414 {
415 Impl::BasisNodeSetupHelper::setOffset(tree, offset);
416 tree.bind(entity);
417 }
418
419 template<typename Tree>
420 void initializeTree(Tree& tree, std::size_t treeIndexOffset = 0)
421 {
422 Dune::TypeTree::forEachNode(tree, [&](auto& node, const auto& treePath) {
423 Impl::BasisNodeSetupHelper::setTreeIndex(node, treeIndexOffset);
424 ++treeIndexOffset;
425 });
426 }
427
428
429 } // namespace Functions
430
431} // namespace Dune
432
433#endif // DUNE_FUNCTIONS_FUNCTIONSPACEBASES_NODES_HH
void bindTree(Tree &tree, const Entity &entity, std::size_t offset=0)
Definition nodes.hh:413
void initializeTree(Tree &tree, std::size_t treeIndexOffset=0)
Definition nodes.hh:420
int size() const
static constexpr IntegralRange< std::decay_t< T > > range(T &&from, U &&to) noexcept
constexpr void forEach(Range &&range, F &&f)
std::ptrdiff_t index() const
decltype(auto) child(Node &&node, TreePath< Indices... > treePath)
void forEachNode(Tree &&tree, PreNodeFunc &&preNodeFunc, LeafNodeFunc &&leafNodeFunc, PostNodeFunc &&postNodeFunc)
constexpr index_constant< 0 > _0
Definition nodes.hh:131
size_type treeIndex() const
Definition nodes.hh:176
size_type localIndex(size_type i) const
Definition nodes.hh:145
size_type offset() const
Definition nodes.hh:183
bool empty() const
Check if the node is empty.
Definition nodes.hh:171
size_type size() const
Obtain the number of basis function in the local node.
Definition nodes.hh:158
void setOffset(const size_type offset)
Definition nodes.hh:188
std::size_t size_type
Definition nodes.hh:137
BasisNodeMixin()
Definition nodes.hh:139
void setSize(const size_type size)
Definition nodes.hh:193
void setTreeIndex(size_type treeIndex)
Definition nodes.hh:198
Definition nodes.hh:214
static constexpr auto degree()
Definition nodes.hh:219
void bind(const Element &entity)
Definition nodes.hh:236
Definition nodes.hh:255
auto & child(Index i)
Definition nodes.hh:274
const Element & element() const
Definition nodes.hh:287
typename T::Element Element
Definition nodes.hh:283
const auto & child(Index i) const
Definition nodes.hh:267
static constexpr auto degree()
Definition nodes.hh:260
void setChild(Index i, TT &&t)
Definition nodes.hh:293
const Element & element() const
Definition nodes.hh:342
void setChild(Index i, TT &&t)
Definition nodes.hh:348
const auto & child(Index i) const
Definition nodes.hh:320
DynamicPowerBasisNode(std::size_t children)
Definition nodes.hh:338
auto & child(Index i)
Definition nodes.hh:327
std::size_t degree() const
Definition nodes.hh:313
typename T::Element Element
Definition nodes.hh:336
static constexpr auto degree()
Definition nodes.hh:367
typename std::tuple_element_t< 0, std::tuple< T... > >::Element Element
Definition nodes.hh:388
auto & child(Dune::index_constant< i > ii)
Definition nodes.hh:379
const Element & element() const
Definition nodes.hh:396
const auto & child(Dune::index_constant< i > ii) const
Definition nodes.hh:373
void setChild(TT &&t, Dune::index_constant< i > ii={})
Definition nodes.hh:402
CompositeBasisNode(const T &... children)
Definition nodes.hh:392
T emplace(T... args)
T size(T... args)