DUNE-FUNCTIONS (2.7)

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#ifndef DUNE_FUNCTIONS_FUNCTIONSPACEBASES_NODES_HH
4#define DUNE_FUNCTIONS_FUNCTIONSPACEBASES_NODES_HH
5
6#include <dune/common/indices.hh>
7
8#include <dune/typetree/leafnode.hh>
9#include <dune/typetree/powernode.hh>
10#include <dune/typetree/compositenode.hh>
11#include <dune/typetree/traversal.hh>
12#include <dune/typetree/visitor.hh>
13
14namespace Dune {
15 namespace Functions {
16
17
18 namespace Impl {
19
20
21 struct ClearSizeVisitor
22 : public TypeTree::TreeVisitor
23 , public TypeTree::DynamicTraversal
24 {
25
26 template<typename Node, typename TreePath>
27 void pre(Node& node, TreePath treePath)
28 {
29 leaf(node,treePath);
30 node.setSize(0);
31 }
32
33 template<typename Node, typename TreePath>
34 void leaf(Node& node, TreePath treePath)
35 {
36 node.setOffset(offset_);
37 }
38
39 ClearSizeVisitor(std::size_t offset)
40 : offset_(offset)
41 {}
42
43 const std::size_t offset_;
44
45 };
46
47
48 template<typename Entity>
49 struct BindVisitor
50 : public TypeTree::TreeVisitor
51 , public TypeTree::DynamicTraversal
52 {
53
54 template<typename Node, typename TreePath>
55 void pre(Node& node, TreePath treePath)
56 {
57 node.setOffset(offset_);
58 }
59
60 template<typename Node, typename TreePath>
61 void post(Node& node, TreePath treePath)
62 {
63 node.setSize(offset_ - node.offset());
64 }
65
66 template<typename Node, typename TreePath>
67 void leaf(Node& node, TreePath treePath)
68 {
69 node.setOffset(offset_);
70 node.bind(entity_);
71 offset_ += node.size();
72 }
73
74 BindVisitor(const Entity& entity, std::size_t offset = 0)
75 : entity_(entity)
76 , offset_(offset)
77 {}
78
79 const Entity& entity_;
80 std::size_t offset_;
81
82 };
83
84
85 struct InitializeTreeVisitor :
86 public TypeTree::TreeVisitor,
87 public TypeTree::DynamicTraversal
88 {
89 template<typename Node, typename TreePath>
90 void pre(Node& node, TreePath treePath)
91 {
92 node.setTreeIndex(treeIndex_);
93 ++treeIndex_;
94 }
95
96 template<typename Node, typename TreePath>
97 void leaf(Node& node, TreePath treePath)
98 {
99 node.setTreeIndex(treeIndex_);
100 ++treeIndex_;
101 }
102
103 InitializeTreeVisitor(std::size_t treeIndexOffset = 0) :
104 treeIndex_(treeIndexOffset)
105 {}
106
107 std::size_t treeIndex_;
108 };
109
110 } // end namespace Impl
111
112
113 class BasisNodeMixin
114 {
115
116 friend struct Impl::ClearSizeVisitor;
117
118 template<typename>
119 friend struct Impl::BindVisitor;
120
121 friend struct Impl::InitializeTreeVisitor;
122
123 public:
124
125 using size_type = std::size_t;
126
127 BasisNodeMixin() :
128 offset_(0),
129 size_(0),
130 treeIndex_(0)
131 {}
132
133 size_type localIndex(size_type i) const
134 {
135 return offset_ + i;
136 }
137
138 size_type size() const
139 {
140 return size_;
141 }
142
143 size_type treeIndex() const
144 {
145 return treeIndex_;
146 }
147
148 protected:
149
150 size_type offset() const
151 {
152 return offset_;
153 }
154
155 void setOffset(const size_type offset)
156 {
157 offset_ = offset;
158 }
159
160 void setSize(const size_type size)
161 {
162 size_ = size;
163 }
164
165 void setTreeIndex(size_type treeIndex)
166 {
167 treeIndex_ = treeIndex;
168 }
169
170 private:
171
172 size_type offset_;
173 size_type size_;
174 size_type treeIndex_;
175
176 };
177
178
179 class LeafBasisNode :
180 public BasisNodeMixin,
181 public TypeTree::LeafNode
182 {};
183
184
185 template<typename T, std::size_t n>
186 class PowerBasisNode :
187 public BasisNodeMixin,
188 public TypeTree::PowerNode<T,n>
189 {
190
191 using Node = TypeTree::PowerNode<T,n>;
192
193 public:
194
195 using Element = typename T::Element;
196
197 PowerBasisNode() = default;
198
199 PowerBasisNode(const typename Node::NodeStorage& children) :
200 Node(children)
201 {}
202
203 const Element& element() const
204 {
205 return this->child(Dune::Indices::_0).element();
206 }
207
208 };
209
210
211 template<typename... T>
212 class CompositeBasisNode :
213 public BasisNodeMixin,
214 public TypeTree::CompositeNode<T...>
215 {
216
217 using Node = TypeTree::CompositeNode<T...>;
218
219 public:
220
221 using Element = typename Node::template Child<0>::Type;
222
223 CompositeBasisNode() = default;
224
225 CompositeBasisNode(const typename Node::NodeStorage& children) :
226 Node(children)
227 {}
228
229 template<typename... Children>
230 CompositeBasisNode(const shared_ptr<Children>&... children) :
231 Node(children...)
232 {}
233
234 const Element& element() const
235 {
236 return this->child(Dune::Indices::_0).element();
237 }
238
239 };
240
241
242 template<typename Tree>
243 void clearSize(Tree& tree, std::size_t offset)
244 {
245 TypeTree::applyToTree(tree,Impl::ClearSizeVisitor(offset));
246 }
247
248 template<typename Tree, typename Entity>
249 void bindTree(Tree& tree, const Entity& entity, std::size_t offset = 0)
250 {
251 Impl::BindVisitor<Entity> visitor(entity,offset);
252 TypeTree::applyToTree(tree,visitor);
253 }
254
255 template<typename Tree>
256 void initializeTree(Tree& tree, std::size_t treeIndexOffset = 0)
257 {
258 Impl::InitializeTreeVisitor visitor(treeIndexOffset);
259 TypeTree::applyToTree(tree,visitor);
260 }
261
262
263 } // namespace Functions
264
265} // namespace Dune
266
267#endif // DUNE_FUNCTIONS_FUNCTIONSPACEBASES_NODES_HH
Definition: polynomial.hh:10
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)