DUNE PDELab (2.7)

taylorhoodbasis.hh
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
8
9#include <dune/typetree/powernode.hh>
10#include <dune/typetree/compositenode.hh>
11
12#include <dune/functions/functionspacebases/nodes.hh>
13
14#include <dune/functions/functionspacebases/lagrangebasis.hh>
15#include <dune/functions/functionspacebases/defaultglobalbasis.hh>
16
17namespace Dune {
18namespace 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
34template<typename GV>
35class TaylorHoodVelocityTree;
36
37template<typename GV>
38class TaylorHoodBasisTree;
39
40template<typename GV, class MI, bool HI>
41class TaylorHoodNodeIndexSet;
42
43
44
65template<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
75public:
76
78 using GridView = GV;
79
81 using size_type = std::size_t;
82
84 using Node = TaylorHoodBasisTree<GV>;
85
87 using IndexSet = TaylorHoodNodeIndexSet<GV, MI, HI>;
88
90 using MultiIndex = MI;
91
94
95private:
96
97 using PQMultiIndex = std::array<size_type, 1>;
100
101public:
102
105 gridView_(gv),
106 pq1PreBasis_(gv),
107 pq2PreBasis_(gv)
108 {}
109
112 {
113 pq1PreBasis_.initializeIndices();
114 pq2PreBasis_.initializeIndices();
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
134 {
135 return Node{};
136 }
137
145 {
146 return IndexSet{*this};
147 }
148
151 {
152 return 2;
153 }
154
156 size_type size(const SizePrefix prefix) const
157 {
158 return sizeImp<useHybridIndices>(prefix);
159 }
160
161private:
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
204public:
205
208 {
209 return dim * pq2PreBasis_.size() + pq1PreBasis_.size();
210 }
211
214 {
215 return dim * pq2PreBasis_.maxNodeSize() + pq1PreBasis_.maxNodeSize();
216 }
217
218protected:
219 GridView gridView_;
220
221 PQ1PreBasis pq1PreBasis_;
222 PQ2PreBasis pq2PreBasis_;
223};
224
225
226
227template<typename GV>
228class TaylorHoodVelocityTree :
229 public PowerBasisNode<LagrangeNode<GV,2>, GV::dimension>
230{
231 using PQ2Node = LagrangeNode<GV,2>;
232 using Base = PowerBasisNode<PQ2Node, GV::dimension>;
233
234public:
235 TaylorHoodVelocityTree()
236 {
237 for(int i=0; i<GV::dimension; ++i)
238 this->setChild(i, std::make_shared<PQ2Node>());
239 }
240};
241
242template<typename GV>
243class TaylorHoodBasisTree :
244 public CompositeBasisNode<
245 TaylorHoodVelocityTree<GV>,
246 LagrangeNode<GV,1>
247 >
248{
249 using VelocityNode=TaylorHoodVelocityTree<GV>;
250 using PressureNode=LagrangeNode<GV,1>;
251
252 using Base=CompositeBasisNode<VelocityNode, PressureNode>;
253
254public:
255 TaylorHoodBasisTree()
256 {
257 this->template setChild<0>(std::make_shared<VelocityNode>());
258 this->template setChild<1>(std::make_shared<PressureNode>());
259 }
260};
261
262
263
264template<typename GV, class MI, bool HI>
265class TaylorHoodNodeIndexSet
266{
267 static const bool useHybridIndices = HI;
268
269 static const int dim = GV::dimension;
270
271public:
272
273 using size_type = std::size_t;
274
276 using MultiIndex = MI;
277
278 using PreBasis = TaylorHoodPreBasis<GV, MI, HI>;
279
280 using Node = TaylorHoodBasisTree<GV>;
281
282 using PQ1NodeIndexSet = typename PreBasis::PQ1PreBasis::IndexSet;
283 using PQ2NodeIndexSet = typename PreBasis::PQ2PreBasis::IndexSet;
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
371private:
372 const PreBasis* preBasis_;
373 PQ1NodeIndexSet pq1NodeIndexSet_;
374 PQ2NodeIndexSet pq2NodeIndexSet_;
375
376 const Node* node_;
377};
378
379
380
381namespace BasisFactory {
382
383namespace Imp {
384
385class TaylorHoodPreBasisFactory
386{
387public:
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
438template<typename GV>
440
441
442
443} // end namespace Functions
444} // end namespace Dune
445
446
447#endif // DUNE_FUNCTIONS_FUNCTIONSPACEBASES_TAYLORHOODBASIS_HH
Global basis for given pre-basis.
Definition: defaultglobalbasis.hh:47
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
Pre-basis for lowest order Taylor-Hood basis.
Definition: taylorhoodbasis.hh:67
const GridView & gridView() const
Obtain the grid view that the basis is defined on.
Definition: taylorhoodbasis.hh:118
TaylorHoodBasisTree< GV > Node
Template mapping root tree path to type of created tree node.
Definition: taylorhoodbasis.hh:84
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
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
size_type maxNodeSize() const
Get the maximal number of DOFs associated to node for any element.
Definition: taylorhoodbasis.hh:213
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
TaylorHoodNodeIndexSet< GV, MI, HI > IndexSet
Template mapping root tree path to type of created tree node index set.
Definition: taylorhoodbasis.hh:87
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
Grid view abstract base class.
Definition: gridview.hh:60
A Vector class with statically reserved memory.
Definition: reservedvector.hh:43
A few common exception classes.
constexpr index_constant< 0 > _0
Compile time index with value 0.
Definition: indices.hh:51
constexpr index_constant< 1 > _1
Compile time index with value 1.
Definition: indices.hh:54
auto taylorHood()
Create a pre-basis factory that can create a Taylor-Hood pre-basis.
Definition: taylorhoodbasis.hh:406
ImplementationDefined child(Node &&node, Indices... indices)
Extracts the child of a node given by a sequence of compile-time and run-time indices.
Definition: childextraction.hh:179
Dune namespace.
Definition: alignedallocator.hh:14
An stl-compliant random-access container which stores everything on the stack.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)