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>
188 class GridFunctionSpaceBase
189 :
public impl::GridFunctionSpaceOrderingData<typename GFSTraits::SizeType>
192 friend struct impl::reset_root_space_flag;
196 typedef GFSTraits Traits;
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))
206 typename Traits::SizeType size()
const
210 DUNE_THROW(UninitializedGridFunctionSpaceError,
"space is not initialized");
212 if (!_size_available)
215 "Size cannot be calculated at this point in the GFS tree.");
220 typename Traits::SizeType blockCount()
const
224 DUNE_THROW(UninitializedGridFunctionSpaceError,
"space is not initialized");
226 if (!_size_available)
229 "Block count cannot be calculated at this point in the GFS tree.");
234 typename Traits::SizeType globalSize()
const
238 DUNE_THROW(UninitializedGridFunctionSpaceError,
"space is not initialized");
250 return _max_local_size;
261 gfs().entitySet().update(force);
262 auto update_leaf_es = impl::update_leaf_entity_set{_entity_set, force};
266 if (!gfs()._ordering)
267 gfs().create_ordering();
268 update(*gfs()._ordering);
271 const std::string& name()
const
276 void name(
const std::string& name)
281 typename Traits::Backend& backend()
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");
311#ifndef DUNE_PDELAB_ENABLE_EXPERIMENTAL_MULTIDOMAIN_SUPPORT
331 _entity_set.emplace(std::move(entity_set));
336 typename Traits::OrderingTag& orderingTag()
338 return _ordering_tag;
341 const typename Traits::OrderingTag& orderingTag()
const
343 return _ordering_tag;
346 bool isRootSpace()
const
348 return _is_root_space;
353 template<
typename Ordering>
354 void update(Ordering& ordering)
const
358 DUNE_THROW(GridFunctionSpaceHierarchyError,
"update() may only be called on the root of the function space hierarchy");
364 mutable std::optional<typename Traits::EntitySet> _entity_set;
368 typedef impl::GridFunctionSpaceOrderingData<typename GFSTraits::SizeType> BaseT;
372 return static_cast<GFS&
>(*this);
375 const GFS& gfs()
const
377 return static_cast<const GFS&
>(*this);
381 typename Traits::Backend _backend;
382 typename Traits::OrderingTag _ordering_tag;
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;
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: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 HybridTreePath< T... > treePath(const T &... t)
Constructs a new HybridTreePath from the given indices.
Definition: treepath.hh:188
void applyToTree(Tree &&tree, Visitor &&visitor)
Apply visitor to TypeTree.
Definition: traversal.hh:237
Dune namespace.
Definition: alignedallocator.hh:11