dune-functions  2.7.1
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 // TaylorHoodPreBasis
25 // TaylorHoodNodeIndexSet
26 // TaylorHoodBasisTree
27 // TaylorHoodVelocityTree
28 //
29 // The pre-basis 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>
35 class TaylorHoodVelocityTree;
36 
37 template<typename GV>
38 class TaylorHoodBasisTree;
39 
40 template<typename GV, class MI, bool HI>
41 class TaylorHoodNodeIndexSet;
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, bool>
73  friend class TaylorHoodNodeIndexSet;
74 
75 public:
76 
78  using GridView = GV;
79 
81  using size_type = std::size_t;
82 
85 
88 
90  using MultiIndex = MI;
91 
93  using SizePrefix = Dune::ReservedVector<size_type, 2>;
94 
95 private:
96 
97  using PQMultiIndex = std::array<size_type, 1>;
100 
101 public:
102 
105  gridView_(gv),
106  pq1PreBasis_(gv),
107  pq2PreBasis_(gv)
108  {}
109 
112  {
115  }
116 
118  const GridView& gridView() const
119  {
120  return gridView_;
121  }
122 
124  void update (const GridView& gv)
125  {
126  pq1PreBasis_.update(gv);
127  pq2PreBasis_.update(gv);
128  }
129 
133  Node makeNode() const
134  {
135  return Node{};
136  }
137 
145  {
146  return IndexSet{*this};
147  }
148 
150  size_type size() const
151  {
152  return 2;
153  }
154 
156  size_type size(const SizePrefix prefix) const
157  {
158  return sizeImp<useHybridIndices>(prefix);
159  }
160 
161 private:
162 
163  template<bool hi,
164  typename std::enable_if<not hi,int>::type = 0>
165  size_type sizeImp(const SizePrefix prefix) const
166  {
167  if (prefix.size() == 0)
168  return 2;
169  if (prefix.size() == 1)
170  {
171  if (prefix[0] == 0)
172  return dim * pq2PreBasis_.size();
173  if (prefix[0] == 1)
174  return pq1PreBasis_.size();
175  }
176  assert(prefix.size() == 2);
177  return 0;
178  }
179 
180  template<bool hi,
181  typename std::enable_if<hi,int>::type = 0>
182  size_type sizeImp(const SizePrefix prefix) const
183  {
184  if (prefix.size() == 0)
185  return 2;
186  if (prefix.size() == 1)
187  {
188  if (prefix[0] == 0)
189  return pq2PreBasis_.size();
190  if (prefix[0] == 1)
191  return pq1PreBasis_.size();
192  }
193  if (prefix.size() == 2)
194  {
195  if (prefix[0] == 0)
196  return dim;
197  if (prefix[0] == 1)
198  return 0;
199  }
200  assert(prefix.size() == 3);
201  return 0;
202  }
203 
204 public:
205 
208  {
209  return dim * pq2PreBasis_.size() + pq1PreBasis_.size();
210  }
211 
214  {
216  }
217 
218 protected:
220 
223 };
224 
225 
226 
227 template<typename GV>
229  public PowerBasisNode<LagrangeNode<GV,2>, GV::dimension>
230 {
231  using PQ2Node = LagrangeNode<GV,2>;
233 
234 public:
236  {
237  for(int i=0; i<GV::dimension; ++i)
238  this->setChild(i, std::make_shared<PQ2Node>());
239  }
240 };
241 
242 template<typename GV>
244  public CompositeBasisNode<
245  TaylorHoodVelocityTree<GV>,
246  LagrangeNode<GV,1>
247  >
248 {
251 
253 
254 public:
256  {
257  this->template setChild<0>(std::make_shared<VelocityNode>());
258  this->template setChild<1>(std::make_shared<PressureNode>());
259  }
260 };
261 
262 
263 
264 template<typename GV, class MI, bool HI>
266 {
267  static const bool useHybridIndices = HI;
268 
269  static const int dim = GV::dimension;
270 
271 public:
272 
273  using size_type = std::size_t;
274 
276  using MultiIndex = MI;
277 
279 
281 
284 
285  TaylorHoodNodeIndexSet(const PreBasis & preBasis) :
286  preBasis_(&preBasis),
287  pq1NodeIndexSet_(preBasis_->pq1PreBasis_.makeIndexSet()),
288  pq2NodeIndexSet_(preBasis_->pq2PreBasis_.makeIndexSet())
289  {}
290 
291  void bind(const Node& node)
292  {
293  using namespace TypeTree::Indices;
294  node_ = &node;
295  pq1NodeIndexSet_.bind(node.child(_1));
296  pq2NodeIndexSet_.bind(node.child(_0, 0));
297  }
298 
299  void unbind()
300  {
301  node_ = nullptr;
302  pq1NodeIndexSet_.unbind();
303  pq2NodeIndexSet_.unbind();
304  }
305 
306  size_type size() const
307  {
308  return node_->size();
309  }
310 
311  template<typename It>
312  It indices(It multiIndices) const
313  {
314  return indicesImp<useHybridIndices>(multiIndices);
315  }
316 
317  static const void multiIndexPushFront(MultiIndex& M, size_type M0)
318  {
319  M.resize(M.size()+1);
320  for(std::size_t i=M.size()-1; i>0; --i)
321  M[i] = M[i-1];
322  M[0] = M0;
323  }
324 
325  template<bool hi, class It,
326  typename std::enable_if<not hi,int>::type = 0>
327  It indicesImp(It multiIndices) const
328  {
329  for(std::size_t child=0; child<dim; ++child)
330  {
331  size_type subTreeSize = pq2NodeIndexSet_.size();
332  pq2NodeIndexSet_.indices(multiIndices);
333  for (std::size_t i = 0; i<subTreeSize; ++i)
334  {
335  multiIndexPushFront(multiIndices[i], 0);
336  multiIndices[i][1] = multiIndices[i][1]*dim + child;
337  }
338  multiIndices += subTreeSize;
339  }
340  pq1NodeIndexSet_.indices(multiIndices);
341  size_type subTreeSize = pq1NodeIndexSet_.size();
342  for (std::size_t i = 0; i<subTreeSize; ++i)
343  multiIndexPushFront(multiIndices[i], 1);
344  multiIndices += subTreeSize;
345  return multiIndices;
346  }
347 
348  template<bool hi, class It,
349  typename std::enable_if<hi,int>::type = 0>
350  It indicesImp(It multiIndices) const
351  {
352  for(std::size_t child=0; child<dim; ++child)
353  {
354  size_type subTreeSize = pq2NodeIndexSet_.size();
355  pq2NodeIndexSet_.indices(multiIndices);
356  for (std::size_t i = 0; i<subTreeSize; ++i)
357  {
358  multiIndexPushFront(multiIndices[i], 0);
359  multiIndices[i].push_back(i);
360  }
361  multiIndices += subTreeSize;
362  }
363  pq1NodeIndexSet_.indices(multiIndices);
364  size_type subTreeSize = pq1NodeIndexSet_.size();
365  for (std::size_t i = 0; i<subTreeSize; ++i)
366  multiIndexPushFront(multiIndices[i], 1);
367  multiIndices += subTreeSize;
368  return multiIndices;
369  }
370 
371 private:
372  const PreBasis* preBasis_;
373  PQ1NodeIndexSet pq1NodeIndexSet_;
374  PQ2NodeIndexSet pq2NodeIndexSet_;
375 
376  const Node* node_;
377 };
378 
379 
380 
381 namespace BasisFactory {
382 
383 namespace Imp {
384 
385 class TaylorHoodPreBasisFactory
386 {
387 public:
388  static const std::size_t requiredMultiIndexSize=2;
389 
390  template<class MultiIndex, class GridView>
391  auto makePreBasis(const GridView& gridView) const
392  {
393  return TaylorHoodPreBasis<GridView, MultiIndex>(gridView);
394  }
395 
396 };
397 
398 } // end namespace BasisFactory::Imp
399 
407 {
408  return Imp::TaylorHoodPreBasisFactory();
409 }
410 
411 } // end namespace BasisFactory
412 
413 // *****************************************************************************
414 // This is the actual global basis implementation based on the reusable parts.
415 // *****************************************************************************
416 
438 template<typename GV>
440 
441 
442 
443 } // end namespace Functions
444 } // end namespace Dune
445 
446 
447 #endif // DUNE_FUNCTIONS_FUNCTIONSPACEBASES_TAYLORHOODBASIS_HH
auto taylorHood()
Create a pre-basis factory that can create a Taylor-Hood pre-basis.
Definition: taylorhoodbasis.hh:406
Definition: polynomial.hh:10
Global basis for given pre-basis.
Definition: defaultglobalbasis.hh:47
Definition: lagrangebasis.hh:295
size_type size() const
Same as size(prefix) with empty prefix.
Definition: lagrangebasis.hh:168
void update(const GridView &gv)
Update the stored grid view, to be called if the grid has changed.
Definition: lagrangebasis.hh:143
void initializeIndices()
Initialize the global indices.
Definition: lagrangebasis.hh:113
size_type maxNodeSize() const
Get the maximal number of DOFs associated to node for any element.
Definition: lagrangebasis.hh:211
Definition: nodes.hh:189
Definition: nodes.hh:215
Definition: taylorhoodbasis.hh:230
TaylorHoodVelocityTree()
Definition: taylorhoodbasis.hh:235
Definition: taylorhoodbasis.hh:248
TaylorHoodBasisTree()
Definition: taylorhoodbasis.hh:255
Definition: taylorhoodbasis.hh:266
MI MultiIndex
Type used for global numbering of the basis vectors.
Definition: taylorhoodbasis.hh:276
static const void multiIndexPushFront(MultiIndex &M, size_type M0)
Definition: taylorhoodbasis.hh:317
void unbind()
Definition: taylorhoodbasis.hh:299
typename PreBasis::PQ1PreBasis::IndexSet PQ1NodeIndexSet
Definition: taylorhoodbasis.hh:282
void bind(const Node &node)
Definition: taylorhoodbasis.hh:291
typename PreBasis::PQ2PreBasis::IndexSet PQ2NodeIndexSet
Definition: taylorhoodbasis.hh:283
size_type size() const
Definition: taylorhoodbasis.hh:306
std::size_t size_type
Definition: taylorhoodbasis.hh:273
It indices(It multiIndices) const
Definition: taylorhoodbasis.hh:312
It indicesImp(It multiIndices) const
Definition: taylorhoodbasis.hh:327
TaylorHoodNodeIndexSet(const PreBasis &preBasis)
Definition: taylorhoodbasis.hh:285
Pre-basis for lowest order Taylor-Hood basis.
Definition: taylorhoodbasis.hh:67
size_type size(const SizePrefix prefix) const
Return number of possible values for next position in multi index.
Definition: taylorhoodbasis.hh:156
GV GridView
The grid view that the FE basis is defined on.
Definition: taylorhoodbasis.hh:78
MI MultiIndex
Type used for global numbering of the basis vectors.
Definition: taylorhoodbasis.hh:90
std::size_t size_type
Type used for indices and size information.
Definition: taylorhoodbasis.hh:81
GridView gridView_
Definition: taylorhoodbasis.hh:219
PQ1PreBasis pq1PreBasis_
Definition: taylorhoodbasis.hh:221
TaylorHoodPreBasis(const GridView &gv)
Constructor for a given grid view object.
Definition: taylorhoodbasis.hh:104
Dune::ReservedVector< size_type, 2 > SizePrefix
Type used for prefixes handed to the size() method.
Definition: taylorhoodbasis.hh:93
void update(const GridView &gv)
Update the stored grid view, to be called if the grid has changed.
Definition: taylorhoodbasis.hh:124
PQ2PreBasis pq2PreBasis_
Definition: taylorhoodbasis.hh:222
size_type maxNodeSize() const
Get the maximal number of DOFs associated to node for any element.
Definition: taylorhoodbasis.hh:213
const GridView & gridView() const
Obtain the grid view that the basis is defined on.
Definition: taylorhoodbasis.hh:118
size_type size() const
Same as size(prefix) with empty prefix.
Definition: taylorhoodbasis.hh:150
void initializeIndices()
Initialize the global indices.
Definition: taylorhoodbasis.hh:111
IndexSet makeIndexSet() const
Create tree node index set.
Definition: taylorhoodbasis.hh:144
size_type dimension() const
Get the total dimension of the space spanned by this basis.
Definition: taylorhoodbasis.hh:207
Node makeNode() const
Create tree node.
Definition: taylorhoodbasis.hh:133