3#ifndef DUNE_FUNCTIONS_FUNCTIONSPACEBASES_LAGRANGEDGBASIS_HH
4#define DUNE_FUNCTIONS_FUNCTIONSPACEBASES_LAGRANGEDGBASIS_HH
7#include <dune/common/exceptions.hh>
8#include <dune/common/math.hh>
10#include <dune/functions/functionspacebases/nodes.hh>
11#include <dune/functions/functionspacebases/defaultglobalbasis.hh>
12#include <dune/functions/functionspacebases/lagrangebasis.hh>
33template<
typename GV,
int k>
34using LagrangeDGNode = LagrangeNode<GV, k>;
36template<
typename GV,
int k>
37class LagrangeDGPreBasis
39 static const int dim = GV::dimension;
45 using size_type = std::size_t;
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;
58 using Node = LagrangeDGNode<GV, k>;
60 static constexpr size_type maxMultiIndexSize = 1;
61 static constexpr size_type minMultiIndexSize = 1;
62 static constexpr size_type multiIndexBufferSize = 1;
65 LagrangeDGPreBasis(
const GridView& gv) :
70 void initializeIndices()
80 quadrilateralOffset_ = dofsPerTriangle * gridView_.size(Dune::GeometryTypes::triangle);
85 prismOffset_ = dofsPerTetrahedron * gridView_.size(Dune::GeometryTypes::tetrahedron);
87 hexahedronOffset_ = prismOffset_ + dofsPerPrism * gridView_.size(Dune::GeometryTypes::prism);
89 pyramidOffset_ = hexahedronOffset_ + dofsPerHexahedron * gridView_.size(Dune::GeometryTypes::hexahedron);
97 const GridView& gridView()
const
102 void update(
const GridView& gv)
110 Node makeNode()
const
115 size_type size()
const
120 return dofsPerEdge*gridView_.size(0);
123 return dofsPerTriangle*gridView_.size(Dune::GeometryTypes::triangle) + dofsPerQuad*gridView_.size(Dune::GeometryTypes::quadrilateral);
127 return dofsPerTetrahedron*gridView_.size(Dune::GeometryTypes::tetrahedron)
128 + dofsPerPyramid*gridView_.size(Dune::GeometryTypes::pyramid)
129 + dofsPerPrism*gridView_.size(Dune::GeometryTypes::prism)
130 + dofsPerHexahedron*gridView_.size(Dune::GeometryTypes::hexahedron);
133 DUNE_THROW(Dune::NotImplemented,
"No size method for " << dim <<
"d grids available yet!");
137 template<
class SizePrefix>
138 size_type size(
const SizePrefix& prefix)
const
140 assert(prefix.size() == 0 || prefix.size() == 1);
141 return (prefix.size() == 0) ? size() : 0;
145 size_type dimension()
const
150 size_type maxNodeSize()
const
155 template<
typename It>
156 It indices(
const Node& node, It it)
const
158 const auto& gridIndexSet = gridView().indexSet();
159 const auto& element = node.element();
161 size_type offset = 0;
162 if constexpr (dim==1)
163 offset = dofsPerEdge*gridIndexSet.subIndex(element,0,0);
164 else if constexpr (dim==2)
166 if (element.type().isTriangle())
167 offset = dofsPerTriangle*gridIndexSet.subIndex(element,0,0);
168 else if (element.type().isQuadrilateral())
169 offset = quadrilateralOffset_ + dofsPerQuad*gridIndexSet.subIndex(element,0,0);
171 DUNE_THROW(Dune::NotImplemented,
"2d elements have to be triangles or quadrilaterals");
173 else if constexpr (dim==3)
175 if (element.type().isTetrahedron())
176 offset = dofsPerTetrahedron*gridIndexSet.subIndex(element,0,0);
177 else if (element.type().isPrism())
178 offset = prismOffset_ + dofsPerPrism*gridIndexSet.subIndex(element,0,0);
179 else if (element.type().isHexahedron())
180 offset = hexahedronOffset_ + dofsPerHexahedron*gridIndexSet.subIndex(element,0,0);
181 else if (element.type().isPyramid())
182 offset = pyramidOffset_ + dofsPerPyramid*gridIndexSet.subIndex(element,0,0);
184 DUNE_THROW(Dune::NotImplemented,
"3d elements have to be tetrahedrons, prisms, hexahedrons or pyramids");
187 DUNE_THROW(Dune::NotImplemented,
"No index method for " << dim <<
"d grids available yet!");
188 for (size_type i = 0, end = node.size() ; i < end ; ++i, ++it)
194 unsigned int order()
const
202 size_t quadrilateralOffset_;
203 size_t pyramidOffset_;
205 size_t hexahedronOffset_;
210namespace BasisFactory {
219template<std::
size_t k>
222 return [](
const auto& gridView) {
223 return LagrangeDGPreBasis<std::decay_t<
decltype(gridView)>, k>(gridView);
242template<
typename GV,
int k>
Global basis for given pre-basis.
Definition: defaultglobalbasis.hh:46
auto power(ChildPreBasisFactory &&childPreBasisFactory, const IndexMergingStrategy &)
Create a pre-basis factory that can build a PowerPreBasis.
Definition: powerbasis.hh:369
auto lagrangeDG()
Create a pre-basis factory that can create a LagrangeDG pre-basis.
Definition: lagrangedgbasis.hh:220
Definition: polynomial.hh:10