dune-functions  2.5-dev
taylorhoodbasis.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_FUNCTIONS_FUNCTIONSPACEBASES_TAYLORHOODBASIS_HH
4 #define DUNE_FUNCTIONS_FUNCTIONSPACEBASES_TAYLORHOODBASIS_HH
5 
6 #include <dune/common/exceptions.hh>
7 #include <dune/common/reservedvector.hh>
8 
9 #include <dune/typetree/powernode.hh>
10 #include <dune/typetree/compositenode.hh>
11 
13 
16 
17 namespace Dune {
18 namespace Functions {
19 
20 
21 // *****************************************************************************
22 // This is the reusable part of the basis. It contains
23 //
24 // TaylorHoodNodeFactory
25 // TaylorHoodNodeIndexSet
26 // TaylorHoodBasisTree
27 // TaylorHoodVelocityTree
28 //
29 // The factory allows to create the others and is the owner of possible shared
30 // state. These three components do _not_ depend on the global basis or index
31 // set and can be used without a global basis.
32 // *****************************************************************************
33 
34 template<typename GV, typename TP>
36 
37 template<typename GV, typename TP>
39 
40 template<typename GV, class MI, class TP, bool HI>
42 
43 
44 
65 template<typename GV, class MI, bool HI=false>
67 {
68  static const bool useHybridIndices = HI;
69 
70  static const int dim = GV::dimension;
71 
72  template<class, class, class, bool>
73  friend class TaylorHoodNodeIndexSet;
74 
75 public:
76 
78  using GridView = GV;
79 
81  using size_type = std::size_t;
82 
84  template<class TP>
86 
88  template<class TP>
90 
92  using MultiIndex = MI;
93 
95  using SizePrefix = Dune::ReservedVector<size_type, 3>;
96 
97 private:
98 
99  using PQMultiIndex = std::array<size_type, 1>;
102 
103 public:
104 
107  gridView_(gv),
108  pq1Factory_(gv),
109  pq2Factory_(gv)
110  {}
111 
114  {
117  }
118 
120  const GridView& gridView() const
121  {
122  return gridView_;
123  }
124 
126  void update (const GridView& gv)
127  {
128  pq1Factory_.update(gv);
129  pq2Factory_.update(gv);
130  }
131 
142  template<class TP>
143  Node<TP> node(const TP& tp) const
144  {
145  return Node<TP>{tp};
146  }
147 
157  template<class TP>
159  {
160  return IndexSet<TP>{*this};
161  }
162 
164  size_type size() const
165  {
166  return 2;
167  }
168 
170  size_type size(const SizePrefix prefix) const
171  {
172  return sizeImp<useHybridIndices>(prefix);
173  }
174 
175 private:
176 
177  template<bool hi,
178  typename std::enable_if<not hi,int>::type = 0>
179  size_type sizeImp(const SizePrefix prefix) const
180  {
181  if (prefix.size() == 0)
182  return 2;
183  if (prefix.size() == 1)
184  {
185  if (prefix[0] == 0)
186  return dim * pq2Factory_.size();
187  if (prefix[0] == 1)
188  return pq1Factory_.size();
189  }
190  if (prefix.size() == 2)
191  return 0;
192  assert(false);
193  }
194 
195  template<bool hi,
196  typename std::enable_if<hi,int>::type = 0>
197  size_type sizeImp(const SizePrefix prefix) const
198  {
199  if (prefix.size() == 0)
200  return 2;
201  if (prefix.size() == 1)
202  {
203  if (prefix[0] == 0)
204  return pq2Factory_.size();
205  if (prefix[0] == 1)
206  return pq1Factory_.size();
207  }
208  if (prefix.size() == 2)
209  {
210  if (prefix[0] == 0)
211  return dim;
212  if (prefix[0] == 1)
213  return 0;
214  }
215  if (prefix.size() == 3)
216  return 0;
217  assert(false);
218  }
219 
220 public:
221 
224  {
225  return dim * pq2Factory_.size() + pq1Factory_.size();
226  }
227 
230  {
231  return dim * pq2Factory_.maxNodeSize() + pq1Factory_.maxNodeSize();
232  }
233 
234 protected:
236 
239 };
240 
241 
242 
243 template<typename GV, typename TP>
245  public PowerBasisNode<std::size_t, TP ,PQkNode<GV,2, decltype(TypeTree::push_back(TP(), 0)) >, GV::dimension>
246 {
247  using ComponentTreePath = decltype(TypeTree::push_back(TP(), 0));
248 
249  using PQ2Node = PQkNode<GV,2, ComponentTreePath >;
251 
252 public:
253  TaylorHoodVelocityTree(const TP& tp) :
254  Base(tp)
255  {
256  for(int i=0; i<GV::dimension; ++i)
257  this->setChild(i, std::make_shared<PQ2Node>(TypeTree::push_back(tp, i)));
258  }
259 };
260 
261 template<typename GV, typename TP>
262 class TaylorHoodBasisTree :
263  public CompositeBasisNode<std::size_t, TP,
264  TaylorHoodVelocityTree<GV, decltype(TypeTree::push_back<0>(TP()))>,
265  PQkNode<GV,1, decltype(TypeTree::push_back<1ul>(TP()))>
266  >
267 {
268  using VelocityTreePath = decltype(TypeTree::push_back<0ul>(TP()));
269  using PressureTreePath = decltype(TypeTree::push_back<1ul>(TP()));
270 
272  using PressureNode=PQkNode<GV,1, PressureTreePath>;
273 
275 
276 public:
277  TaylorHoodBasisTree(const TP& tp):
278  Base(tp)
279  {
280  using namespace Dune::TypeTree::Indices;
281  this->template setChild<0>(std::make_shared<VelocityNode>(push_back(tp, _0)));
282  this->template setChild<1>(std::make_shared<PressureNode>(push_back(tp, _1)));
283  }
284 };
285 
286 
287 
288 template<typename GV, class MI, class TP, bool HI>
290 {
291  static const bool useHybridIndices = HI;
292 
293  static const int dim = GV::dimension;
294 
295 public:
296 
297  using size_type = std::size_t;
298 
300  using MultiIndex = MI;
301 
303 
304  using Node = typename NodeFactory::template Node<TP>;
305 
306  using PQ1TreePath = typename TypeTree::Child<Node,1>::TreePath;
307  using PQ2TreePath = typename TypeTree::Child<Node,0,0>::TreePath;
308 
309  using PQ1NodeIndexSet = typename NodeFactory::PQ1Factory::template IndexSet<PQ1TreePath>;
310  using PQ2NodeIndexSet = typename NodeFactory::PQ2Factory::template IndexSet<PQ2TreePath>;
311 
312  TaylorHoodNodeIndexSet(const NodeFactory & nodeFactory) :
313  nodeFactory_(&nodeFactory),
314  pq1NodeIndexSet_(nodeFactory_->pq1Factory_.template indexSet<PQ1TreePath>()),
315  pq2NodeIndexSet_(nodeFactory_->pq2Factory_.template indexSet<PQ2TreePath>())
316  {}
317 
318  void bind(const Node& node)
319  {
320  using namespace TypeTree::Indices;
321  node_ = &node;
322  pq1NodeIndexSet_.bind(node.child(_1));
323  pq2NodeIndexSet_.bind(node.child(_0, 0));
324  }
325 
326  void unbind()
327  {
328  node_ = nullptr;
329  pq1NodeIndexSet_.unbind();
330  pq2NodeIndexSet_.unbind();
331  }
332 
333  size_type size() const
334  {
335  return node_->size();
336  }
337 
338  MultiIndex index(size_type localIndex) const
339  {
340  return indexImp<useHybridIndices>(localIndex);
341  }
342 
343  template<bool hi,
344  typename std::enable_if<not hi,int>::type = 0>
345  MultiIndex indexImp(size_type localIndex) const
346  {
347  MultiIndex mi;
348 
349  size_type velocityComponentSize = pq2NodeIndexSet_.size();
350  size_type pressureOffset = velocityComponentSize * dim;
351 
352  mi[0] = localIndex / pressureOffset;
353  if (mi[0] == 0)
354  {
355  size_type v_comp = localIndex / velocityComponentSize;
356  size_type v_localIndex = localIndex % velocityComponentSize;
357  mi[1] = pq2NodeIndexSet_.index(v_localIndex)[0] * dim + v_comp;
358  }
359  if (mi[0] == 1)
360  mi[1] = pq1NodeIndexSet_.index(localIndex-pressureOffset)[0];
361  return mi;
362  }
363 
364  template<bool hi,
365  typename std::enable_if<hi,int>::type = 0>
366  MultiIndex indexImp(size_type localIndex) const
367  {
368  MultiIndex mi;
369 
370  size_type velocityComponentSize = pq2NodeIndexSet_.size();
371  size_type pressureOffset = velocityComponentSize * dim;
372 
373  mi.push_back(localIndex / pressureOffset);
374  if (mi[0] == 0)
375  {
376  size_type v_comp = localIndex / velocityComponentSize;
377  size_type v_localIndex = localIndex % velocityComponentSize;
378  mi.push_back(pq2NodeIndexSet_.index(v_localIndex)[0]);
379  mi.push_back(v_comp);
380  }
381  if (mi[0] == 1)
382  mi.push_back(pq1NodeIndexSet_.index(localIndex-pressureOffset)[0]);
383  return mi;
384  }
385 
386 private:
387  const NodeFactory* nodeFactory_;
388  PQ1NodeIndexSet pq1NodeIndexSet_;
389  PQ2NodeIndexSet pq2NodeIndexSet_;
390 
391  const Node* node_;
392 };
393 
394 
395 
396 // *****************************************************************************
397 // This is the actual global basis implementation based on the reusable parts.
398 // *****************************************************************************
399 
421 template<typename GV>
423 
424 
425 
426 } // end namespace Functions
427 } // end namespace Dune
428 
429 
430 #endif // DUNE_FUNCTIONS_FUNCTIONSPACEBASES_TAYLORHOODBASIS_HH
Definition: nodes.hh:209
Definition: taylorhoodbasis.hh:41
MI MultiIndex
Type used for global numbering of the basis vectors.
Definition: taylorhoodbasis.hh:92
std::size_t size_type
Definition: taylorhoodbasis.hh:297
IndexSet< TP > indexSet() const
Create tree node index set with given root tree path.
Definition: taylorhoodbasis.hh:158
MultiIndex index(size_type localIndex) const
Definition: taylorhoodbasis.hh:338
Definition: taylorhoodbasis.hh:38
size_type size() const
Same as size(prefix) with empty prefix.
Definition: taylorhoodbasis.hh:164
void bind(const Node &node)
Definition: taylorhoodbasis.hh:318
Global basis for given node factory.
Definition: defaultglobalbasis.hh:42
Definition: polynomial.hh:7
TaylorHoodNodeFactory(const GridView &gv)
Constructor for a given grid view object.
Definition: taylorhoodbasis.hh:106
typename NodeFactory::PQ1Factory::template IndexSet< PQ1TreePath > PQ1NodeIndexSet
Definition: taylorhoodbasis.hh:309
void update(const GridView &gv)
Update the stored grid view, to be called if the grid has changed.
Definition: taylorhoodbasis.hh:126
TaylorHoodNodeIndexSet(const NodeFactory &nodeFactory)
Definition: taylorhoodbasis.hh:312
Definition: nodes.hh:232
typename TypeTree::Child< Node, 1 >::TreePath PQ1TreePath
Definition: taylorhoodbasis.hh:306
MI MultiIndex
Type used for global numbering of the basis vectors.
Definition: taylorhoodbasis.hh:300
TaylorHoodVelocityTree(const TP &tp)
Definition: taylorhoodbasis.hh:253
PQ1Factory pq1Factory_
Definition: taylorhoodbasis.hh:237
Dune::ReservedVector< size_type, 3 > SizePrefix
Type used for prefixes handed to the size() method.
Definition: taylorhoodbasis.hh:95
Node< TP > node(const TP &tp) const
Create tree node with given root tree path.
Definition: taylorhoodbasis.hh:143
PQ2Factory pq2Factory_
Definition: taylorhoodbasis.hh:238
size_type size() const
Definition: taylorhoodbasis.hh:333
typename NodeFactory::template Node< TP > Node
Definition: taylorhoodbasis.hh:304
const GridView & gridView() const
Obtain the grid view that the basis is defined on.
Definition: taylorhoodbasis.hh:120
Definition: pqknodalbasis.hh:36
typename NodeFactory::PQ2Factory::template IndexSet< PQ2TreePath > PQ2NodeIndexSet
Definition: taylorhoodbasis.hh:310
void initializeIndices()
Initialize the global indices.
Definition: taylorhoodbasis.hh:113
size_type size() const
Same as size(prefix) with empty prefix.
Definition: pqknodalbasis.hh:191
size_type size(const SizePrefix prefix) const
Return number of possible values for next position in multi index.
Definition: taylorhoodbasis.hh:170
typename TypeTree::Child< Node, 0, 0 >::TreePath PQ2TreePath
Definition: taylorhoodbasis.hh:307
MultiIndex indexImp(size_type localIndex) const
Definition: taylorhoodbasis.hh:345
size_type maxNodeSize() const
Get the maximal number of DOFs associated to node for any element.
Definition: pqknodalbasis.hh:245
std::size_t size_type
Type used for indices and size information.
Definition: taylorhoodbasis.hh:81
void update(const GridView &gv)
Update the stored grid view, to be called if the grid has changed.
Definition: pqknodalbasis.hh:154
Factory for lowest order Taylor-Hood basis.
Definition: taylorhoodbasis.hh:66
GridView gridView_
Definition: taylorhoodbasis.hh:235
Definition: taylorhoodbasis.hh:35
void unbind()
Definition: taylorhoodbasis.hh:326
TaylorHoodBasisTree(const TP &tp)
Definition: taylorhoodbasis.hh:277
GV GridView
The grid view that the FE basis is defined on.
Definition: taylorhoodbasis.hh:78
size_type maxNodeSize() const
Get the maximal number of DOFs associated to node for any element.
Definition: taylorhoodbasis.hh:229
void initializeIndices()
Initialize the global indices.
Definition: pqknodalbasis.hh:118
size_type dimension() const
Get the total dimension of the space spanned by this basis.
Definition: taylorhoodbasis.hh:223