DUNE-FUNCTIONS (unstable)

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
4// SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file AUTHORS.md
5// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception OR LGPL-3.0-or-later
6
7#ifndef DUNE_FUNCTIONS_FUNCTIONSPACEBASES_TAYLORHOODBASIS_HH
8#define DUNE_FUNCTIONS_FUNCTIONSPACEBASES_TAYLORHOODBASIS_HH
9
10#include <dune/common/exceptions.hh>
11#include <dune/common/reservedvector.hh>
12#include <dune/common/indices.hh>
13
14#include <dune/typetree/powernode.hh>
15#include <dune/typetree/compositenode.hh>
16
17#include <dune/functions/functionspacebases/nodes.hh>
18
19#include <dune/functions/functionspacebases/lagrangebasis.hh>
20#include <dune/functions/functionspacebases/defaultglobalbasis.hh>
21
22namespace Dune {
23namespace Functions {
24
25
26// *****************************************************************************
27// This is the reusable part of the basis. It contains
28//
29// TaylorHoodPreBasis
30// TaylorHoodBasisTree
31// TaylorHoodVelocityTree
32//
33// The pre-basis allows to create the others and is the owner of possible shared
34// state. These components do _not_ depend on the global basis and local view
35// and can be used without a global basis.
36// *****************************************************************************
37
38template<typename GV>
39class TaylorHoodVelocityTree;
40
41template<typename GV>
42class TaylorHoodBasisTree;
43
63template<typename GV, bool HI=false>
65{
66 static const bool useHybridIndices = HI;
67
68 static const int dim = GV::dimension;
69
70public:
71
73 using GridView = GV;
74
76 using size_type = std::size_t;
77
79 using Node = TaylorHoodBasisTree<GV>;
80
81 static constexpr size_type maxMultiIndexSize = useHybridIndices ? 3 : 2;
82 static constexpr size_type minMultiIndexSize = 2;
83 static constexpr size_type multiIndexBufferSize = maxMultiIndexSize;
84
85private:
86
89
90public:
91
94 gridView_(gv),
95 pq1PreBasis_(gv),
96 pq2PreBasis_(gv)
97 {}
98
101 {
102 pq1PreBasis_.initializeIndices();
103 pq2PreBasis_.initializeIndices();
104 }
105
107 const GridView& gridView() const
108 {
109 return gridView_;
110 }
111
113 void update (const GridView& gv)
114 {
115 pq1PreBasis_.update(gv);
116 pq2PreBasis_.update(gv);
117 }
118
123 {
124 return Node{};
125 }
126
129 {
130 return 2;
131 }
132
134 template<class SizePrefix>
135 size_type size(const SizePrefix& prefix) const
136 {
137 return sizeImp<useHybridIndices>(prefix);
138 }
139
140private:
141
142 template<bool hi, class SizePrefix,
143 std::enable_if_t<not hi,int> = 0>
144 size_type sizeImp(const SizePrefix& prefix) const
145 {
146 if (prefix.size() == 0)
147 return 2;
148 if (prefix.size() == 1)
149 {
150 if (prefix[0] == 0)
151 return dim * pq2PreBasis_.size();
152 if (prefix[0] == 1)
153 return pq1PreBasis_.size();
154 }
155 assert(prefix.size() == 2);
156 return 0;
157 }
158
159 template<bool hi, class SizePrefix,
160 std::enable_if_t<hi,int> = 0>
161 size_type sizeImp(const SizePrefix& prefix) const
162 {
163 if (prefix.size() == 0)
164 return 2;
165 if (prefix.size() == 1)
166 {
167 if (prefix[0] == 0)
168 return pq2PreBasis_.size();
169 if (prefix[0] == 1)
170 return pq1PreBasis_.size();
171 }
172 if (prefix.size() == 2)
173 {
174 if (prefix[0] == 0)
175 return dim;
176 if (prefix[0] == 1)
177 return 0;
178 }
179 assert(prefix.size() == 3);
180 return 0;
181 }
182
183public:
184
187 {
188 return dim * pq2PreBasis_.size() + pq1PreBasis_.size();
189 }
190
193 {
194 return dim * pq2PreBasis_.maxNodeSize() + pq1PreBasis_.maxNodeSize();
195 }
196
197 template<typename It>
198 It indices(const Node& node, It it) const
199 {
200 return indicesImp<useHybridIndices>(node, it);
201 }
202
209 {
210 namespace CD = Dune::Functions::ContainerDescriptors;
211 if constexpr(HI)
212 return CD::makeDescriptor(
213 CD::makeUniformDescriptor(pq2PreBasis_.size(),
215 CD::FlatVector{pq1PreBasis_.size()});
216 else
217 return CD::Array<CD::FlatVector,2>{
218 CD::FlatVector{GV::dimension * pq2PreBasis_.size()},
219 CD::FlatVector{pq1PreBasis_.size()} };
220 }
221
222protected:
223
224 template<class MultiIndex>
225 static const void multiIndexPushFront(MultiIndex& M, size_type M0)
226 {
227 M.resize(M.size()+1);
228 for(std::size_t i=M.size()-1; i>0; --i)
229 M[i] = M[i-1];
230 M[0] = M0;
231 }
232
233 template<bool hi, class It,
234 std::enable_if_t<not hi,int> = 0>
235 It indicesImp(const Node& node, It multiIndices) const
236 {
237 using namespace Dune::Indices;
238 for(std::size_t child=0; child<dim; ++child)
239 {
240 size_type subTreeSize = node.child(_0, 0).size();
241 pq2PreBasis_.indices(node.child(_0, 0), multiIndices);
242 for (std::size_t i = 0; i<subTreeSize; ++i)
243 {
244 multiIndexPushFront(multiIndices[i], 0);
245 multiIndices[i][1] = multiIndices[i][1]*dim + child;
246 }
247 multiIndices += subTreeSize;
248 }
249 size_type subTreeSize = node.child(_1).size();
250 pq1PreBasis_.indices(node.child(_1), multiIndices);
251 for (std::size_t i = 0; i<subTreeSize; ++i)
252 multiIndexPushFront(multiIndices[i], 1);
253 multiIndices += subTreeSize;
254 return multiIndices;
255 }
256
257 template<bool hi, class It,
258 std::enable_if_t<hi,int> = 0>
259 It indicesImp(const Node& node, It multiIndices) const
260 {
261 using namespace Dune::Indices;
262 for(std::size_t child=0; child<dim; ++child)
263 {
264 size_type subTreeSize = node.child(_0, 0).size();
265 pq2PreBasis_.indices(node.child(_0, 0), multiIndices);
266 for (std::size_t i = 0; i<subTreeSize; ++i)
267 {
268 multiIndexPushFront(multiIndices[i], 0);
269 multiIndices[i].push_back(i);
270 }
271 multiIndices += subTreeSize;
272 }
273 size_type subTreeSize = node.child(_1).size();
274 pq1PreBasis_.indices(node.child(_1), multiIndices);
275 for (std::size_t i = 0; i<subTreeSize; ++i)
276 multiIndexPushFront(multiIndices[i], 1);
277 multiIndices += subTreeSize;
278 return multiIndices;
279 }
280
281 GridView gridView_;
282
283 PQ1PreBasis pq1PreBasis_;
284 PQ2PreBasis pq2PreBasis_;
285};
286
287
288
289template<typename GV>
290class TaylorHoodVelocityTree :
291 public PowerBasisNode<LagrangeNode<GV,2>, GV::dimension>
292{
293 using PQ2Node = LagrangeNode<GV,2>;
294 using Base = PowerBasisNode<PQ2Node, GV::dimension>;
295
296public:
297 TaylorHoodVelocityTree()
298 {
299 for(int i=0; i<GV::dimension; ++i)
300 this->setChild(i, std::make_shared<PQ2Node>());
301 }
302};
303
304template<typename GV>
305class TaylorHoodBasisTree :
306 public CompositeBasisNode<
307 TaylorHoodVelocityTree<GV>,
308 LagrangeNode<GV,1>
309 >
310{
311 using VelocityNode=TaylorHoodVelocityTree<GV>;
312 using PressureNode=LagrangeNode<GV,1>;
313
314 using Base=CompositeBasisNode<VelocityNode, PressureNode>;
315
316public:
317 TaylorHoodBasisTree()
318 {
319 this->template setChild<0>(std::make_shared<VelocityNode>());
320 this->template setChild<1>(std::make_shared<PressureNode>());
321 }
322};
323
324
325
326namespace BasisFactory {
327
334inline auto taylorHood()
335{
336 return [](const auto& gridView) {
337 return TaylorHoodPreBasis<std::decay_t<decltype(gridView)>>(gridView);
338 };
339}
340
341} // end namespace BasisFactory
342
343// *****************************************************************************
344// This is the actual global basis implementation based on the reusable parts.
345// *****************************************************************************
346
368template<typename GV>
370
371
372
373} // end namespace Functions
374} // end namespace Dune
375
376
377#endif // DUNE_FUNCTIONS_FUNCTIONSPACEBASES_TAYLORHOODBASIS_HH
Global basis for given pre-basis.
Definition: defaultglobalbasis.hh:50
void initializeIndices()
Initialize the global indices.
Definition: lagrangebasis.hh:98
void update(const GridView &gv)
Update the stored grid view, to be called if the grid has changed.
Definition: lagrangebasis.hh:128
size_type maxNodeSize() const
Get the maximal number of DOFs associated to node for any element.
Definition: lagrangebasis.hh:172
size_type size(const SizePrefix &prefix) const
Return number of possible values for next position in multi index.
Definition: leafprebasismixin.hh:53
Pre-basis for lowest order Taylor-Hood basis.
Definition: taylorhoodbasis.hh:65
TaylorHoodPreBasis(const GridView &gv)
Constructor for a given grid view object.
Definition: taylorhoodbasis.hh:93
const GridView & gridView() const
Obtain the grid view that the basis is defined on.
Definition: taylorhoodbasis.hh:107
size_type size(const SizePrefix &prefix) const
Return number of possible values for next position in multi index.
Definition: taylorhoodbasis.hh:135
GV GridView
The grid view that the FE basis is defined on.
Definition: taylorhoodbasis.hh:73
void update(const GridView &gv)
Update the stored grid view, to be called if the grid has changed.
Definition: taylorhoodbasis.hh:113
auto containerDescriptor() const
Return an container descriptor depending on the flag HI. Either return a Tuple if hybrid indices shou...
Definition: taylorhoodbasis.hh:208
TaylorHoodBasisTree< GV > Node
Template mapping root tree path to type of created tree node.
Definition: taylorhoodbasis.hh:79
size_type size() const
Same as size(prefix) with empty prefix.
Definition: taylorhoodbasis.hh:128
size_type dimension() const
Get the total dimension of the space spanned by this basis.
Definition: taylorhoodbasis.hh:186
Node makeNode() const
Create tree node.
Definition: taylorhoodbasis.hh:122
void initializeIndices()
Initialize the global indices.
Definition: taylorhoodbasis.hh:100
size_type maxNodeSize() const
Get the maximal number of DOFs associated to node for any element.
Definition: taylorhoodbasis.hh:192
std::size_t size_type
Type used for indices and size information.
Definition: taylorhoodbasis.hh:76
auto taylorHood()
Create a pre-basis factory that can create a Taylor-Hood pre-basis.
Definition: taylorhoodbasis.hh:334
Definition: polynomial.hh:17
Descriptor for arrays with all children identical and the number of children a static size.
Definition: containerdescriptors.hh:129
Uniform descriptor with dynamic size.
Definition: containerdescriptors.hh:168
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Aug 13, 22:30, 2024)