@@ -197,23 +197,30 @@ class FEType
197197{
198198public:
199199
200+ /* *
201+ * The approximation order of the element (at 0 p-refinement level).
202+ */
203+ OrderWrapper order;
204+
200205#ifndef LIBMESH_ENABLE_INFINITE_ELEMENTS
201206
202207 /* *
203- * Constructor. Optionally takes the approximation \p Order
204- * and the finite element family \p FEFamily
208+ * Constructor. Optionally takes the approximation \p Order,
209+ * the finite element family \p FEFamily.
210+ *
211+ * We can't set p_refinement in this argument list without
212+ * conflicting with the \p ro parameter in the InfFE-compatible
213+ * constructor version below, so we use the set_p_refinement API
214+ * below to potentially convert an FEType with p-refinement (the
215+ * default) to one without.
205216 */
206217 FEType (const int o = 1 ,
207218 const FEFamily f = LAGRANGE) :
208219 order(o),
209- family(f)
220+ family(f),
221+ p_refinement(true )
210222 {}
211223
212- /* *
213- * The approximation order of the element.
214- */
215- OrderWrapper order;
216-
217224 /* *
218225 * The type of finite element. Valid types are \p LAGRANGE,
219226 * \p HIERARCHIC, etc...
@@ -230,24 +237,26 @@ class FEType
230237 * are the same, as with the \p family and \p base_family. It must
231238 * be so, otherwise what we switch on would change when infinite
232239 * elements are not compiled in.
240+ *
241+ * We can't set p_refinement in this argument list in a way
242+ * that matches the non-InfFE-enabled constructor version above, so
243+ * we use the set_p_refinement API below to potentially convert an
244+ * FEType with p-refinement (the default) to one without.
233245 */
234246 FEType (const int o = 1 ,
235247 const FEFamily f = LAGRANGE,
236248 const int ro = THIRD,
237249 const FEFamily rf = JACOBI_20_00,
238- const InfMapType im = CARTESIAN) :
250+ const InfMapType im = CARTESIAN
251+ ) :
239252 order(o),
240253 radial_order(ro),
241254 family(f),
242255 radial_family(rf),
243- inf_map(im)
256+ inf_map(im),
257+ p_refinement(true )
244258 {}
245259
246- /* *
247- * The approximation order in the base of the infinite element.
248- */
249- OrderWrapper order;
250-
251260 /* *
252261 * The approximation order in radial direction of the infinite element.
253262 */
@@ -276,13 +285,40 @@ class FEType
276285
277286#endif // ifndef LIBMESH_ENABLE_INFINITE_ELEMENTS
278287
288+ /* *
289+ * Whether or not the finite elements for this type increase their p
290+ * refinement level on geometric elements of increased p level.
291+ */
292+ bool p_refinement;
293+
294+ /* *
295+ * "Fluent API" for constructing a non-default p_refinement, for
296+ * easier compatibility between non-InfFE and InfFE code
297+ */
298+ FEType set_p_refinement (bool p) &
299+ {
300+ this ->p_refinement = p;
301+ return *this ;
302+ }
303+
304+ /* *
305+ * Specialization for rvalues so we don't return a dangling
306+ * reference to a temporary.
307+ */
308+ FEType set_p_refinement (bool p) &&
309+ {
310+ this ->p_refinement = p;
311+ return std::move (*this );
312+ }
313+
279314 /* *
280315 * Tests equality
281316 */
282317 bool operator == (const FEType & f2) const
283318 {
284319 return (order == f2.order
285320 && family == f2.family
321+ && p_refinement == f2.p_refinement
286322#ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
287323 && radial_order == f2.radial_order
288324 && radial_family == f2.radial_family
@@ -308,7 +344,8 @@ class FEType
308344 return (order < f2.order );
309345 if (family != f2.family )
310346 return (family < f2.family );
311-
347+ if (p_refinement != f2.p_refinement )
348+ return (p_refinement < f2.p_refinement );
312349#ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
313350 if (radial_order != f2.radial_order )
314351 return (radial_order < f2.radial_order );
@@ -321,16 +358,19 @@ class FEType
321358 }
322359
323360 /* *
324- * \returns The default quadrature order for this \p FEType. The
325- * default quadrature order is calculated assuming a polynomial of
326- * degree \p order and is based on integrating the mass matrix for
327- * such an element exactly on affine elements.
361+ * \returns The default quadrature order for this \p FEType, on an
362+ * element without p refinement. The default quadrature order is
363+ * calculated assuming a polynomial of degree \p order and is based
364+ * on integrating the mass matrix for such an element exactly on
365+ * affine elements.
328366 */
329367 Order default_quadrature_order () const ;
330368
331369 /* *
332370 * \returns A quadrature rule of appropriate type and order for this \p
333- * FEType. The default quadrature rule is based on integrating the mass
371+ * FEType, on an element without p refinement.
372+ *
373+ * The default quadrature rule is based on integrating the mass
334374 * matrix for such an element exactly, with an additional power on
335375 * the basis order to help account for nonlinearities and/or
336376 * nonuniform coefficients. Higher or lower degree rules can be
@@ -341,7 +381,9 @@ class FEType
341381
342382 /* *
343383 * \returns The default quadrature order for integrating unweighted
344- * basis functions of this \p FEType.
384+ * basis functions of this \p FEType, on an element without p
385+ * refinement.
386+ *
345387 * The unweighted quadrature order is calculated assuming a
346388 * polynomial of degree \p order and is based on integrating the
347389 * shape functions for such an element exactly on affine elements.
@@ -350,10 +392,12 @@ class FEType
350392
351393 /* *
352394 * \returns A quadrature rule of appropriate type and order for
353- * unweighted integration of this \p FEType. The default quadrature
354- * rule is based on integrating the shape functions on an affine
355- * element exactly. Higher or lower degree rules can be chosen by
356- * changing the extraorder parameter.
395+ * unweighted integration of this \p FEType, on an element without p
396+ * refinement
397+ *
398+ * The default quadrature rule is based on integrating the shape
399+ * functions on an affine element exactly. Higher or lower degree
400+ * rules can be chosen by changing the extraorder parameter.
357401 */
358402 std::unique_ptr<QBase> unweighted_quadrature_rule (const unsigned int dim,
359403 const int extraorder=0 ) const ;
@@ -392,7 +436,13 @@ struct hash<libMesh::FEType>
392436 // Old compiler versions seem to need the static_cast
393437 libMesh::boostcopy::hash_combine (seed, static_cast <int >(fe_type.family ));
394438 libMesh::boostcopy::hash_combine (seed, fe_type.order ._order );
395- return seed;
439+ libMesh::boostcopy::hash_combine (seed, static_cast <int >(fe_type.p_refinement ));
440+ #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
441+ libMesh::boostcopy::hash_combine (seed, static_cast <int >(fe_type.radial_family ));
442+ libMesh::boostcopy::hash_combine (seed, fe_type.radial_order ._order );
443+ libMesh::boostcopy::hash_combine (seed, static_cast <int >(fe_type.inf_map ));
444+ #endif // ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
445+ return seed;
396446 }
397447};
398448}
0 commit comments