@@ -414,6 +414,11 @@ class FE : public FEGenericBase<typename FEOutputType<T>::type>
414414 * a finite element of type \p t and approximation order \p o.
415415 *
416416 * On a p-refined element, \p o should be the total order of the element.
417+ *
418+ * This method does not support all finite element types; e.g. for an
419+ * arbitrary polygon or polyhedron type the number of shape
420+ * functions may depend on an individual element and not just its
421+ * type.
417422 */
418423 static unsigned int n_shape_functions (const ElemType t,
419424 const Order o)
@@ -424,29 +429,72 @@ class FE : public FEGenericBase<typename FEOutputType<T>::type>
424429 * finite element.
425430 *
426431 * On a p-refined element, \p o should be the total order of the element.
432+ *
433+ * This method does not support all finite element types; e.g. for an
434+ * arbitrary polygon or polyhedron type the number of shape
435+ * functions may depend on an individual element and not just its
436+ * type.
427437 */
428438 static unsigned int n_dofs (const ElemType t,
429439 const Order o);
430440
441+ /* *
442+ * \returns The number of shape functions associated with this
443+ * finite element.
444+ *
445+ * On a p-refined element, \p o should be the total order of the element.
446+ *
447+ * \p e should only be a null pointer if using a FE family like
448+ * SCALAR that has degrees of freedom independent of any element.
449+ */
450+ static unsigned int n_dofs (const Elem * e,
451+ const Order o);
452+
431453 /* *
432454 * \returns The number of dofs at node \p n for a finite element
433455 * of type \p t and order \p o.
434456 *
435457 * On a p-refined element, \p o should be the total order of the element.
458+ *
459+ * This method does not support all finite element types; e.g. for an
460+ * arbitrary polygon or polyhedron type the meaning of a node index
461+ * \p n may depend on an individual element and not just its type.
436462 */
437463 static unsigned int n_dofs_at_node (const ElemType t,
438464 const Order o,
439465 const unsigned int n);
440466
467+ /* *
468+ * \returns The number of dofs at node \p n for a finite element
469+ * of type \p t and order \p o.
470+ *
471+ * On a p-refined element, \p o should be the total order of the element.
472+ */
473+ static unsigned int n_dofs_at_node (const Elem & e,
474+ const Order o,
475+ const unsigned int n);
476+
441477 /* *
442478 * \returns The number of dofs interior to the element,
443479 * not associated with any interior nodes.
444480 *
445481 * On a p-refined element, \p o should be the total order of the element.
482+ *
483+ * This method may not support all finite element types, e.g. higher
484+ * order polygons or polyhedra may differ from element to element.
446485 */
447486 static unsigned int n_dofs_per_elem (const ElemType t,
448487 const Order o);
449488
489+ /* *
490+ * \returns The number of dofs interior to the element,
491+ * not associated with any interior nodes.
492+ *
493+ * On a p-refined element, \p o should be the total order of the element.
494+ */
495+ static unsigned int n_dofs_per_elem (const Elem & e,
496+ const Order o);
497+
450498 /* *
451499 * \returns The continuity level of the finite element.
452500 */
@@ -1528,6 +1576,8 @@ void lagrange_nodal_soln(const Elem * elem,
15281576 */
15291577unsigned int monomial_n_dofs (const ElemType t, const Order o);
15301578
1579+ unsigned int monomial_n_dofs (const Elem * e, const Order o);
1580+
15311581/* *
15321582 * Helper functions for rational basis functions.
15331583 */
@@ -1582,6 +1632,73 @@ void rational_all_shape_derivs (const Elem & elem,
15821632
15831633} // namespace libMesh
15841634
1635+
1636+ // Full specialization of all n_dofs type functions, for every
1637+ // dimension, with both original ElemType and new Elem signatures
1638+ #define LIBMESH_DEFAULT_NDOFS (MyType ) \
1639+ template <> unsigned int FE<0 ,MyType>::n_dofs(const ElemType t, const Order o) { return MyType##_n_dofs (t, o); } \
1640+ template <> unsigned int FE<1 ,MyType>::n_dofs(const ElemType t, const Order o) { return MyType##_n_dofs (t, o); } \
1641+ template <> unsigned int FE<2 ,MyType>::n_dofs(const ElemType t, const Order o) { return MyType##_n_dofs (t, o); } \
1642+ template <> unsigned int FE<3 ,MyType>::n_dofs(const ElemType t, const Order o) { return MyType##_n_dofs (t, o); } \
1643+ \
1644+ template <> unsigned int FE<0 ,MyType>::n_dofs(const Elem * e, const Order o) { return MyType##_n_dofs (e, o); } \
1645+ template <> unsigned int FE<1 ,MyType>::n_dofs(const Elem * e, const Order o) { return MyType##_n_dofs (e, o); } \
1646+ template <> unsigned int FE<2 ,MyType>::n_dofs(const Elem * e, const Order o) { return MyType##_n_dofs (e, o); } \
1647+ template <> unsigned int FE<3 ,MyType>::n_dofs(const Elem * e, const Order o) { return MyType##_n_dofs (e, o); } \
1648+ \
1649+ template <> unsigned int FE<0 ,MyType>::n_dofs_at_node(const ElemType t, const Order o, const unsigned int n) { return MyType##_n_dofs_at_node (t, o, n); } \
1650+ template <> unsigned int FE<1 ,MyType>::n_dofs_at_node(const ElemType t, const Order o, const unsigned int n) { return MyType##_n_dofs_at_node (t, o, n); } \
1651+ template <> unsigned int FE<2 ,MyType>::n_dofs_at_node(const ElemType t, const Order o, const unsigned int n) { return MyType##_n_dofs_at_node (t, o, n); } \
1652+ template <> unsigned int FE<3 ,MyType>::n_dofs_at_node(const ElemType t, const Order o, const unsigned int n) { return MyType##_n_dofs_at_node (t, o, n); } \
1653+ \
1654+ template <> unsigned int FE<0 ,MyType>::n_dofs_at_node(const Elem & e, const Order o, const unsigned int n) { return MyType##_n_dofs_at_node (e, o, n); } \
1655+ template <> unsigned int FE<1 ,MyType>::n_dofs_at_node(const Elem & e, const Order o, const unsigned int n) { return MyType##_n_dofs_at_node (e, o, n); } \
1656+ template <> unsigned int FE<2 ,MyType>::n_dofs_at_node(const Elem & e, const Order o, const unsigned int n) { return MyType##_n_dofs_at_node (e, o, n); } \
1657+ template <> unsigned int FE<3 ,MyType>::n_dofs_at_node(const Elem & e, const Order o, const unsigned int n) { return MyType##_n_dofs_at_node (e, o, n); } \
1658+ \
1659+ template <> unsigned int FE<0 ,MyType>::n_dofs_per_elem(const ElemType t, const Order o) { return MyType##_n_dofs_per_elem (t, o); } \
1660+ template <> unsigned int FE<1 ,MyType>::n_dofs_per_elem(const ElemType t, const Order o) { return MyType##_n_dofs_per_elem (t, o); } \
1661+ template <> unsigned int FE<2 ,MyType>::n_dofs_per_elem(const ElemType t, const Order o) { return MyType##_n_dofs_per_elem (t, o); } \
1662+ template <> unsigned int FE<3 ,MyType>::n_dofs_per_elem(const ElemType t, const Order o) { return MyType##_n_dofs_per_elem (t, o); } \
1663+ \
1664+ template <> unsigned int FE<0 ,MyType>::n_dofs_per_elem(const Elem & e, const Order o) { return MyType##_n_dofs_per_elem (e, o); } \
1665+ template <> unsigned int FE<1 ,MyType>::n_dofs_per_elem(const Elem & e, const Order o) { return MyType##_n_dofs_per_elem (e, o); } \
1666+ template <> unsigned int FE<2 ,MyType>::n_dofs_per_elem(const Elem & e, const Order o) { return MyType##_n_dofs_per_elem (e, o); } \
1667+ template <> unsigned int FE<3 ,MyType>::n_dofs_per_elem(const Elem & e, const Order o) { return MyType##_n_dofs_per_elem (e, o); }
1668+
1669+
1670+ #define LIBMESH_DEFAULT_VEC_NDOFS (MyType ) \
1671+ template <> unsigned int FE<0 ,MyType##_VEC>::n_dofs(const ElemType t, const Order o) { return FE<0 ,MyType>::n_dofs (t, o); } \
1672+ template <> unsigned int FE<1 ,MyType##_VEC>::n_dofs(const ElemType t, const Order o) { return FE<1 ,MyType>::n_dofs (t, o); } \
1673+ template <> unsigned int FE<2 ,MyType##_VEC>::n_dofs(const ElemType t, const Order o) { return 2 *FE<2 ,MyType>::n_dofs (t, o); } \
1674+ template <> unsigned int FE<3 ,MyType##_VEC>::n_dofs(const ElemType t, const Order o) { return 3 *FE<3 ,MyType>::n_dofs (t, o); } \
1675+ \
1676+ template <> unsigned int FE<0 ,MyType##_VEC>::n_dofs(const Elem * e, const Order o) { return FE<0 ,MyType>::n_dofs (e, o); } \
1677+ template <> unsigned int FE<1 ,MyType##_VEC>::n_dofs(const Elem * e, const Order o) { return FE<1 ,MyType>::n_dofs (e, o); } \
1678+ template <> unsigned int FE<2 ,MyType##_VEC>::n_dofs(const Elem * e, const Order o) { return 2 *FE<2 ,MyType>::n_dofs (e, o); } \
1679+ template <> unsigned int FE<3 ,MyType##_VEC>::n_dofs(const Elem * e, const Order o) { return 3 *FE<3 ,MyType>::n_dofs (e, o); } \
1680+ \
1681+ template <> unsigned int FE<0 ,MyType##_VEC>::n_dofs_at_node(const ElemType t, const Order o, const unsigned int n) { return FE<0 ,MyType>::n_dofs_at_node (t, o, n); } \
1682+ template <> unsigned int FE<1 ,MyType##_VEC>::n_dofs_at_node(const ElemType t, const Order o, const unsigned int n) { return FE<1 ,MyType>::n_dofs_at_node (t, o, n); } \
1683+ template <> unsigned int FE<2 ,MyType##_VEC>::n_dofs_at_node(const ElemType t, const Order o, const unsigned int n) { return 2 *FE<2 ,MyType>::n_dofs_at_node (t, o, n); } \
1684+ template <> unsigned int FE<3 ,MyType##_VEC>::n_dofs_at_node(const ElemType t, const Order o, const unsigned int n) { return 3 *FE<3 ,MyType>::n_dofs_at_node (t, o, n); } \
1685+ \
1686+ template <> unsigned int FE<0 ,MyType##_VEC>::n_dofs_at_node(const Elem & e, const Order o, const unsigned int n) { return FE<0 ,MyType>::n_dofs_at_node (e.type (), o, n); } \
1687+ template <> unsigned int FE<1 ,MyType##_VEC>::n_dofs_at_node(const Elem & e, const Order o, const unsigned int n) { return FE<1 ,MyType>::n_dofs_at_node (e.type (), o, n); } \
1688+ template <> unsigned int FE<2 ,MyType##_VEC>::n_dofs_at_node(const Elem & e, const Order o, const unsigned int n) { return 2 *FE<2 ,MyType>::n_dofs_at_node (e.type (), o, n); } \
1689+ template <> unsigned int FE<3 ,MyType##_VEC>::n_dofs_at_node(const Elem & e, const Order o, const unsigned int n) { return 3 *FE<3 ,MyType>::n_dofs_at_node (e.type (), o, n); } \
1690+ \
1691+ template <> unsigned int FE<0 ,MyType##_VEC>::n_dofs_per_elem(const ElemType t, const Order o) { return FE<0 ,MyType>::n_dofs_per_elem (t, o); } \
1692+ template <> unsigned int FE<1 ,MyType##_VEC>::n_dofs_per_elem(const ElemType t, const Order o) { return FE<1 ,MyType>::n_dofs_per_elem (t, o); } \
1693+ template <> unsigned int FE<2 ,MyType##_VEC>::n_dofs_per_elem(const ElemType t, const Order o) { return 2 *FE<2 ,MyType>::n_dofs_per_elem (t, o); } \
1694+ template <> unsigned int FE<3 ,MyType##_VEC>::n_dofs_per_elem(const ElemType t, const Order o) { return 3 *FE<3 ,MyType>::n_dofs_per_elem (t, o); } \
1695+ \
1696+ template <> unsigned int FE<0 ,MyType##_VEC>::n_dofs_per_elem(const Elem & e, const Order o) { return FE<0 ,MyType>::n_dofs_per_elem (e.type (), o); } \
1697+ template <> unsigned int FE<1 ,MyType##_VEC>::n_dofs_per_elem(const Elem & e, const Order o) { return FE<1 ,MyType>::n_dofs_per_elem (e.type (), o); } \
1698+ template <> unsigned int FE<2 ,MyType##_VEC>::n_dofs_per_elem(const Elem & e, const Order o) { return 2 *FE<2 ,MyType>::n_dofs_per_elem (e.type (), o); } \
1699+ template <> unsigned int FE<3 ,MyType##_VEC>::n_dofs_per_elem(const Elem & e, const Order o) { return 3 *FE<3 ,MyType>::n_dofs_per_elem (e.type (), o); }
1700+
1701+
15851702#define LIBMESH_DEFAULT_VECTORIZED_FE (MyDim, MyType ) \
15861703template <> \
15871704void FE<MyDim,MyType>::all_shapes \
0 commit comments