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>
60 template<
typename GV,
int k,
class MI>
63 static const int dim = GV::dimension;
75 template<
typename,
int,
class,
class>
80 k == 0 ? (dim == 0 ? 1 : 0) : 1;
82 k == 0 ? (dim == 1 ? 1 : 0) : k-1;
84 k == 0 ? (dim == 2 ? 1 : 0) : (k-1)*(k-2)/2;
86 k == 0 ? (dim == 2 ? 1 : 0) : (k-1)*(k-1);
87 const static size_type dofsPerTetrahedron =
88 k == 0 ? (dim == 3 ? 1 : 0) : (k-3)*(k-2)*(k-1)/6;
90 k == 0 ? (dim == 3 ? 1 : 0) : (k-1)*(k-1)*(k-2)/2;
91 const static size_type dofsPerHexahedron =
92 k == 0 ? (dim == 3 ? 1 : 0) : (k-1)*(k-1)*(k-1);
94 k == 0 ? (dim == 3 ? 1 : 0) : (k-2)*(k-1)*(2*k-3)/6;
124 GeometryType triangle;
125 triangle.makeTriangle();
128 Dune::GeometryType quadrilateral;
129 quadrilateral.makeQuadrilateral();
133 GeometryType tetrahedron;
134 tetrahedron.makeSimplex(3);
141 GeometryType hexahedron;
142 hexahedron.makeCube(3);
200 GeometryType triangle, quad;
201 triangle.makeTriangle();
202 quad.makeQuadrilateral();
211 GeometryType triangle, quad, tetrahedron, pyramid, prism, hexahedron;
212 triangle.makeTriangle();
213 quad.makeQuadrilateral();
214 tetrahedron.makeTetrahedron();
215 pyramid.makePyramid();
217 hexahedron.makeCube(3);
228 DUNE_THROW(Dune::NotImplemented,
"No size method for " << dim <<
"d grids available yet!");
234 assert(prefix.size() == 0 || prefix.size() == 1);
235 return (prefix.size() == 0) ?
size() : 0;
266 template<
typename GV,
int k,
typename TP>
270 static const int dim = GV::dimension;
274 using FiniteElementCache =
typename Dune::PQkLocalFiniteElementCache<typename GV::ctype, double, dim, k>;
280 using Element =
typename GV::template Codim<0>::Entity;
285 finiteElement_(nullptr),
301 return *finiteElement_;
308 finiteElement_ = &(cache_.get(element_->type()));
309 this->setSize(finiteElement_->size());
321 template<
typename GV,
int k,
class MI,
class TP>
324 enum {dim = GV::dimension};
338 nodeFactory_(&nodeFactory),
363 assert(node_ !=
nullptr);
364 return node_->finiteElement().size();
370 assert(node_ !=
nullptr);
371 Dune::LocalKey localKey = node_->finiteElement().localCoefficients().localKey(i);
372 const auto& gridIndexSet = nodeFactory_->gridView().indexSet();
373 const auto& element = node_->element();
376 auto dofDim = dim - localKey.codim();
379 return {{ (
size_type)(gridIndexSet.subIndex(element,localKey.subEntity(),dim)) }};
385 return {{ nodeFactory_->edgeOffset_
386 + nodeFactory_->dofsPerEdge * ((
size_type)gridIndexSet.subIndex(element,0,0))
387 + localKey.index() }};
390 const Dune::ReferenceElement<double,dim>& refElement
391 = Dune::ReferenceElements<double,dim>::general(element.type());
395 auto v0 = (
size_type)gridIndexSet.subIndex(element,refElement.subEntity(localKey.subEntity(),localKey.codim(),0,dim),dim);
396 auto v1 = (
size_type)gridIndexSet.subIndex(element,refElement.subEntity(localKey.subEntity(),localKey.codim(),1,dim),dim);
397 bool flip = (v0 > v1);
399 ? nodeFactory_->edgeOffset_
400 + nodeFactory_->dofsPerEdge*((
size_type)gridIndexSet.subIndex(element,localKey.subEntity(),localKey.codim()))
401 + (nodeFactory_->dofsPerEdge-1)-localKey.index()
402 : nodeFactory_->edgeOffset_
403 + nodeFactory_->dofsPerEdge*((
size_type)gridIndexSet.subIndex(element,localKey.subEntity(),localKey.codim()))
404 + localKey.index() }};
412 if (element.type().isTriangle())
414 const int interiorLagrangeNodesPerTriangle = (k-1)*(k-2)/2;
415 return {{ nodeFactory_->triangleOffset_ + interiorLagrangeNodesPerTriangle*((
size_type)gridIndexSet.subIndex(element,0,0)) + localKey.index() }};
417 else if (element.type().isQuadrilateral())
419 const int interiorLagrangeNodesPerQuadrilateral = (k-1)*(k-1);
420 return {{ nodeFactory_->quadrilateralOffset_ + interiorLagrangeNodesPerQuadrilateral*((
size_type)gridIndexSet.subIndex(element,0,0)) + localKey.index() }};
423 DUNE_THROW(Dune::NotImplemented,
"2d elements have to be triangles or quadrilaterals");
426 const Dune::ReferenceElement<double,dim>& refElement
427 = Dune::ReferenceElements<double,dim>::general(element.type());
430 DUNE_THROW(Dune::NotImplemented,
"PQkNodalBasis for 3D grids is only implemented if k<=3");
432 if (k==3 and !refElement.type(localKey.subEntity(), localKey.codim()).isTriangle())
433 DUNE_THROW(Dune::NotImplemented,
"PQkNodalBasis for 3D grids with k==3 is only implemented if the grid is a simplex grid");
435 return {{ nodeFactory_->triangleOffset_ + ((
size_type)gridIndexSet.subIndex(element,localKey.subEntity(),localKey.codim())) }};
443 if (element.type().isTetrahedron())
444 return {{ nodeFactory_->tetrahedronOffset_ + NodeFactory::dofsPerTetrahedron*((
size_type)gridIndexSet.subIndex(element,0,0)) + localKey.index() }};
445 else if (element.type().isHexahedron())
446 return {{ nodeFactory_->hexahedronOffset_ + NodeFactory::dofsPerHexahedron*((
size_type)gridIndexSet.subIndex(element,0,0)) + localKey.index() }};
447 else if (element.type().isPrism())
448 return {{ nodeFactory_->prismOffset_ + NodeFactory::dofsPerPrism*((
size_type)gridIndexSet.subIndex(element,0,0)) + localKey.index() }};
449 else if (element.type().isPyramid())
450 return {{ nodeFactory_->pyramidOffset_ + NodeFactory::dofsPerPyramid*((
size_type)gridIndexSet.subIndex(element,0,0)) + localKey.index() }};
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");
467 namespace BasisBuilder {
471 template<std::
size_t k>
474 static const std::size_t requiredMultiIndexSize=1;
476 template<
class MultiIndex,
class Gr
idView>
495 template<std::
size_t k>
524 template<
typename GV,
int k>
533 #endif // DUNE_FUNCTIONS_FUNCTIONSPACEBASES_PQKNODALBASIS_HH Definition: pqknodalbasis.hh:39
size_type prismOffset_
Definition: pqknodalbasis.hh:259
Imp::PQkNodeFactoryBuilder< k > pq()
Create a factory builder that can build a PQkNodeFactory.
Definition: pqknodalbasis.hh:496
Definition: pqknodalbasis.hh:472
std::size_t size_type
Definition: nodes.hh:127
size_type tetrahedronOffset_
Definition: pqknodalbasis.hh:257
const Element * element_
Definition: pqknodalbasis.hh:316
Global basis for given node factory.
Definition: defaultglobalbasis.hh:42
Definition: polynomial.hh:7
size_type edgeOffset_
Definition: pqknodalbasis.hh:254
PQkNodeFactory(const GridView &gv)
Constructor for a given grid view object.
Definition: pqknodalbasis.hh:113
void unbind()
Unbind the view.
Definition: pqknodalbasis.hh:354
typename GV::template Codim< 0 >::Entity Element
Definition: pqknodalbasis.hh:280
size_type pyramidOffset_
Definition: pqknodalbasis.hh:258
size_type size() const
Size of subtree rooted in this node (element-local)
Definition: pqknodalbasis.hh:361
const Element & element() const
Return current element, throw if unbound.
Definition: pqknodalbasis.hh:290
void bind(const Node &node)
Bind the view to a grid element.
Definition: pqknodalbasis.hh:347
FiniteElementCache cache_
Definition: pqknodalbasis.hh:314
size_type quadrilateralOffset_
Definition: pqknodalbasis.hh:256
const FiniteElement & finiteElement() const
Return the LocalFiniteElement for the element we are bound to.
Definition: pqknodalbasis.hh:299
Definition: pqknodalbasis.hh:36
const NodeFactory * nodeFactory_
Definition: pqknodalbasis.hh:460
size_type size() const
Same as size(prefix) with empty prefix.
Definition: pqknodalbasis.hh:191
typename NodeFactory::template Node< TP > Node
Definition: pqknodalbasis.hh:335
typename FiniteElementCache::FiniteElementType FiniteElement
Definition: pqknodalbasis.hh:281
size_type dimension() const
Get the total dimension of the space spanned by this basis.
Definition: pqknodalbasis.hh:239
std::size_t size_type
Type used for indices and size information.
Definition: pqknodalbasis.hh:71
Dune::ReservedVector< size_type, 1 > SizePrefix
Type used for prefixes handed to the size() method.
Definition: pqknodalbasis.hh:110
TP TreePath
Definition: nodes.hh:126
size_type hexahedronOffset_
Definition: pqknodalbasis.hh:260
const Node * node_
Definition: pqknodalbasis.hh:462
MultiIndex index(size_type i) const
Maps from subtree index set [0..size-1] to a globally unique multi index in global basis...
Definition: pqknodalbasis.hh:368
PQkNodeIndexSet(const NodeFactory &nodeFactory)
Definition: pqknodalbasis.hh:337
A factory for PQ-lagrange bases with given order.
Definition: pqknodalbasis.hh:42
IndexSet< TP > indexSet() const
Create tree node index set with given root tree path.
Definition: pqknodalbasis.hh:185
size_type vertexOffset_
Definition: pqknodalbasis.hh:253
const GridView & gridView() const
Obtain the grid view that the basis is defined on.
Definition: pqknodalbasis.hh:148
size_type maxNodeSize() const
Get the maximal number of DOFs associated to node for any element.
Definition: pqknodalbasis.hh:245
Node< TP > node(const TP &tp) const
Create tree node with given root tree path.
Definition: pqknodalbasis.hh:170
void update(const GridView &gv)
Update the stored grid view, to be called if the grid has changed.
Definition: pqknodalbasis.hh:154
size_type size(const SizePrefix prefix) const
Return number of possible values for next position in multi index.
Definition: pqknodalbasis.hh:232
Imp::PowerNodeFactoryBuilder< k, IndexMergingStrategy, SubFactoryTag > power(SubFactoryTag &&tag, const IndexMergingStrategy &ims)
Create a factory builder that can build a PowerNodeFactory.
Definition: powerbasis.hh:424
const FiniteElement * finiteElement_
Definition: pqknodalbasis.hh:315
MI MultiIndex
Type used for global numbering of the basis vectors.
Definition: pqknodalbasis.hh:331
PQkNode(const TreePath &treePath)
Definition: pqknodalbasis.hh:283
auto build(const GridView &gridView) -> PQkNodeFactory< GridView, k, MultiIndex >
Definition: pqknodalbasis.hh:477
PQMultiIndex MultiIndex
Type used for global numbering of the basis vectors.
Definition: pqknodalbasis.hh:107
size_type triangleOffset_
Definition: pqknodalbasis.hh:255
GridView gridView_
Definition: pqknodalbasis.hh:251
GV GridView
The grid view that the FE basis is defined on.
Definition: pqknodalbasis.hh:68
void bind(const Element &e)
Bind to element.
Definition: pqknodalbasis.hh:305
std::size_t size_type
Definition: pqknodalbasis.hh:328
void initializeIndices()
Initialize the global indices.
Definition: pqknodalbasis.hh:118