3 #ifndef DUNE_PDELAB_GRIDFUNCTIONSPACE_GRIDFUNCTIONSPACEBASE_HH
4 #define DUNE_PDELAB_GRIDFUNCTIONSPACE_GRIDFUNCTIONSPACEBASE_HH
8 #include <dune/typetree/visitor.hh>
9 #include <dune/typetree/traversal.hh>
23 template<
typename GFS,
typename GFSTraits>
24 class GridFunctionSpaceBase;
28 struct reset_root_space_flag
29 :
public TypeTree::DirectChildrenVisitor
30 ,
public TypeTree::DynamicTraversal
33 template<
typename GFS,
typename Child,
typename TreePath,
typename ChildIndex>
34 void afterChild(
const GFS& gfs, Child& child, TreePath, ChildIndex)
const
36 if (child._initialized && child._is_root_space)
38 DUNE_THROW(GridFunctionSpaceHierarchyError,
"initialized space cannot become part of larger GridFunctionSpace tree");
40 child._is_root_space =
false;
45 template<
typename size_type>
46 struct update_ordering_data;
51 template<
typename size_type>
52 class GridFunctionSpaceOrderingData
55 template<
typename,
typename>
56 friend class ::Dune::PDELab::GridFunctionSpaceBase;
59 friend struct update_ordering_data;
61 GridFunctionSpaceOrderingData()
66 , _is_root_space(true)
68 , _size_available(true)
72 size_type _block_count;
73 size_type _global_size;
74 size_type _max_local_size;
81 template<
typename size_type>
82 struct update_ordering_data
83 :
public TypeTree::TreeVisitor
84 ,
public TypeTree::DynamicTraversal
87 typedef GridFunctionSpaceOrderingData<size_type> Data;
89 template<
typename Ordering>
90 void update(
const Ordering& ordering,
bool is_root)
92 if (ordering._gfs_data)
94 Data& data = *ordering._gfs_data;
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);
106 template<
typename Ordering,
typename TreePath>
107 void leaf(
const Ordering& ordering, TreePath tp)
109 update(ordering,tp.size() == 0);
112 template<
typename Ordering,
typename TreePath>
113 void post(
const Ordering& ordering, TreePath tp)
115 update(ordering,tp.size() == 0);
118 template<
typename Ordering>
119 explicit update_ordering_data(
const Ordering& ordering)
120 : _global_size(ordering.size())
121 , _max_local_size(ordering.maxLocalSize())
124 const size_type _global_size;
125 const size_type _max_local_size;
131 template<
class EntitySet>
132 struct common_entity_set
133 :
public TypeTree::TreeVisitor
134 ,
public TypeTree::DynamicTraversal
136 template<
typename T,
typename TreePath>
137 void leaf(T&& t, TreePath treePath) {
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."
150 std::optional<EntitySet> _entity_set;
158 template<
class EntitySet>
159 struct update_leaf_entity_set
160 :
public TypeTree::TreeVisitor
161 ,
public TypeTree::DynamicTraversal
163 update_leaf_entity_set(
const std::optional<EntitySet>& entity_set,
bool force_update)
164 : _force_update{force_update}
165 , _entity_set{entity_set}
168 template<
typename GFSNode,
typename TreePath>
169 void leaf(GFSNode&& gfs_node, TreePath treePath) {
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();
179 std::optional<EntitySet> _entity_set;
187 template<
typename GFS,
typename GFSTraits>
189 :
public impl::GridFunctionSpaceOrderingData<typename GFSTraits::SizeType>
192 friend struct impl::reset_root_space_flag;
198 template<
typename Backend_,
typename OrderingTag_>
200 : _backend(std::forward<Backend_>(
backend))
201 , _ordering_tag(std::forward<OrderingTag_>(ordering_tag))
203 TypeTree::applyToTree(gfs(),impl::reset_root_space_flag());
206 typename Traits::SizeType
size()
const
212 if (!_size_available)
215 "Size cannot be calculated at this point in the GFS tree.");
226 if (!_size_available)
229 "Block count cannot be calculated at this point in the GFS tree.");
250 return _max_local_size;
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);
266 if (!gfs()._ordering)
267 gfs().create_ordering();
271 const std::string&
name()
const
286 const typename Traits::Backend&
backend()
const
294 return gfs().entitySet().gridView();
300 assert(
_entity_set &&
"No entity set has been assigned to this node");
307 assert(
_entity_set &&
"No entity set has been assigned to this node");
334 return _ordering_tag;
339 return _ordering_tag;
344 return _is_root_space;
349 template<
typename Ordering>
357 TypeTree::applyToTree(ordering,impl::update_ordering_data<typename Traits::SizeType>(ordering));
364 typedef impl::GridFunctionSpaceOrderingData<typename GFSTraits::SizeType> BaseT;
368 return static_cast<GFS&
>(*this);
371 const GFS& gfs()
const
373 return static_cast<const GFS&
>(*this);
377 typename Traits::Backend _backend;
378 typename Traits::OrderingTag _ordering_tag;
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;
PDELab-specific exceptions.
void update(Ordering &ordering) const
Definition: gridfunctionspacebase.hh:350
GFSTraits Traits
Definition: gridfunctionspacebase.hh:196
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
Traits::Backend & backend()
Definition: gridfunctionspacebase.hh:281
const Traits::Backend & backend() const
Definition: gridfunctionspacebase.hh:286
Traits::SizeType blockCount() const
Definition: gridfunctionspacebase.hh:220
std::optional< typename Traits::EntitySet > _entity_set
Definition: gridfunctionspacebase.hh:360
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
Traits::OrderingTag & orderingTag()
Definition: gridfunctionspacebase.hh:332
const std::string & name() const
Definition: gridfunctionspacebase.hh:271
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
const Traits::OrderingTag & orderingTag() const
Definition: gridfunctionspacebase.hh:337
Traits::SizeType globalSize() const
Definition: gridfunctionspacebase.hh:234
bool isRootSpace() const
Definition: gridfunctionspacebase.hh:342
Traits::SizeType size() const
Definition: gridfunctionspacebase.hh:206
Traits::EntitySet & entitySet()
get entity set
Definition: gridfunctionspacebase.hh:305
GridFunctionSpaceBase(Backend_ &&backend, OrderingTag_ &&ordering_tag)
Definition: gridfunctionspacebase.hh:199
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: exceptions.hh:36
Definition: gridfunctionspacebase.hh:190