3#ifndef DUNE_FUNCTIONS_FUNCTIONSPACEBASES_LAGRANGEBASIS_HH
4#define DUNE_FUNCTIONS_FUNCTIONSPACEBASES_LAGRANGEBASIS_HH
7#include <dune/common/exceptions.hh>
9#include <dune/localfunctions/lagrange.hh>
10#include <dune/localfunctions/lagrange/equidistantpoints.hh>
11#include <dune/localfunctions/lagrange/pqkfactory.hh>
31template<
typename GV,
int k,
typename R=
double>
34template<
typename GV,
int k,
typename R=
double>
35class LagrangePreBasis;
53template<
typename GV,
int k,
typename R>
56 static const int dim = GV::dimension;
57 static const bool useDynamicOrder = (k<0);
83 if (!useDynamicOrder &&
order!=std::numeric_limits<unsigned int>::max())
84 DUNE_THROW(RangeError,
"Template argument k has to be -1 when supplying a run-time order!");
86 for (
int i=0; i<=dim; i++)
166 DUNE_THROW(Dune::NotImplemented,
"No size method for " << dim <<
"d grids available yet!");
170 template<
class SizePrefix>
173 assert(prefix.size() == 0 || prefix.size() == 1);
174 return (prefix.size() == 0) ?
size() : 0;
188 return power(
order()+1, (
unsigned int)GV::dimension);
191 template<
typename It>
196 Dune::LocalKey localKey = node.
finiteElement().localCoefficients().localKey(i);
197 const auto& gridIndexSet =
gridView().indexSet();
198 const auto& element = node.
element();
201 auto dofDim = dim - localKey.codim();
208 if (k==1 || dofDim==0) {
209 *it = {{ (
size_type)(gridIndexSet.subIndex(element,localKey.subEntity(),dim)) }};
219 + localKey.index() }};
224 const auto refElement
225 = Dune::referenceElement<double,dim>(element.type());
229 auto v0 = (
size_type)gridIndexSet.subIndex(element,refElement.subEntity(localKey.subEntity(),localKey.codim(),0,dim),dim);
230 auto v1 = (
size_type)gridIndexSet.subIndex(element,refElement.subEntity(localKey.subEntity(),localKey.codim(),1,dim),dim);
231 bool flip = (v0 > v1);
234 +
dofsPerCube(1)*((
size_type)gridIndexSet.subIndex(element,localKey.subEntity(),localKey.codim()))
237 +
dofsPerCube(1)*((
size_type)gridIndexSet.subIndex(element,localKey.subEntity(),localKey.codim()))
238 + localKey.index() }};
247 if (element.type().isTriangle())
252 else if (element.type().isQuadrilateral())
258 DUNE_THROW(Dune::NotImplemented,
"2d elements have to be triangles or quadrilaterals");
261 const auto refElement
262 = Dune::referenceElement<double,dim>(element.type());
265 DUNE_THROW(Dune::NotImplemented,
"LagrangeBasis for 3D grids is only implemented if k<=3");
267 if (
order()==3 and !refElement.type(localKey.subEntity(), localKey.codim()).isTriangle())
268 DUNE_THROW(Dune::NotImplemented,
"LagrangeBasis for 3D grids with k==3 is only implemented if the grid is a simplex grid");
279 if (element.type().isTetrahedron())
284 else if (element.type().isHexahedron())
289 else if (element.type().isPrism())
294 else if (element.type().isPyramid())
300 DUNE_THROW(Dune::NotImplemented,
"3d elements have to be tetrahedra, hexahedra, prisms, or pyramids");
302 DUNE_THROW(Dune::NotImplemented,
"Grids of dimension larger than 3 are no supported");
304 DUNE_THROW(Dune::NotImplemented,
"Grid contains elements not supported for the LagrangeBasis");
312 return (useDynamicOrder) ?
order_ : k;
346 return order() == 0 ? (dim == simplexDim ? 1 : 0) : Dune::binomial(std::size_t(
order()-1),simplexDim);
384template<
typename GV,
int k,
typename R>
389 template<
typename Domain,
typename Range,
int dim>
390 class LagrangeRunTimeLFECache
393 using FiniteElementType = LagrangeLocalFiniteElement<EquidistantPointSet,dim,Domain,Range>;
395 const FiniteElementType& get(GeometryType type)
397 auto i = data_.find(type);
399 i = data_.emplace(type,FiniteElementType(type,
order_)).first;
403 std::map<GeometryType, FiniteElementType> data_;
407 static constexpr int dim = GV::dimension;
408 static constexpr bool useDynamicOrder = (k<0);
410 using FiniteElementCache =
typename std::conditional<(useDynamicOrder),
411 LagrangeRunTimeLFECache<typename GV::ctype, R, dim>,
412 PQkLocalFiniteElementCache<typename GV::ctype, R, dim, k>
418 using Element =
typename GV::template Codim<0>::Entity;
434 if constexpr (useDynamicOrder)
465 return (useDynamicOrder) ?
order_ : k;
478namespace BasisFactory {
488template<std::
size_t k,
typename R=
double>
491 return [](
const auto& gridView) {
503template<
typename R=
double>
506 return [=](
const auto& gridView) {
507 return LagrangePreBasis<std::decay_t<
decltype(gridView)>, -1, R>(gridView, order);
538template<
typename GV,
int k=-1,
typename R=
double>
auto power(ChildPreBasisFactory &&childPreBasisFactory, const IndexMergingStrategy &)
Create a pre-basis factory that can build a PowerPreBasis.
Definition: powerbasis.hh:369
auto lagrange()
Create a pre-basis factory that can create a Lagrange pre-basis.
Definition: lagrangebasis.hh:489
Definition: polynomial.hh:10
Global basis for given pre-basis.
Definition: defaultglobalbasis.hh:46
Definition: lagrangebasis.hh:387
LagrangeNode(unsigned int order)
Constructor with a run-time order.
Definition: lagrangebasis.hh:428
unsigned int order() const
Definition: lagrangebasis.hh:463
const FiniteElement & finiteElement() const
Return the LocalFiniteElement for the element we are bound to.
Definition: lagrangebasis.hh:448
const Element * element_
Definition: lagrangebasis.hh:473
const Element & element() const
Return current element, throw if unbound.
Definition: lagrangebasis.hh:439
FiniteElementCache cache_
Definition: lagrangebasis.hh:471
typename FiniteElementCache::FiniteElementType FiniteElement
Definition: lagrangebasis.hh:419
void bind(const Element &e)
Bind to element.
Definition: lagrangebasis.hh:454
typename GV::template Codim< 0 >::Entity Element
Definition: lagrangebasis.hh:418
const FiniteElement * finiteElement_
Definition: lagrangebasis.hh:472
unsigned int order_
Definition: lagrangebasis.hh:469
std::size_t size_type
Definition: lagrangebasis.hh:417
LagrangeNode()
Constructor without order (uses the compile-time value)
Definition: lagrangebasis.hh:422
A pre-basis for a PQ-lagrange bases with given order.
Definition: lagrangebasis.hh:55
size_type dofsPerPrism() const
Definition: lagrangebasis.hh:333
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:350
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:344
static constexpr size_type maxMultiIndexSize
Definition: lagrangebasis.hh:70
size_type computeDofsPerPrism() const
Definition: lagrangebasis.hh:355
size_type edgeOffset_
Definition: lagrangebasis.hh:372
std::array< size_type, dim+1 > dofsPerSimplex_
Definition: lagrangebasis.hh:366
It indices(const Node &node, It it) const
Definition: lagrangebasis.hh:192
size_type vertexOffset_
Definition: lagrangebasis.hh:371
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:322
std::size_t size_type
Type used for indices and size information.
Definition: lagrangebasis.hh:65
size_type pyramidOffset_
Definition: lagrangebasis.hh:376
size_type prismOffset_
Definition: lagrangebasis.hh:377
size_type tetrahedronOffset_
Definition: lagrangebasis.hh:375
void initializeIndices()
Initialize the global indices.
Definition: lagrangebasis.hh:96
size_type computeDofsPerPyramid() const
Definition: lagrangebasis.hh:360
LagrangePreBasis(const GridView &gv, unsigned int order)
Constructor for a given grid view object and run-time order.
Definition: lagrangebasis.hh:80
size_type dofsPerPyramid_
Definition: lagrangebasis.hh:369
size_type dimension() const
Get the total dimension of the space spanned by this basis.
Definition: lagrangebasis.hh:178
LagrangePreBasis(const GridView &gv)
Constructor for a given grid view object with compile-time order.
Definition: lagrangebasis.hh:75
void update(const GridView &gv)
Update the stored grid view, to be called if the grid has changed.
Definition: lagrangebasis.hh:126
size_type size(const SizePrefix &prefix) const
Return number of possible values for next position in multi index.
Definition: lagrangebasis.hh:171
static constexpr size_type multiIndexBufferSize
Definition: lagrangebasis.hh:72
GV GridView
The grid view that the FE basis is defined on.
Definition: lagrangebasis.hh:62
size_type quadrilateralOffset_
Definition: lagrangebasis.hh:374
const GridView & gridView() const
Obtain the grid view that the basis is defined on.
Definition: lagrangebasis.hh:120
GridView gridView_
Definition: lagrangebasis.hh:316
Node makeNode() const
Create tree node.
Definition: lagrangebasis.hh:134
unsigned int order() const
Polynomial order used in the local Lagrange finite-elements.
Definition: lagrangebasis.hh:310
const unsigned int order_
Definition: lagrangebasis.hh:319
std::array< size_type, dim+1 > dofsPerCube_
Definition: lagrangebasis.hh:367
size_type maxNodeSize() const
Get the maximal number of DOFs associated to node for any element.
Definition: lagrangebasis.hh:184
size_type size() const
Same as size(prefix) with empty prefix.
Definition: lagrangebasis.hh:140
size_type dofsPerPrism_
Definition: lagrangebasis.hh:368
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:328
size_type triangleOffset_
Definition: lagrangebasis.hh:373
size_type hexahedronOffset_
Definition: lagrangebasis.hh:378
static constexpr size_type minMultiIndexSize
Definition: lagrangebasis.hh:71
size_type dofsPerPyramid() const
Definition: lagrangebasis.hh:338
void setSize(const size_type size)
Definition: nodes.hh:164