DUNE PDELab (git)

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 <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())
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>
188 class GridFunctionSpaceBase
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 {
214 DUNE_THROW(GridFunctionSpaceHierarchyError,
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 {
228 DUNE_THROW(GridFunctionSpaceHierarchyError,
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#ifndef DUNE_PDELAB_ENABLE_EXPERIMENTAL_MULTIDOMAIN_SUPPORT
312 protected:
313#endif
329 void setEntitySet(typename Traits::EntitySet entity_set)
330 {
331 _entity_set.emplace(std::move(entity_set));
332 }
333
334 public:
335
336 typename Traits::OrderingTag& orderingTag()
337 {
338 return _ordering_tag;
339 }
340
341 const typename Traits::OrderingTag& orderingTag() const
342 {
343 return _ordering_tag;
344 }
345
346 bool isRootSpace() const
347 {
348 return _is_root_space;
349 }
350
351 protected:
352
353 template<typename Ordering>
354 void update(Ordering& ordering) const
355 {
356 if (!_is_root_space)
357 {
358 DUNE_THROW(GridFunctionSpaceHierarchyError,"update() may only be called on the root of the function space hierarchy");
359 }
360 ordering.update();
361 TypeTree::applyToTree(ordering,impl::update_ordering_data<typename Traits::SizeType>(ordering));
362 }
363
364 mutable std::optional<typename Traits::EntitySet> _entity_set;
365
366 private:
367
368 typedef impl::GridFunctionSpaceOrderingData<typename GFSTraits::SizeType> BaseT;
369
370 GFS& gfs()
371 {
372 return static_cast<GFS&>(*this);
373 }
374
375 const GFS& gfs() const
376 {
377 return static_cast<const GFS&>(*this);
378 }
379
380 std::string _name;
381 typename Traits::Backend _backend;
382 typename Traits::OrderingTag _ordering_tag;
383
384 using BaseT::_size;
385 using BaseT::_block_count;
386 using BaseT::_global_size;
387 using BaseT::_max_local_size;
388 using BaseT::_is_root_space;
389 using BaseT::_initialized;
390 using BaseT::_size_available;
391
392 };
393
394
395 } // namespace PDELab
396} // namespace Dune
397
398#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:218
Traits::SizeType maxLocalSize() const
get max dimension of shape function space
Definition: gridfunctionspacebase.hh:244
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:329
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::EntitySet & entitySet()
get entity set
Definition: gridfunctionspacebase.hh:305
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
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:225
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.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 23, 23:29, 2024)