dune-pdelab 2.7-git
Loading...
Searching...
No Matches
gridfunctionspacebase.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#ifndef DUNE_PDELAB_GRIDFUNCTIONSPACE_GRIDFUNCTIONSPACEBASE_HH
4#define DUNE_PDELAB_GRIDFUNCTIONSPACE_GRIDFUNCTIONSPACEBASE_HH
5
6#include <optional>
7
8#include <dune/typetree/visitor.hh>
9#include <dune/typetree/traversal.hh>
10
12
13namespace Dune {
14 namespace PDELab {
15
19
20#ifndef DOXYGEN
21
22 // forward declaration for friend declaration
23 template<typename GFS, typename GFSTraits>
24 class GridFunctionSpaceBase;
25
26 namespace impl {
27
28 struct reset_root_space_flag
29 : public TypeTree::DirectChildrenVisitor
30 , public TypeTree::DynamicTraversal
31 {
32
33 template<typename GFS, typename Child, typename TreePath, typename ChildIndex>
34 void afterChild(const GFS& gfs, Child& child, TreePath, ChildIndex) const
35 {
36 if (child._initialized && child._is_root_space)
37 {
38 DUNE_THROW(GridFunctionSpaceHierarchyError,"initialized space cannot become part of larger GridFunctionSpace tree");
39 }
40 child._is_root_space = false;
41 }
42
43 };
44
45 template<typename size_type>
46 struct update_ordering_data;
47
48 // helper class with minimal dependencies. Orderings keep a pointer to this structure and populate it
49 // during their update procedure.
50
51 template<typename size_type>
52 class GridFunctionSpaceOrderingData
53 {
54
55 template<typename,typename>
56 friend class ::Dune::PDELab::GridFunctionSpaceBase;
57
58 template<typename>
59 friend struct update_ordering_data;
60
61 GridFunctionSpaceOrderingData()
62 : _size(0)
63 , _block_count(0)
64 , _global_size(0)
65 , _max_local_size(0)
66 , _is_root_space(true)
67 , _initialized(false)
68 , _size_available(true)
69 {}
70
71 size_type _size;
72 size_type _block_count;
73 size_type _global_size;
74 size_type _max_local_size;
75 bool _is_root_space;
76 bool _initialized;
77 bool _size_available;
78
79 };
80
81 template<typename size_type>
82 struct update_ordering_data
83 : public TypeTree::TreeVisitor
84 , public TypeTree::DynamicTraversal
85 {
86
87 typedef GridFunctionSpaceOrderingData<size_type> Data;
88
89 template<typename Ordering>
90 void update(const Ordering& ordering, bool is_root)
91 {
92 if (ordering._gfs_data)
93 {
94 Data& data = *ordering._gfs_data;
95 // if (data._initialized && data._is_root_space && !is_root)
96 // {
97 // DUNE_THROW(GridFunctionSpaceHierarchyError,"former root space is now part of a larger tree");
98 // }
99 data._initialized = true;
100 data._global_size = _global_size;
101 data._max_local_size = _max_local_size;
102 data._size_available = ordering.update_gfs_data_size(data._size,data._block_count);
103 }
104 }
105
106 template<typename Ordering, typename TreePath>
107 void leaf(const Ordering& ordering, TreePath tp)
108 {
109 update(ordering,tp.size() == 0);
110 }
111
112 template<typename Ordering, typename TreePath>
113 void post(const Ordering& ordering, TreePath tp)
114 {
115 update(ordering,tp.size() == 0);
116 }
117
118 template<typename Ordering>
119 explicit update_ordering_data(const Ordering& ordering)
120 : _global_size(ordering.size())
121 , _max_local_size(ordering.maxLocalSize())
122 {}
123
124 const size_type _global_size;
125 const size_type _max_local_size;
126
127 };
128
129
131 template<class EntitySet>
132 struct common_entity_set
133 : public TypeTree::TreeVisitor
134 , public TypeTree::DynamicTraversal
135 {
136 template<typename T, typename TreePath>
137 void leaf(T&& t, TreePath treePath) {
138 if (not _entity_set)
139 _entity_set = t.entitySet();
140 else if (*_entity_set != t.entitySet())
141 DUNE_THROW(
142 GridFunctionSpaceHierarchyError,
143 "Use same entity sets for every space that is entity blocked! "
144 "A reason for getting this error is creating GridFunctionSpaces with "
145 "a grid view in the constructor. To solve this, create an entity set"
146 "(e.g. AllEntitySet<GV>) and use one instance to construct all of your GridFunctionSpaces."
147);
148 }
149
150 std::optional<EntitySet> _entity_set;
151 };
152
158 template<class EntitySet>
159 struct update_leaf_entity_set
160 : public TypeTree::TreeVisitor
161 , public TypeTree::DynamicTraversal
162 {
163 update_leaf_entity_set(const std::optional<EntitySet>& entity_set, bool force_update)
164 : _force_update{force_update}
165 , _entity_set{entity_set}
166 {}
167
168 template<typename GFSNode, typename TreePath>
169 void leaf(GFSNode&& gfs_node, TreePath treePath) {
170 if (not _entity_set)
171 _entity_set = gfs_node.entitySet();
172 if (*_entity_set != gfs_node.entitySet()) {
173 gfs_node.entitySet().update(_force_update);
174 _entity_set = gfs_node.entitySet();
175 }
176 }
177
178 bool _force_update;
179 std::optional<EntitySet> _entity_set;
180 };
181
182 } // namespace impl
183
184#endif // DOXYGEN
185
186
187 template<typename GFS, typename GFSTraits>
189 : public impl::GridFunctionSpaceOrderingData<typename GFSTraits::SizeType>
190 {
191
192 friend struct impl::reset_root_space_flag;
193
194 public:
195
196 typedef GFSTraits Traits;
197
198 template<typename Backend_, typename OrderingTag_>
199 GridFunctionSpaceBase(Backend_&& backend, OrderingTag_&& ordering_tag)
200 : _backend(std::forward<Backend_>(backend))
201 , _ordering_tag(std::forward<OrderingTag_>(ordering_tag))
202 {
203 TypeTree::applyToTree(gfs(),impl::reset_root_space_flag());
204 }
205
206 typename Traits::SizeType size() const
207 {
208 if (!_initialized)
209 {
210 DUNE_THROW(UninitializedGridFunctionSpaceError,"space is not initialized");
211 }
212 if (!_size_available)
213 {
215 "Size cannot be calculated at this point in the GFS tree.");
216 }
217 return _size;
218 }
219
220 typename Traits::SizeType blockCount() const
221 {
222 if (!_initialized)
223 {
224 DUNE_THROW(UninitializedGridFunctionSpaceError,"space is not initialized");
225 }
226 if (!_size_available)
227 {
229 "Block count cannot be calculated at this point in the GFS tree.");
230 }
231 return _block_count;
232 }
233
234 typename Traits::SizeType globalSize() const
235 {
236 if (!_initialized)
237 {
238 DUNE_THROW(UninitializedGridFunctionSpaceError,"space is not initialized");
239 }
240 return _global_size;
241 }
242
244 typename Traits::SizeType maxLocalSize () const
245 {
246 if (!_initialized)
247 {
248 DUNE_THROW(UninitializedGridFunctionSpaceError,"space is not initialized");
249 }
250 return _max_local_size;
251 }
252
254
259 void update(bool force = false)
260 {
261 gfs().entitySet().update(force);
262 auto update_leaf_es = impl::update_leaf_entity_set{_entity_set, force};
263 TypeTree::applyToTree(gfs(), update_leaf_es);
264 // We bypass the normal access using ordering() here to avoid a double
265 // update if the Ordering has not been created yet.
266 if (!gfs()._ordering)
267 gfs().create_ordering();
268 update(*gfs()._ordering);
269 }
270
271 const std::string& name() const
272 {
273 return _name;
274 }
275
276 void name(const std::string& name)
277 {
278 _name = name;
279 }
280
281 typename Traits::Backend& backend()
282 {
283 return _backend;
284 }
285
286 const typename Traits::Backend& backend() const
287 {
288 return _backend;
289 }
290
292 const typename Traits::GridView& gridView () const
293 {
294 return gfs().entitySet().gridView();
295 }
296
298 const typename Traits::EntitySet& entitySet () const
299 {
300 assert(_entity_set && "No entity set has been assigned to this node");
301 return *_entity_set;
302 }
303
305 typename Traits::EntitySet& entitySet ()
306 {
307 assert(_entity_set && "No entity set has been assigned to this node");
308 return *_entity_set;
309 }
310
311
327 void setEntitySet(typename Traits::EntitySet entity_set)
328 {
329 _entity_set.emplace(std::move(entity_set));
330 }
331
332 typename Traits::OrderingTag& orderingTag()
333 {
334 return _ordering_tag;
335 }
336
337 const typename Traits::OrderingTag& orderingTag() const
338 {
339 return _ordering_tag;
340 }
341
342 bool isRootSpace() const
343 {
344 return _is_root_space;
345 }
346
347 protected:
348
349 template<typename Ordering>
350 void update(Ordering& ordering) const
351 {
352 if (!_is_root_space)
353 {
354 DUNE_THROW(GridFunctionSpaceHierarchyError,"update() may only be called on the root of the function space hierarchy");
355 }
356 ordering.update();
357 TypeTree::applyToTree(ordering,impl::update_ordering_data<typename Traits::SizeType>(ordering));
358 }
359
360 mutable std::optional<typename Traits::EntitySet> _entity_set;
361
362 private:
363
364 typedef impl::GridFunctionSpaceOrderingData<typename GFSTraits::SizeType> BaseT;
365
366 GFS& gfs()
367 {
368 return static_cast<GFS&>(*this);
369 }
370
371 const GFS& gfs() const
372 {
373 return static_cast<const GFS&>(*this);
374 }
375
376 std::string _name;
377 typename Traits::Backend _backend;
378 typename Traits::OrderingTag _ordering_tag;
379
380 using BaseT::_size;
381 using BaseT::_block_count;
382 using BaseT::_global_size;
383 using BaseT::_max_local_size;
384 using BaseT::_is_root_space;
385 using BaseT::_initialized;
386 using BaseT::_size_available;
387
388 };
389
390
391 } // namespace PDELab
392} // namespace Dune
393
394#endif // DUNE_PDELAB_GRIDFUNCTIONSPACE_GRIDFUNCTIONSPACEBASE_HH
PDELab-specific exceptions.
void update(Ordering &ordering) const
Definition: gridfunctionspacebase.hh:350
GFSTraits Traits
Definition: gridfunctionspacebase.hh:196
Traits::OrderingTag & orderingTag()
Definition: gridfunctionspacebase.hh:332
const Traits::Backend & backend() const
Definition: gridfunctionspacebase.hh:286
Traits::Backend & backend()
Definition: gridfunctionspacebase.hh:281
Traits::SizeType maxLocalSize() const
get max dimension of shape function space
Definition: gridfunctionspacebase.hh:244
Traits::SizeType blockCount() const
Definition: gridfunctionspacebase.hh:220
std::optional< typename Traits::EntitySet > _entity_set
Definition: gridfunctionspacebase.hh:360
const Traits::GridView & gridView() const
get grid view
Definition: gridfunctionspacebase.hh:292
void setEntitySet(typename Traits::EntitySet entity_set)
Set the Entity Set object to this grid function space.
Definition: gridfunctionspacebase.hh:327
void name(const std::string &name)
Definition: gridfunctionspacebase.hh:276
const Traits::OrderingTag & orderingTag() const
Definition: gridfunctionspacebase.hh:337
void update(bool force=false)
Update the indexing information of the GridFunctionSpace.
Definition: gridfunctionspacebase.hh:259
const Traits::EntitySet & entitySet() const
get entity set
Definition: gridfunctionspacebase.hh:298
Traits::SizeType globalSize() const
Definition: gridfunctionspacebase.hh:234
bool isRootSpace() const
Definition: gridfunctionspacebase.hh:342
Traits::EntitySet & entitySet()
get entity set
Definition: gridfunctionspacebase.hh:305
Traits::SizeType size() const
Definition: gridfunctionspacebase.hh:206
const std::string & name() const
Definition: gridfunctionspacebase.hh:271
GridFunctionSpaceBase(Backend_ &&backend, OrderingTag_ &&ordering_tag)
Definition: gridfunctionspacebase.hh:199
STL namespace.
For backward compatibility – Do not use this!
Definition: adaptivity.hh:28
Called a GridFunctionSpace method that requires initialization of the space.
Definition: exceptions.hh:30
Definition: gridfunctionspacebase.hh:190