DUNE-FUNCTIONS (2.8)

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