7#ifndef DUNE_FUNCTIONS_FUNCTIONSPACEBASES_LAGRANGEBASIS_HH
8#define DUNE_FUNCTIONS_FUNCTIONSPACEBASES_LAGRANGEBASIS_HH
11#include <dune/common/exceptions.hh>
13#include <dune/localfunctions/lagrange.hh>
14#include <dune/localfunctions/lagrange/equidistantpoints.hh>
15#include <dune/localfunctions/lagrange/lagrangelfecache.hh>
36template<
typename GV,
int k,
typename R=
double>
39template<
typename GV,
int k,
typename R=
double>
40class LagrangePreBasis;
58template<
typename GV,
int k,
typename R>
62 static const int dim = GV::dimension;
63 static const bool useDynamicOrder = (k<0);
85 if (!useDynamicOrder &&
order!=std::numeric_limits<unsigned int>::max())
86 DUNE_THROW(RangeError,
"Template argument k has to be -1 when supplying a run-time order!");
88 for (
int i=0; i<=dim; i++)
168 DUNE_THROW(Dune::NotImplemented,
"No size method for " << dim <<
"d grids available yet!");
176 return power(
order()+1, (
unsigned int)GV::dimension);
179 template<
typename It>
184 Dune::LocalKey localKey = node.
finiteElement().localCoefficients().localKey(i);
185 const auto& gridIndexSet =
gridView().indexSet();
186 const auto& element = node.
element();
189 auto dofDim = dim - localKey.codim();
196 if (k==1 || dofDim==0) {
197 *it = {{ (
size_type)(gridIndexSet.subIndex(element,localKey.subEntity(),dim)) }};
207 + localKey.index() }};
212 const auto refElement
213 = Dune::referenceElement<double,dim>(element.type());
217 auto v0 = (
size_type)gridIndexSet.subIndex(element,refElement.subEntity(localKey.subEntity(),localKey.codim(),0,dim),dim);
218 auto v1 = (
size_type)gridIndexSet.subIndex(element,refElement.subEntity(localKey.subEntity(),localKey.codim(),1,dim),dim);
219 bool flip = (v0 > v1);
222 +
dofsPerCube(1)*((
size_type)gridIndexSet.subIndex(element,localKey.subEntity(),localKey.codim()))
225 +
dofsPerCube(1)*((
size_type)gridIndexSet.subIndex(element,localKey.subEntity(),localKey.codim()))
226 + localKey.index() }};
235 if (element.type().isTriangle())
240 else if (element.type().isQuadrilateral())
246 DUNE_THROW(Dune::NotImplemented,
"2d elements have to be triangles or quadrilaterals");
249 const auto refElement
250 = Dune::referenceElement<double,dim>(element.type());
253 DUNE_THROW(Dune::NotImplemented,
"LagrangeBasis for 3D grids is only implemented if k<=3");
255 if (
order()==3 and !refElement.type(localKey.subEntity(), localKey.codim()).isTriangle())
256 DUNE_THROW(Dune::NotImplemented,
"LagrangeBasis for 3D grids with k==3 is only implemented if the grid is a simplex grid");
267 if (element.type().isTetrahedron())
272 else if (element.type().isHexahedron())
277 else if (element.type().isPrism())
282 else if (element.type().isPyramid())
288 DUNE_THROW(Dune::NotImplemented,
"3d elements have to be tetrahedra, hexahedra, prisms, or pyramids");
290 DUNE_THROW(Dune::NotImplemented,
"Grids of dimension larger than 3 are no supported");
292 DUNE_THROW(Dune::NotImplemented,
"Grid contains elements not supported for the LagrangeBasis");
300 return (useDynamicOrder) ?
order_ : k;
334 return order() == 0 ? (dim == simplexDim ? 1 : 0) : Dune::binomial(std::size_t(
order()-1),simplexDim);
340 return order() == 0 ? (dim == cubeDim ? 1 : 0) : Dune::power(
order()-1, cubeDim);
372template<
typename GV,
int k,
typename R>
377 template<
typename Domain,
typename Range,
int dim>
378 class LagrangeRunTimeLFECache
381 using FiniteElementType = LagrangeLocalFiniteElement<EquidistantPointSet,dim,Domain,Range>;
383 const FiniteElementType& get(GeometryType type)
385 auto i = data_.find(type);
387 i = data_.emplace(type,FiniteElementType(type,order_)).first;
391 std::map<GeometryType, FiniteElementType> data_;
395 static constexpr int dim = GV::dimension;
396 static constexpr bool useDynamicOrder = (k<0);
398 using FiniteElementCache = std::conditional_t<(useDynamicOrder),
399 LagrangeRunTimeLFECache<typename GV::ctype, R, dim>,
400 LagrangeLocalFiniteElementCache<
typename GV::ctype, R, dim, std::max(k,0)>
406 using Element =
typename GV::template Codim<0>::Entity;
422 if constexpr (useDynamicOrder)
453 return (useDynamicOrder) ?
order_ : k;
466namespace BasisFactory {
476template<std::
size_t k,
typename R=
double>
479 return [](
const auto& gridView) {
491template<
typename R=
double>
494 return [=](
const auto& gridView) {
495 return LagrangePreBasis<std::decay_t<
decltype(gridView)>, -1, R>(gridView, order);
526template<
typename GV,
int k=-1,
typename R=
double>
auto lagrange()
Create a pre-basis factory that can create a Lagrange pre-basis.
Definition lagrangebasis.hh:477
Definition polynomial.hh:17
Global basis for given pre-basis.
Definition defaultglobalbasis.hh:50
Definition lagrangebasis.hh:375
LagrangeNode(unsigned int order)
Constructor with a run-time order.
Definition lagrangebasis.hh:416
unsigned int order() const
Definition lagrangebasis.hh:451
const FiniteElement & finiteElement() const
Return the LocalFiniteElement for the element we are bound to.
Definition lagrangebasis.hh:436
const Element * element_
Definition lagrangebasis.hh:461
const Element & element() const
Return current element, throw if unbound.
Definition lagrangebasis.hh:427
FiniteElementCache cache_
Definition lagrangebasis.hh:459
typename FiniteElementCache::FiniteElementType FiniteElement
Definition lagrangebasis.hh:407
void bind(const Element &e)
Bind to element.
Definition lagrangebasis.hh:442
typename GV::template Codim< 0 >::Entity Element
Definition lagrangebasis.hh:406
const FiniteElement * finiteElement_
Definition lagrangebasis.hh:460
unsigned int order_
Definition lagrangebasis.hh:457
std::size_t size_type
Definition lagrangebasis.hh:405
LagrangeNode()
Constructor without order (uses the compile-time value)
Definition lagrangebasis.hh:410
A pre-basis for a PQ-lagrange bases with given order.
Definition lagrangebasis.hh:61
size_type dofsPerPrism() const
Definition lagrangebasis.hh:321
size_type computeDofsPerCube(std::size_t cubeDim) const
Number of degrees of freedom assigned to a cube (without the ones assigned to its faces!...
Definition lagrangebasis.hh:338
size_type computeDofsPerSimplex(std::size_t simplexDim) const
Number of degrees of freedom assigned to a simplex (without the ones assigned to its faces!...
Definition lagrangebasis.hh:332
size_type computeDofsPerPrism() const
Definition lagrangebasis.hh:343
unsigned int order_
Definition lagrangebasis.hh:307
size_type edgeOffset_
Definition lagrangebasis.hh:360
std::array< size_type, dim+1 > dofsPerSimplex_
Definition lagrangebasis.hh:354
It indices(const Node &node, It it) const
Definition lagrangebasis.hh:180
size_type vertexOffset_
Definition lagrangebasis.hh:359
size_type dofsPerSimplex(std::size_t simplexDim) const
Number of degrees of freedom assigned to a simplex (without the ones assigned to its faces!...
Definition lagrangebasis.hh:310
std::size_t size_type
Type used for indices and size information.
Definition lagrangebasis.hh:71
size_type pyramidOffset_
Definition lagrangebasis.hh:364
size_type prismOffset_
Definition lagrangebasis.hh:365
size_type tetrahedronOffset_
Definition lagrangebasis.hh:363
void initializeIndices()
Initialize the global indices.
Definition lagrangebasis.hh:98
size_type computeDofsPerPyramid() const
Definition lagrangebasis.hh:348
LagrangePreBasis(const GridView &gv, unsigned int order)
Constructor for a given grid view object and run-time order.
Definition lagrangebasis.hh:82
size_type dofsPerPyramid_
Definition lagrangebasis.hh:357
size_type dimension() const
Get the total dimension of the space spanned by this basis.
Definition lagrangebasis.hh:142
LagrangePreBasis(const GridView &gv)
Constructor for a given grid view object with compile-time order.
Definition lagrangebasis.hh:77
void update(const GridView &gv)
Update the stored grid view, to be called if the grid has changed.
Definition lagrangebasis.hh:128
GV GridView
The grid view that the FE basis is defined on.
Definition lagrangebasis.hh:68
size_type quadrilateralOffset_
Definition lagrangebasis.hh:362
const GridView & gridView() const
Obtain the grid view that the basis is defined on.
Definition lagrangebasis.hh:122
GridView gridView_
Definition lagrangebasis.hh:304
Node makeNode() const
Create tree node.
Definition lagrangebasis.hh:136
unsigned int order() const
Polynomial order used in the local Lagrange finite-elements.
Definition lagrangebasis.hh:298
std::array< size_type, dim+1 > dofsPerCube_
Definition lagrangebasis.hh:355
size_type maxNodeSize() const
Get the maximal number of DOFs associated to node for any element.
Definition lagrangebasis.hh:172
size_type dofsPerPrism_
Definition lagrangebasis.hh:356
size_type dofsPerCube(std::size_t cubeDim) const
Number of degrees of freedom assigned to a cube (without the ones assigned to its faces!...
Definition lagrangebasis.hh:316
size_type triangleOffset_
Definition lagrangebasis.hh:361
size_type hexahedronOffset_
Definition lagrangebasis.hh:366
size_type dofsPerPyramid() const
Definition lagrangebasis.hh:326
A generic MixIn class for PreBasis.
Definition leafprebasismixin.hh:36
void setSize(const size_type size)
Definition nodes.hh:169