dune-pdelab  2.4-dev
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 <dune/typetree/visitor.hh>
7 #include <dune/typetree/traversal.hh>
8 
11 
12 namespace Dune {
13  namespace PDELab {
14 
18 
19 #ifndef DOXYGEN
20 
21  // forward declaration for friend declaration
22  template<typename GFS, typename GFSTraits>
23  class GridFunctionSpaceBase;
24 
25  namespace impl {
26 
27  struct reset_root_space_flag
28  : public TypeTree::DirectChildrenVisitor
29  , public TypeTree::DynamicTraversal
30  {
31 
32  template<typename GFS, typename Child, typename TreePath, typename ChildIndex>
33  void afterChild(const GFS& gfs, Child& child, TreePath, ChildIndex) const
34  {
35  if (child._initialized && child._is_root_space)
36  {
37  DUNE_THROW(GridFunctionSpaceHierarchyError,"initialized space cannot become part of larger GridFunctionSpace tree");
38  }
39  child._is_root_space = false;
40  }
41 
42  };
43 
44  template<typename size_type>
45  struct update_ordering_data;
46 
47  // helper class with minimal dependencies. Orderings keep a pointer to this structure and populate it
48  // during their update procedure.
49 
50  template<typename size_type>
51  class GridFunctionSpaceOrderingData
52  : public PartitionInfoProvider
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  data.setPartitionSet(ordering);
104  }
105  }
106 
107  template<typename Ordering, typename TreePath>
108  void leaf(const Ordering& ordering, TreePath tp)
109  {
110  update(ordering,tp.size() == 0);
111  }
112 
113  template<typename Ordering, typename TreePath>
114  void post(const Ordering& ordering, TreePath tp)
115  {
116  update(ordering,tp.size() == 0);
117  }
118 
119  template<typename Ordering>
120  explicit update_ordering_data(const Ordering& ordering)
121  : _global_size(ordering.size())
122  , _max_local_size(ordering.maxLocalSize())
123  {}
124 
125  const size_type _global_size;
126  const size_type _max_local_size;
127 
128  };
129 
130 
131  } // namespace impl
132 
133 #endif // DOXYGEN
134 
135 
136  template<typename GFS, typename GFSTraits>
138  : public impl::GridFunctionSpaceOrderingData<typename GFSTraits::SizeType>
139  {
140 
141  friend struct impl::reset_root_space_flag;
142 
143  public:
144 
145  typedef GFSTraits Traits;
146 
147  template<typename Backend_, typename OrderingTag_>
148  GridFunctionSpaceBase(Backend_&& backend, OrderingTag_&& ordering_tag)
149  : _backend(std::forward<Backend_>(backend))
150  , _ordering_tag(std::forward<OrderingTag_>(ordering_tag))
151  {
152  TypeTree::applyToTree(gfs(),impl::reset_root_space_flag());
153  }
154 
155  typename Traits::SizeType size() const
156  {
157  if (!_initialized)
158  {
159  DUNE_THROW(UninitializedGridFunctionSpaceError,"space is not initialized");
160  }
161  if (!_size_available)
162  {
164  "Size cannot be calculated at this point in the GFS tree.");
165  }
166  return _size;
167  }
168 
169  typename Traits::SizeType blockCount() const
170  {
171  if (!_initialized)
172  {
173  DUNE_THROW(UninitializedGridFunctionSpaceError,"space is not initialized");
174  }
175  if (!_size_available)
176  {
178  "Block count cannot be calculated at this point in the GFS tree.");
179  }
180  return _block_count;
181  }
182 
183  typename Traits::SizeType globalSize() const
184  {
185  if (!_initialized)
186  {
187  DUNE_THROW(UninitializedGridFunctionSpaceError,"space is not initialized");
188  }
189  return _global_size;
190  }
191 
193  typename Traits::SizeType maxLocalSize () const
194  {
195  if (!_initialized)
196  {
197  DUNE_THROW(UninitializedGridFunctionSpaceError,"space is not initialized");
198  }
199  return _max_local_size;
200  }
201 
203  bool containsPartition(PartitionType partition) const
204  {
205  if (!_initialized)
206  {
207  DUNE_THROW(UninitializedGridFunctionSpaceError,"space is not initialized");
208  }
210  }
211 
212  void update()
213  {
214  // We bypass the normal access using ordering() here to avoid a double
215  // update if the Ordering has not been created yet.
216  if (!gfs()._ordering)
217  gfs().create_ordering();
218  update(*gfs()._ordering);
219  }
220 
221  const std::string& name() const
222  {
223  return _name;
224  }
225 
226  void name(const std::string& name)
227  {
228  _name = name;
229  }
230 
232  {
233  return _backend;
234  }
235 
236  const typename Traits::Backend& backend() const
237  {
238  return _backend;
239  }
240 
242  {
243  return _ordering_tag;
244  }
245 
246  const typename Traits::OrderingTag& orderingTag() const
247  {
248  return _ordering_tag;
249  }
250 
251  bool isRootSpace() const
252  {
253  return _is_root_space;
254  }
255 
256  protected:
257 
258  template<typename Ordering>
259  void update(Ordering& ordering) const
260  {
261  if (!_is_root_space)
262  {
263  DUNE_THROW(GridFunctionSpaceHierarchyError,"update() may only be called on the root of the function space hierarchy");
264  }
265  ordering.update();
266  TypeTree::applyToTree(ordering,impl::update_ordering_data<typename Traits::SizeType>(ordering));
267  }
268 
269  private:
270 
271  typedef impl::GridFunctionSpaceOrderingData<typename GFSTraits::SizeType> BaseT;
272 
273  GFS& gfs()
274  {
275  return static_cast<GFS&>(*this);
276  }
277 
278  const GFS& gfs() const
279  {
280  return static_cast<const GFS&>(*this);
281  }
282 
283  std::string _name;
284  typename Traits::Backend _backend;
285  typename Traits::OrderingTag _ordering_tag;
286 
287  using BaseT::_size;
288  using BaseT::_block_count;
289  using BaseT::_global_size;
290  using BaseT::_max_local_size;
291  using BaseT::_is_root_space;
292  using BaseT::_initialized;
293  using BaseT::_size_available;
294 
295  };
296 
297 
298  } // namespace PDELab
299 } // namespace Dune
300 
301 #endif // DUNE_PDELAB_GRIDFUNCTIONSPACE_GRIDFUNCTIONSPACEBASE_HH
Traits::SizeType globalSize() const
Definition: gridfunctionspacebase.hh:183
B Backend
Definition: powercompositegridfunctionspacebase.hh:53
Definition: gridfunctionspacebase.hh:137
void update()
Definition: gridfunctionspacebase.hh:212
const Traits::Backend & backend() const
Definition: gridfunctionspacebase.hh:236
Traits::SizeType maxLocalSize() const
get max dimension of shape function space
Definition: gridfunctionspacebase.hh:193
STL namespace.
bool containsPartition(PartitionType partition) const
Returns whether this GridFunctionSpace contains entities with PartitionType partition.
Definition: gridfunctionspacebase.hh:203
void name(const std::string &name)
Definition: gridfunctionspacebase.hh:226
GridFunctionSpaceBase(Backend_ &&backend, OrderingTag_ &&ordering_tag)
Definition: gridfunctionspacebase.hh:148
O OrderingTag
Definition: powercompositegridfunctionspacebase.hh:58
std::size_t _size
Definition: datahandleprovider.hh:45
Traits::OrderingTag & orderingTag()
Definition: gridfunctionspacebase.hh:241
GFSTraits Traits
Definition: gridfunctionspacebase.hh:145
const std::string & name() const
Definition: gridfunctionspacebase.hh:221
Traits::Backend & backend()
Definition: gridfunctionspacebase.hh:231
bool isRootSpace() const
Definition: gridfunctionspacebase.hh:251
Definition: adaptivity.hh:27
B::size_type SizeType
short cut for size type exported by Backend
Definition: powercompositegridfunctionspacebase.hh:61
bool containsPartition(PartitionType partition) const
Returns whether this ordering contains entities with PartitionType partition.
Definition: partitioninfoprovider.hh:28
PDELab-specific exceptions.
Called a GridFunctionSpace method that requires initialization of the space.
Definition: exceptions.hh:28
const Traits::OrderingTag & orderingTag() const
Definition: gridfunctionspacebase.hh:246
Traits::SizeType size() const
Definition: gridfunctionspacebase.hh:155
void update(Ordering &ordering) const
Definition: gridfunctionspacebase.hh:259
Traits::SizeType blockCount() const
Definition: gridfunctionspacebase.hh:169