DUNE PDELab (git)

nodes.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_NODES_HH
8#define DUNE_FUNCTIONS_FUNCTIONSPACEBASES_NODES_HH
9
10#include <cassert>
11#include <memory>
12
13#include <dune/common/indices.hh>
14
15#include <dune/typetree/leafnode.hh>
16#include <dune/typetree/powernode.hh>
17#include <dune/typetree/dynamicpowernode.hh>
18#include <dune/typetree/compositenode.hh>
19#include <dune/typetree/traversal.hh>
20#include <dune/typetree/visitor.hh>
21
22namespace Dune {
23 namespace Functions {
24
25
26 namespace Impl {
27
28
29 struct ClearSizeVisitor
30 : public TypeTree::TreeVisitor
31 , public TypeTree::DynamicTraversal
32 {
33
34 template<typename Node, typename TreePath>
35 void pre(Node& node, TreePath treePath)
36 {
37 leaf(node,treePath);
38 node.setSize(0);
39 }
40
41 template<typename Node, typename TreePath>
42 void leaf(Node& node, TreePath treePath)
43 {
44 node.setOffset(offset_);
45 }
46
47 ClearSizeVisitor(std::size_t offset)
48 : offset_(offset)
49 {}
50
51 const std::size_t offset_;
52
53 };
54
55
56 template<typename Entity>
57 struct BindVisitor
58 : public TypeTree::TreeVisitor
59 , public TypeTree::DynamicTraversal
60 {
61
62 template<typename Node, typename TreePath>
63 void pre(Node& node, TreePath)
64 {
65 node.setOffset(offset_);
66 }
67
68 template<typename Node, typename TreePath>
69 void post(Node& node, TreePath)
70 {
71 node.setSize(offset_ - node.offset());
72 }
73
74 template<typename Node, typename TreePath>
75 void leaf(Node& node, TreePath)
76 {
77 node.setOffset(offset_);
78 node.bind(entity_);
79 offset_ += node.size();
80 }
81
82 BindVisitor(const Entity& entity, std::size_t offset = 0)
83 : entity_(entity)
84 , offset_(offset)
85 {}
86
87 const Entity& entity_;
88 std::size_t offset_;
89
90 };
91
92
93 struct InitializeTreeVisitor :
94 public TypeTree::TreeVisitor,
95 public TypeTree::DynamicTraversal
96 {
97 template<typename Node, typename TreePath>
98 void pre(Node& node, TreePath)
99 {
100 node.setTreeIndex(treeIndex_);
101 ++treeIndex_;
102 }
103
104 template<typename Node, typename TreePath>
105 void leaf(Node& node, TreePath)
106 {
107 node.setTreeIndex(treeIndex_);
108 ++treeIndex_;
109 }
110
111 InitializeTreeVisitor(std::size_t treeIndexOffset = 0) :
112 treeIndex_(treeIndexOffset)
113 {}
114
115 std::size_t treeIndex_;
116 };
117
118 } // end namespace Impl
119
120
121 class BasisNodeMixin
122 {
123
124 friend struct Impl::ClearSizeVisitor;
125
126 template<typename>
127 friend struct Impl::BindVisitor;
128
129 friend struct Impl::InitializeTreeVisitor;
130
131 public:
132
133 using size_type = std::size_t;
134
135 BasisNodeMixin() :
136 offset_(0),
137 size_(0),
138 treeIndex_(0)
139 {}
140
141 size_type localIndex(size_type i) const
142 {
143 assert(i < size_);
144 return offset_ + i;
145 }
146
147 size_type size() const
148 {
149 return size_;
150 }
151
152 size_type treeIndex() const
153 {
154 return treeIndex_;
155 }
156
157 protected:
158
159 size_type offset() const
160 {
161 return offset_;
162 }
163
164 void setOffset(const size_type offset)
165 {
166 offset_ = offset;
167 }
168
169 void setSize(const size_type size)
170 {
171 size_ = size;
172 }
173
174 void setTreeIndex(size_type treeIndex)
175 {
176 treeIndex_ = treeIndex;
177 }
178
179 private:
180
181 size_type offset_;
182 size_type size_;
183 size_type treeIndex_;
184
185 };
186
187
188 class LeafBasisNode :
189 public BasisNodeMixin,
190 public TypeTree::LeafNode
191 {};
192
193
194 template<typename T, std::size_t n>
195 class PowerBasisNode :
196 public BasisNodeMixin,
197 public TypeTree::PowerNode<T,n>
198 {
199
200 using Node = TypeTree::PowerNode<T,n>;
201
202 public:
203
204 using Element = typename T::Element;
205
206 PowerBasisNode() = default;
207
208 PowerBasisNode(const typename Node::NodeStorage& children) :
209 Node(children)
210 {}
211
212 const Element& element() const
213 {
214 return this->child(Dune::Indices::_0).element();
215 }
216
217 };
218
219
220 template<typename T>
221 class DynamicPowerBasisNode :
222 public BasisNodeMixin,
223 public TypeTree::DynamicPowerNode<T>
224 {
225
226 using Node = TypeTree::DynamicPowerNode<T>;
227
228 public:
229
230 using Element = typename T::Element;
231
232 DynamicPowerBasisNode (std::size_t children)
233 : Node(children)
234 {}
235
236 DynamicPowerBasisNode (typename Node::NodeStorage children)
237 : Node(std::move(children))
238 {}
239
240 const Element& element() const
241 {
242 return this->child(0).element();
243 }
244
245 };
246
247
248 template<typename... T>
249 class CompositeBasisNode :
250 public BasisNodeMixin,
251 public TypeTree::CompositeNode<T...>
252 {
253
254 using Node = TypeTree::CompositeNode<T...>;
255
256 public:
257
258 using Element = typename Node::template Child<0>::Type::Element;
259
260 CompositeBasisNode() = default;
261
262 CompositeBasisNode(const typename Node::NodeStorage& children) :
263 Node(children)
264 {}
265
266 template<typename... Children>
267 CompositeBasisNode(const std::shared_ptr<Children>&... children) :
268 Node(children...)
269 {}
270
271 const Element& element() const
272 {
273 return this->child(Dune::Indices::_0).element();
274 }
275
276 };
277
278
279 template<typename Tree>
280 void clearSize(Tree& tree, std::size_t offset)
281 {
282 TypeTree::applyToTree(tree,Impl::ClearSizeVisitor(offset));
283 }
284
285 template<typename Tree, typename Entity>
286 void bindTree(Tree& tree, const Entity& entity, std::size_t offset = 0)
287 {
288 Impl::BindVisitor<Entity> visitor(entity,offset);
289 TypeTree::applyToTree(tree,visitor);
290 }
291
292 template<typename Tree>
293 void initializeTree(Tree& tree, std::size_t treeIndexOffset = 0)
294 {
295 Impl::InitializeTreeVisitor visitor(treeIndexOffset);
296 TypeTree::applyToTree(tree,visitor);
297 }
298
299
300 } // namespace Functions
301
302} // namespace Dune
303
304#endif // DUNE_FUNCTIONS_FUNCTIONSPACEBASES_NODES_HH
std::tuple< std::shared_ptr< Children >... > NodeStorage
The type used for storing the children.
Definition: compositenode.hh:36
std::vector< ChildStorageType > NodeStorage
The type used for storing the children.
Definition: dynamicpowernode.hh:67
std::array< std::shared_ptr< T >, k > NodeStorage
The type used for storing the children.
Definition: powernode.hh:77
constexpr index_constant< 0 > _0
Compile time index with value 0.
Definition: indices.hh:52
constexpr auto treePath(const T &... t)
Constructs a new HybridTreePath from the given indices.
Definition: treepath.hh:326
void applyToTree(Tree &&tree, Visitor &&visitor)
Apply visitor to TypeTree.
Definition: traversal.hh:239
ImplementationDefined child(Node &&node, Indices... indices)
Extracts the child of a node given by a sequence of compile-time and run-time indices.
Definition: childextraction.hh:128
Dune namespace.
Definition: alignedallocator.hh:13
constexpr std::integral_constant< std::size_t, sizeof...(II)> size(std::integer_sequence< T, II... >)
Return the size of the sequence.
Definition: integersequence.hh:75
STL namespace.
void post(T &&, TreePath) const
Method for postfix tree traversal.
Definition: visitor.hh:83
void leaf(T &&, TreePath) const
Method for leaf traversal.
Definition: visitor.hh:93
void pre(T &&, TreePath) const
Method for prefix tree traversal.
Definition: visitor.hh:60
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 13, 23:29, 2024)