dune-pdelab  2.0.0
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 #if HAVE_RVALUE_REFERENCES
148 
149  template<typename Backend_, typename OrderingTag_>
150  GridFunctionSpaceBase(Backend_&& backend, OrderingTag_&& ordering_tag)
151  : _backend(std::forward<Backend_>(backend))
152  , _ordering_tag(std::forward<OrderingTag_>(ordering_tag))
153  {
154  TypeTree::applyToTree(gfs(),impl::reset_root_space_flag());
155  }
156 
157 #else
158 
159  GridFunctionSpaceBase(const B& backend, const OrderingTag& ordering_tag)
160  : _backend(backend)
161  , _ordering_tag(ordering_tag)
162  , _size(0)
163  , _global_size(0)
164  , _is_root_space(true)
165  , _initialized(false)
166  {
167  TypeTree::applyToTree(gfs(),impl::reset_root_space_flag());
168  }
169 
170 #endif
171 
172  typename Traits::SizeType size() const
173  {
174  if (!_initialized)
175  {
176  DUNE_THROW(UninitializedGridFunctionSpaceError,"space is not initialized");
177  }
178  if (!_size_available)
179  {
181  "Size cannot be calculated at this point in the GFS tree.");
182  }
183  return _size;
184  }
185 
186  typename Traits::SizeType blockCount() const
187  {
188  if (!_initialized)
189  {
190  DUNE_THROW(UninitializedGridFunctionSpaceError,"space is not initialized");
191  }
192  if (!_size_available)
193  {
195  "Block count cannot be calculated at this point in the GFS tree.");
196  }
197  return _block_count;
198  }
199 
200  typename Traits::SizeType globalSize() const
201  {
202  if (!_initialized)
203  {
204  DUNE_THROW(UninitializedGridFunctionSpaceError,"space is not initialized");
205  }
206  return _global_size;
207  }
208 
210  typename Traits::SizeType maxLocalSize () const
211  {
212  if (!_initialized)
213  {
214  DUNE_THROW(UninitializedGridFunctionSpaceError,"space is not initialized");
215  }
216  return _max_local_size;
217  }
218 
220  bool containsPartition(PartitionType partition) const
221  {
222  if (!_initialized)
223  {
224  DUNE_THROW(UninitializedGridFunctionSpaceError,"space is not initialized");
225  }
227  }
228 
229  void update()
230  {
231  // We bypass the normal access using ordering() here to avoid a double
232  // update if the Ordering has not been created yet.
233  if (!gfs()._ordering)
234  gfs().create_ordering();
235  update(*gfs()._ordering);
236  }
237 
238  const std::string& name() const
239  {
240  return _name;
241  }
242 
243  void name(const std::string& name)
244  {
245  _name = name;
246  }
247 
249  {
250  return _backend;
251  }
252 
253  const typename Traits::Backend& backend() const
254  {
255  return _backend;
256  }
257 
259  {
260  return _ordering_tag;
261  }
262 
263  const typename Traits::OrderingTag& orderingTag() const
264  {
265  return _ordering_tag;
266  }
267 
268  bool isRootSpace() const
269  {
270  return _is_root_space;
271  }
272 
273  protected:
274 
275  template<typename Ordering>
276  void update(Ordering& ordering) const
277  {
278  if (!_is_root_space)
279  {
280  DUNE_THROW(GridFunctionSpaceHierarchyError,"update() may only be called on the root of the function space hierarchy");
281  }
282  ordering.update();
283  TypeTree::applyToTree(ordering,impl::update_ordering_data<typename Traits::SizeType>(ordering));
284  }
285 
286  private:
287 
288  typedef impl::GridFunctionSpaceOrderingData<typename GFSTraits::SizeType> BaseT;
289 
290  GFS& gfs()
291  {
292  return static_cast<GFS&>(*this);
293  }
294 
295  const GFS& gfs() const
296  {
297  return static_cast<const GFS&>(*this);
298  }
299 
300  std::string _name;
301  typename Traits::Backend _backend;
302  typename Traits::OrderingTag _ordering_tag;
303 
304  using BaseT::_size;
305  using BaseT::_block_count;
306  using BaseT::_global_size;
307  using BaseT::_max_local_size;
308  using BaseT::_is_root_space;
309  using BaseT::_initialized;
310  using BaseT::_size_available;
311 
312  };
313 
314 
315  } // namespace PDELab
316 } // namespace Dune
317 
318 #endif // DUNE_PDELAB_GRIDFUNCTIONSPACE_GRIDFUNCTIONSPACEBASE_HH
GFSTraits Traits
Definition: gridfunctionspacebase.hh:145
void name(const std::string &name)
Definition: gridfunctionspacebase.hh:243
B::size_type SizeType
short cut for size type exported by Backend
Definition: powercompositegridfunctionspacebase.hh:60
bool containsPartition(PartitionType partition) const
Returns whether this GridFunctionSpace contains entities with PartitionType partition.
Definition: gridfunctionspacebase.hh:220
const std::string & name() const
Definition: gridfunctionspacebase.hh:238
PDELab-specific exceptions.
Traits::SizeType size() const
Definition: gridfunctionspacebase.hh:172
Definition: gridfunctionspacebase.hh:137
const Traits::Backend & backend() const
Definition: gridfunctionspacebase.hh:253
bool isRootSpace() const
Definition: gridfunctionspacebase.hh:268
Called a GridFunctionSpace method that requires initialization of the space.
Definition: exceptions.hh:28
B Backend
Definition: powercompositegridfunctionspacebase.hh:52
std::size_t _size
Definition: datahandleprovider.hh:46
bool containsPartition(PartitionType partition) const
Returns whether this ordering contains entities with PartitionType partition.
Definition: partitioninfoprovider.hh:28
const Traits::OrderingTag & orderingTag() const
Definition: gridfunctionspacebase.hh:263
Traits::Backend & backend()
Definition: gridfunctionspacebase.hh:248
Traits::OrderingTag & orderingTag()
Definition: gridfunctionspacebase.hh:258
Traits::SizeType maxLocalSize() const
get max dimension of shape function space
Definition: gridfunctionspacebase.hh:210
Traits::SizeType globalSize() const
Definition: gridfunctionspacebase.hh:200
void update()
Definition: gridfunctionspacebase.hh:229
GridFunctionSpaceBase(const B &backend, const OrderingTag &ordering_tag)
Definition: gridfunctionspacebase.hh:159
void update(Ordering &ordering) const
Definition: gridfunctionspacebase.hh:276
O OrderingTag
Definition: powercompositegridfunctionspacebase.hh:57
Traits::SizeType blockCount() const
Definition: gridfunctionspacebase.hh:186