DUNE-FUNCTIONS (2.8)

lagrangedgbasis.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_LAGRANGEDGBASIS_HH
4#define DUNE_FUNCTIONS_FUNCTIONSPACEBASES_LAGRANGEDGBASIS_HH
5
6#include <array>
7#include <dune/common/exceptions.hh>
8
9#include <dune/functions/functionspacebases/nodes.hh>
10#include <dune/functions/functionspacebases/defaultglobalbasis.hh>
11#include <dune/functions/functionspacebases/flatmultiindex.hh>
12#include <dune/functions/functionspacebases/lagrangebasis.hh>
13
14
15
16
17namespace Dune {
18namespace Functions {
19
20
21
22// *****************************************************************************
23// This is the reusable part of the basis. It contains
24//
25// LagrangeDGPreBasis
26// LagrangeDGNode
27//
28// The pre-basis allows to create the others and is the owner of possible shared
29// state. These components do _not_ depend on the global basis and local view
30// and can be used without a global basis.
31// *****************************************************************************
32
33template<typename GV, int k>
34using LagrangeDGNode = LagrangeNode<GV, k>;
35
36template<typename GV, int k, class MI>
37class LagrangeDGPreBasis
38{
39 static const int dim = GV::dimension;
40
41public:
42
44 using GridView = GV;
45 using size_type = std::size_t;
46
47
48 // Precompute the number of dofs per entity type
49 const static int dofsPerEdge = k+1;
50 const static int dofsPerTriangle = (k+1)*(k+2)/2;
51 const static int dofsPerQuad = (k+1)*(k+1);
52 const static int dofsPerTetrahedron = (k+1)*(k+2)*(k+3)/6;
53 const static int dofsPerPrism = (k+1)*(k+1)*(k+2)/2;
54 const static int dofsPerHexahedron = (k+1)*(k+1)*(k+1);
55 const static int dofsPerPyramid = (k+1)*(k+2)*(2*k+3)/6;
56
57
58 using Node = LagrangeDGNode<GV, k>;
59
61 using IndexSet = Impl::DefaultNodeIndexSet<LagrangeDGPreBasis>;
62
64 using MultiIndex = MI;
65
66 using SizePrefix = Dune::ReservedVector<size_type, 1>;
67
69 LagrangeDGPreBasis(const GridView& gv) :
70 gridView_(gv)
71 {}
72
73
74 void initializeIndices()
75 {
76 switch (dim)
77 {
78 case 1:
79 {
80 break;
81 }
82 case 2:
83 {
84 quadrilateralOffset_ = dofsPerTriangle * gridView_.size(Dune::GeometryTypes::triangle);
85 break;
86 }
87 case 3:
88 {
89 prismOffset_ = dofsPerTetrahedron * gridView_.size(Dune::GeometryTypes::tetrahedron);
90
91 hexahedronOffset_ = prismOffset_ + dofsPerPrism * gridView_.size(Dune::GeometryTypes::prism);
92
93 pyramidOffset_ = hexahedronOffset_ + dofsPerHexahedron * gridView_.size(Dune::GeometryTypes::hexahedron);
94 break;
95 }
96 }
97 }
98
101 const GridView& gridView() const
102 {
103 return gridView_;
104 }
105
106 void update(const GridView& gv)
107 {
108 gridView_ = gv;
109 }
110
114 Node makeNode() const
115 {
116 return Node{};
117 }
118
126 [[deprecated("Warning: The IndexSet typedef and the makeIndexSet method are deprecated. "\
127 "As a replacement use the indices() method of the PreBasis directly.")]]
128 IndexSet makeIndexSet() const
129 {
130 return IndexSet{*this};
131 }
132
133 size_type size() const
134 {
135 switch (dim)
136 {
137 case 1:
138 return dofsPerEdge*gridView_.size(0);
139 case 2:
140 {
141 return dofsPerTriangle*gridView_.size(Dune::GeometryTypes::triangle) + dofsPerQuad*gridView_.size(Dune::GeometryTypes::quadrilateral);
142 }
143 case 3:
144 {
145 return dofsPerTetrahedron*gridView_.size(Dune::GeometryTypes::tetrahedron)
146 + dofsPerPyramid*gridView_.size(Dune::GeometryTypes::pyramid)
147 + dofsPerPrism*gridView_.size(Dune::GeometryTypes::prism)
148 + dofsPerHexahedron*gridView_.size(Dune::GeometryTypes::hexahedron);
149 }
150 }
151 DUNE_THROW(Dune::NotImplemented, "No size method for " << dim << "d grids available yet!");
152 }
153
155 size_type size(const SizePrefix prefix) const
156 {
157 assert(prefix.size() == 0 || prefix.size() == 1);
158 return (prefix.size() == 0) ? size() : 0;
159 }
160
162 size_type dimension() const
163 {
164 return size();
165 }
166
167 size_type maxNodeSize() const
168 {
169 return StaticPower<(k+1),GV::dimension>::power;
170 }
171
172 template<typename It>
173 It indices(const Node& node, It it) const
174 {
175 const auto& gridIndexSet = gridView().indexSet();
176 const auto& element = node.element();
177
178 for (size_type i = 0, end = node.size() ; i < end ; ++i, ++it)
179 {
180 switch (dim)
181 {
182 case 1:
183 {
184 *it = {dofsPerEdge*gridIndexSet.subIndex(element,0,0) + i};
185 continue;
186 }
187 case 2:
188 {
189 if (element.type().isTriangle())
190 {
191 *it = {dofsPerTriangle*gridIndexSet.subIndex(element,0,0) + i};
192 continue;
193 }
194 else if (element.type().isQuadrilateral())
195 {
196 *it = { quadrilateralOffset_ + dofsPerQuad*gridIndexSet.subIndex(element,0,0) + i};
197 continue;
198 }
199 else
200 DUNE_THROW(Dune::NotImplemented, "2d elements have to be triangles or quadrilaterals");
201 }
202 case 3:
203 {
204 if (element.type().isTetrahedron())
205 {
206 *it = {dofsPerTetrahedron*gridIndexSet.subIndex(element,0,0) + i};
207 continue;
208 }
209 else if (element.type().isPrism())
210 {
211 *it = { prismOffset_ + dofsPerPrism*gridIndexSet.subIndex(element,0,0) + i};
212 continue;
213 }
214 else if (element.type().isHexahedron())
215 {
216 *it = { hexahedronOffset_ + dofsPerHexahedron*gridIndexSet.subIndex(element,0,0) + i};
217 continue;
218 }
219 else if (element.type().isPyramid())
220 {
221 *it = { pyramidOffset_ + dofsPerPyramid*gridIndexSet.subIndex(element,0,0) + i};
222 continue;
223 }
224 else
225 DUNE_THROW(Dune::NotImplemented, "3d elements have to be tetrahedrons, prisms, hexahedrons or pyramids");
226 }
227 }
228 DUNE_THROW(Dune::NotImplemented, "No index method for " << dim << "d grids available yet!");
229 }
230 return it;
231 }
232
233
234protected:
235 GridView gridView_;
236
237 size_t quadrilateralOffset_;
238 size_t pyramidOffset_;
239 size_t prismOffset_;
240 size_t hexahedronOffset_;
241};
242
243
244
245namespace BasisFactory {
246
247namespace Imp {
248
249template<std::size_t k>
250class LagrangeDGPreBasisFactory
251{
252public:
253 static const std::size_t requiredMultiIndexSize = 1;
254
255 template<class MultiIndex, class GridView>
256 auto makePreBasis(const GridView& gridView) const
257 {
258 return LagrangeDGPreBasis<GridView, k, MultiIndex>(gridView);
259 }
260
261};
262
263} // end namespace BasisFactory::Imp
264
265
266
274template<std::size_t k>
276{
277 return Imp::LagrangeDGPreBasisFactory<k>();
278}
279
280} // end namespace BasisFactory
281
282
283
284// *****************************************************************************
285// This is the actual global basis implementation based on the reusable parts.
286// *****************************************************************************
287
295template<typename GV, int k>
297
298
299
300} // end namespace Functions
301} // end namespace Dune
302
303
304#endif // DUNE_FUNCTIONS_FUNCTIONSPACEBASES_LAGRANGEDGBASIS_HH
Global basis for given pre-basis.
Definition: defaultglobalbasis.hh:47
auto power(ChildPreBasisFactory &&childPreBasisFactory, const IndexMergingStrategy &ims)
Create a pre-basis factory that can build a PowerPreBasis.
Definition: powerbasis.hh:425
auto lagrangeDG()
Create a pre-basis factory that can create a LagrangeDG pre-basis.
Definition: lagrangedgbasis.hh:275
Definition: polynomial.hh:10
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)