3 #ifndef DUNE_FUNCTIONS_FUNCTIONSPACEBASES_PQKNODALBASIS_HH
4 #define DUNE_FUNCTIONS_FUNCTIONSPACEBASES_PQKNODALBASIS_HH
7 #include <dune/common/exceptions.hh>
9 #include <dune/localfunctions/lagrange/pqkfactory.hh>
11 #include <dune/typetree/leafnode.hh>
35 template<
typename GV,
int k,
typename TP>
38 template<
typename GV,
int k,
class MI,
class TP>
41 template<
typename GV,
int k,
class MI>
58 template<
typename GV,
int k,
class MI>
61 static const int dim = GV::dimension;
73 template<
typename,
int,
class,
class>
78 k == 0 ? (dim == 0 ? 1 : 0) : 1;
80 k == 0 ? (dim == 1 ? 1 : 0) : k-1;
82 k == 0 ? (dim == 2 ? 1 : 0) : (k-1)*(k-2)/2;
84 k == 0 ? (dim == 2 ? 1 : 0) : (k-1)*(k-1);
85 const static size_type dofsPerTetrahedron =
86 k == 0 ? (dim == 3 ? 1 : 0) : (k-3)*(k-2)*(k-1)/6;
88 k == 0 ? (dim == 3 ? 1 : 0) : (k-1)*(k-1)*(k-2)/2;
89 const static size_type dofsPerHexahedron =
90 k == 0 ? (dim == 3 ? 1 : 0) : (k-1)*(k-1)*(k-1);
92 k == 0 ? (dim == 3 ? 1 : 0) : (k-2)*(k-1)*(2*k-3)/6;
205 DUNE_THROW(Dune::NotImplemented,
"No size method for " << dim <<
"d grids available yet!");
211 assert(prefix.size() == 0 || prefix.size() == 1);
212 return (prefix.size() == 0) ?
size() : 0;
224 return StaticPower<(k+1),GV::dimension>::
power;
243 template<
typename GV,
int k,
typename TP>
247 static const int dim = GV::dimension;
248 static const int maxSize = StaticPower<(k+1),GV::dimension>::
power;
251 using FiniteElementCache =
typename Dune::PQkLocalFiniteElementCache<typename GV::ctype, double, dim, k>;
257 using Element =
typename GV::template Codim<0>::Entity;
298 template<
typename GV,
int k,
class MI,
class TP>
301 enum {dim = GV::dimension};
340 assert(
node_ !=
nullptr);
341 return node_->finiteElement().size();
345 template<
typename It>
348 assert(
node_ !=
nullptr);
349 for (
size_type i = 0, end =
node_->finiteElement().size() ; i < end ; ++it, ++i)
351 Dune::LocalKey localKey =
node_->finiteElement().localCoefficients().localKey(i);
353 const auto& element =
node_->element();
356 auto dofDim = dim - localKey.codim();
359 *it = {{ (
size_type)(gridIndexSet.subIndex(element,localKey.subEntity(),dim)) }};
369 + localKey.index() }};
374 const auto refElement
375 = Dune::referenceElement<double,dim>(element.type());
379 auto v0 = (
size_type)gridIndexSet.subIndex(element,refElement.subEntity(localKey.subEntity(),localKey.codim(),0,dim),dim);
380 auto v1 = (
size_type)gridIndexSet.subIndex(element,refElement.subEntity(localKey.subEntity(),localKey.codim(),1,dim),dim);
381 bool flip = (v0 > v1);
384 +
preBasis_->dofsPerEdge*((
size_type)gridIndexSet.subIndex(element,localKey.subEntity(),localKey.codim()))
385 + (
preBasis_->dofsPerEdge-1)-localKey.index()
387 +
preBasis_->dofsPerEdge*((
size_type)gridIndexSet.subIndex(element,localKey.subEntity(),localKey.codim()))
388 + localKey.index() }};
397 if (element.type().isTriangle())
399 const int interiorLagrangeNodesPerTriangle = (k-1)*(k-2)/2;
403 else if (element.type().isQuadrilateral())
405 const int interiorLagrangeNodesPerQuadrilateral = (k-1)*(k-1);
410 DUNE_THROW(Dune::NotImplemented,
"2d elements have to be triangles or quadrilaterals");
413 const auto refElement
414 = Dune::referenceElement<double,dim>(element.type());
417 DUNE_THROW(Dune::NotImplemented,
"PQkNodalBasis for 3D grids is only implemented if k<=3");
419 if (k==3 and !refElement.type(localKey.subEntity(), localKey.codim()).isTriangle())
420 DUNE_THROW(Dune::NotImplemented,
"PQkNodalBasis for 3D grids with k==3 is only implemented if the grid is a simplex grid");
431 if (element.type().isTetrahedron())
436 else if (element.type().isHexahedron())
441 else if (element.type().isPrism())
446 else if (element.type().isPyramid())
452 DUNE_THROW(Dune::NotImplemented,
"3d elements have to be tetrahedra, hexahedra, prisms, or pyramids");
454 DUNE_THROW(Dune::NotImplemented,
"Grids of dimension larger than 3 are no supported");
456 DUNE_THROW(Dune::NotImplemented,
"Grid contains elements not supported for the PQkNodalBasis");
469 namespace BasisBuilder {
473 template<std::
size_t k>
474 class PQkPreBasisFactory
477 static const std::size_t requiredMultiIndexSize = 1;
479 template<
class MultiIndex,
class Gr
idView>
480 auto makePreBasis(
const GridView& gridView)
const
498 template<std::
size_t k>
501 return Imp::PQkPreBasisFactory<k>();
527 template<
typename GV,
int k>
536 #endif // DUNE_FUNCTIONS_FUNCTIONSPACEBASES_PQKNODALBASIS_HH