DUNE PDELab (2.7)

gridfunctionspacebase.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_PDELAB_GRIDFUNCTIONSPACE_GRIDFUNCTIONSPACEBASE_HH
4#define DUNE_PDELAB_GRIDFUNCTIONSPACE_GRIDFUNCTIONSPACEBASE_HH
5
6#include <dune/typetree/visitor.hh>
7#include <dune/typetree/traversal.hh>
8
10
11namespace Dune {
12 namespace PDELab {
13
17
18#ifndef DOXYGEN
19
20 // forward declaration for friend declaration
21 template<typename GFS, typename GFSTraits>
22 class GridFunctionSpaceBase;
23
24 namespace impl {
25
26 struct reset_root_space_flag
27 : public TypeTree::DirectChildrenVisitor
28 , public TypeTree::DynamicTraversal
29 {
30
31 template<typename GFS, typename Child, typename TreePath, typename ChildIndex>
32 void afterChild(const GFS& gfs, Child& child, TreePath, ChildIndex) const
33 {
34 if (child._initialized && child._is_root_space)
35 {
36 DUNE_THROW(GridFunctionSpaceHierarchyError,"initialized space cannot become part of larger GridFunctionSpace tree");
37 }
38 child._is_root_space = false;
39 }
40
41 };
42
43 template<typename size_type>
44 struct update_ordering_data;
45
46 // helper class with minimal dependencies. Orderings keep a pointer to this structure and populate it
47 // during their update procedure.
48
49 template<typename size_type>
50 class GridFunctionSpaceOrderingData
51 {
52
53 template<typename,typename>
54 friend class ::Dune::PDELab::GridFunctionSpaceBase;
55
56 template<typename>
57 friend struct update_ordering_data;
58
59 GridFunctionSpaceOrderingData()
60 : _size(0)
61 , _block_count(0)
62 , _global_size(0)
63 , _max_local_size(0)
64 , _is_root_space(true)
65 , _initialized(false)
66 , _size_available(true)
67 {}
68
69 size_type _size;
70 size_type _block_count;
71 size_type _global_size;
72 size_type _max_local_size;
73 bool _is_root_space;
74 bool _initialized;
75 bool _size_available;
76
77 };
78
79 template<typename size_type>
80 struct update_ordering_data
81 : public TypeTree::TreeVisitor
82 , public TypeTree::DynamicTraversal
83 {
84
85 typedef GridFunctionSpaceOrderingData<size_type> Data;
86
87 template<typename Ordering>
88 void update(const Ordering& ordering, bool is_root)
89 {
90 if (ordering._gfs_data)
91 {
92 Data& data = *ordering._gfs_data;
93 // if (data._initialized && data._is_root_space && !is_root)
94 // {
95 // DUNE_THROW(GridFunctionSpaceHierarchyError,"former root space is now part of a larger tree");
96 // }
97 data._initialized = true;
98 data._global_size = _global_size;
99 data._max_local_size = _max_local_size;
100 data._size_available = ordering.update_gfs_data_size(data._size,data._block_count);
101 }
102 }
103
104 template<typename Ordering, typename TreePath>
105 void leaf(const Ordering& ordering, TreePath tp)
106 {
107 update(ordering,tp.size() == 0);
108 }
109
110 template<typename Ordering, typename TreePath>
111 void post(const Ordering& ordering, TreePath tp)
112 {
113 update(ordering,tp.size() == 0);
114 }
115
116 template<typename Ordering>
117 explicit update_ordering_data(const Ordering& ordering)
118 : _global_size(ordering.size())
119 , _max_local_size(ordering.maxLocalSize())
120 {}
121
122 const size_type _global_size;
123 const size_type _max_local_size;
124
125 };
126
127
128 } // namespace impl
129
130#endif // DOXYGEN
131
132
133 template<typename GFS, typename GFSTraits>
134 class GridFunctionSpaceBase
135 : public impl::GridFunctionSpaceOrderingData<typename GFSTraits::SizeType>
136 {
137
138 friend struct impl::reset_root_space_flag;
139
140 public:
141
142 typedef GFSTraits Traits;
143
144 template<typename Backend_, typename OrderingTag_>
145 GridFunctionSpaceBase(Backend_&& backend, OrderingTag_&& ordering_tag)
146 : _backend(std::forward<Backend_>(backend))
147 , _ordering_tag(std::forward<OrderingTag_>(ordering_tag))
148 {
149 TypeTree::applyToTree(gfs(),impl::reset_root_space_flag());
150 }
151
152 typename Traits::SizeType size() const
153 {
154 if (!_initialized)
155 {
156 DUNE_THROW(UninitializedGridFunctionSpaceError,"space is not initialized");
157 }
158 if (!_size_available)
159 {
160 DUNE_THROW(GridFunctionSpaceHierarchyError,
161 "Size cannot be calculated at this point in the GFS tree.");
162 }
163 return _size;
164 }
165
166 typename Traits::SizeType blockCount() const
167 {
168 if (!_initialized)
169 {
170 DUNE_THROW(UninitializedGridFunctionSpaceError,"space is not initialized");
171 }
172 if (!_size_available)
173 {
174 DUNE_THROW(GridFunctionSpaceHierarchyError,
175 "Block count cannot be calculated at this point in the GFS tree.");
176 }
177 return _block_count;
178 }
179
180 typename Traits::SizeType globalSize() const
181 {
182 if (!_initialized)
183 {
184 DUNE_THROW(UninitializedGridFunctionSpaceError,"space is not initialized");
185 }
186 return _global_size;
187 }
188
190 typename Traits::SizeType maxLocalSize () const
191 {
192 if (!_initialized)
193 {
194 DUNE_THROW(UninitializedGridFunctionSpaceError,"space is not initialized");
195 }
196 return _max_local_size;
197 }
198
200
205 void update(bool force = false)
206 {
207 auto entity_set = gfs().entitySet();
208 entity_set.update(force);
209 // We bypass the normal access using ordering() here to avoid a double
210 // update if the Ordering has not been created yet.
211 if (!gfs()._ordering)
212 gfs().create_ordering();
213 update(*gfs()._ordering);
214 }
215
216 const std::string& name() const
217 {
218 return _name;
219 }
220
221 void name(const std::string& name)
222 {
223 _name = name;
224 }
225
226 typename Traits::Backend& backend()
227 {
228 return _backend;
229 }
230
231 const typename Traits::Backend& backend() const
232 {
233 return _backend;
234 }
235
236 typename Traits::OrderingTag& orderingTag()
237 {
238 return _ordering_tag;
239 }
240
241 const typename Traits::OrderingTag& orderingTag() const
242 {
243 return _ordering_tag;
244 }
245
246 bool isRootSpace() const
247 {
248 return _is_root_space;
249 }
250
251 protected:
252
253 template<typename Ordering>
254 void update(Ordering& ordering) const
255 {
256 if (!_is_root_space)
257 {
258 DUNE_THROW(GridFunctionSpaceHierarchyError,"update() may only be called on the root of the function space hierarchy");
259 }
260 ordering.update();
261 TypeTree::applyToTree(ordering,impl::update_ordering_data<typename Traits::SizeType>(ordering));
262 }
263
264 private:
265
266 typedef impl::GridFunctionSpaceOrderingData<typename GFSTraits::SizeType> BaseT;
267
268 GFS& gfs()
269 {
270 return static_cast<GFS&>(*this);
271 }
272
273 const GFS& gfs() const
274 {
275 return static_cast<const GFS&>(*this);
276 }
277
278 std::string _name;
279 typename Traits::Backend _backend;
280 typename Traits::OrderingTag _ordering_tag;
281
282 using BaseT::_size;
283 using BaseT::_block_count;
284 using BaseT::_global_size;
285 using BaseT::_max_local_size;
286 using BaseT::_is_root_space;
287 using BaseT::_initialized;
288 using BaseT::_size_available;
289
290 };
291
292
293 } // namespace PDELab
294} // namespace Dune
295
296#endif // DUNE_PDELAB_GRIDFUNCTIONSPACE_GRIDFUNCTIONSPACEBASE_HH
Called a GridFunctionSpace method that requires initialization of the space.
Definition: exceptions.hh:30
PDELab-specific exceptions.
#define DUNE_THROW(E, m)
Definition: exceptions.hh:216
Traits::SizeType maxLocalSize() const
get max dimension of shape function space
Definition: gridfunctionspacebase.hh:190
void update(bool force=false)
Update the indexing information of the GridFunctionSpace.
Definition: gridfunctionspacebase.hh:205
void applyToTree(Tree &&tree, Visitor &&visitor)
Apply visitor to TypeTree.
Definition: traversal.hh:213
typename impl::_Child< Node, indices... >::type Child
Template alias for the type of a child node given by a list of child indices.
Definition: childextraction.hh:276
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:179
Dune namespace.
Definition: alignedallocator.hh:14
STL namespace.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)