*/
virtual const FiniteElement<dim> & base_element (const unsigned int index) const = 0;
+ /**
+ * Check for non-zero values on a face.
+ *
+ * This function returns
+ * @p{true}, if the shape
+ * function @p{shape_index} has
+ * non-zero values on the face
+ * @p{face_index}.
+ */
+ virtual bool has_support_on_face (const unsigned int shape_index,
+ const unsigned int face_index) const = 0;
+
/**
* Determine an estimate for the
* memory consumption (in bytes)
*/
virtual const FiniteElement<dim> & base_element (const unsigned int index) const;
+ /**
+ * Check for non-zero values on a face.
+ *
+ * This function returns
+ * @p{true}, if the shape
+ * function @p{shape_index} has
+ * non-zero values on the face
+ * @p{face_index}.
+ *
+ * Implementation of the
+ * interface in
+ * @ref{FiniteElement}
+ */
+ virtual bool has_support_on_face (const unsigned int shape_index,
+ const unsigned int face_index) const;
+
/**
* Determine an estimate for the
* memory consumption (in bytes)
*/
virtual const FiniteElement<dim> & base_element (const unsigned int index) const;
+ /**
+ * Check for non-zero values on a face.
+ *
+ * This function returns
+ * @p{true}, if the shape
+ * function @p{shape_index} has
+ * non-zero values on the face
+ * @p{face_index}.
+ *
+ * Implementation of the
+ * interface in
+ * @ref{FiniteElement}
+ */
+ virtual bool has_support_on_face (const unsigned int shape_index,
+ const unsigned int face_index) const;
+
/**
* Determine an estimate for the
* memory consumption (in bytes)
*/
virtual const FiniteElement<dim> & base_element (const unsigned int index) const;
+ /**
+ * Check for non-zero values on a face.
+ *
+ * This function returns
+ * @p{true}, if the shape
+ * function @p{shape_index} has
+ * non-zero values on the face
+ * @p{face_index}.
+ *
+ * Implementation of the
+ * interface in
+ * @ref{FiniteElement}
+ */
+ virtual bool has_support_on_face (const unsigned int shape_index,
+ const unsigned int face_index) const;
+
/**
* Determine an estimate for the
* memory consumption (in bytes)
+template <int dim>
+bool
+FE_DGQ<dim>::has_support_on_face (unsigned int shape_index,
+ const unsigned int face_index) const
+{
+ if (dim==1)
+ return true;
+ const unsigned int cell_start = (dim==2)
+ ? first_quad_index
+ : first_hex_index;
+ const unsigned int face_start = (dim==2)
+ ? first_line_index
+ : first_quad_index;
+
+ // Interior degrees of
+ // freedom correspond to
+ // shape functions with
+ // support inside the cell.
+ if (shape_index >= cell_start)
+ return false;
+ // Shape functions are sorted
+ // by face. If we dived by
+ // the number of shapes per
+ // face, the result must be
+ // equal to the face index.
+ if (shape_index >= face_start)
+ {
+ shape_index -= first_line_index;
+ shape_index /= dofs_per_face;
+ return (shape_index == face_index);
+ }
+ // Only degrees of freedom on
+ // a vertex are left.
+ shape_index /= dofs_per_vertex;
+ // Use a table to figure out
+ // which face is neighbor to
+ // which vertex.
+ switch (100*dim+10*face_index+shape_index)
+ {
+ case 200:
+ case 230:
+ case 201:
+ case 211:
+ case 212:
+ case 222:
+ case 223:
+ case 233:
+ case 300:
+ case 320:
+ case 350:
+ case 301:
+ case 321:
+ case 331:
+ case 302:
+ case 332:
+ case 342:
+ case 303:
+ case 343:
+ case 353:
+ case 314:
+ case 324:
+ case 354:
+ case 315:
+ case 325:
+ case 335:
+ case 316:
+ case 336:
+ case 346:
+ case 317:
+ case 347:
+ case 357:
+ return true;
+ default:
+ return false;
+ }
+ return true;
+}
+
+
+
template <int dim>
unsigned int
FE_DGQ<dim>::memory_consumption () const
+template <int dim>
+bool
+FE_Q<dim>::has_support_on_face (unsigned int shape_index,
+ const unsigned int face_index) const
+{
+ if (dim==1)
+ return true;
+ const unsigned int cell_start = (dim==2)
+ ? first_quad_index
+ : first_hex_index;
+ const unsigned int face_start = (dim==2)
+ ? first_line_index
+ : first_quad_index;
+
+ // Interior degrees of
+ // freedom correspond to
+ // shape functions with
+ // support inside the cell.
+ if (shape_index >= cell_start)
+ return false;
+ // Shape functions are sorted
+ // by face. If we dived by
+ // the number of shapes per
+ // face, the result must be
+ // equal to the face index.
+ if (shape_index >= face_start)
+ {
+ shape_index -= first_line_index;
+ shape_index /= dofs_per_face;
+ return (shape_index == face_index);
+ }
+ // Only degrees of freedom on
+ // a vertex are left.
+ shape_index /= dofs_per_vertex;
+ // Use a table to figure out
+ // which face is neighbor to
+ // which vertex.
+ switch (100*dim+10*face_index+shape_index)
+ {
+ case 200:
+ case 230:
+ case 201:
+ case 211:
+ case 212:
+ case 222:
+ case 223:
+ case 233:
+ case 300:
+ case 320:
+ case 350:
+ case 301:
+ case 321:
+ case 331:
+ case 302:
+ case 332:
+ case 342:
+ case 303:
+ case 343:
+ case 353:
+ case 314:
+ case 324:
+ case 354:
+ case 315:
+ case 325:
+ case 335:
+ case 316:
+ case 336:
+ case 346:
+ case 317:
+ case 347:
+ case 357:
+ return true;
+ default:
+ return false;
+ }
+ return true;
+}
+
+
+
template <int dim>
unsigned int
FE_Q<dim>::memory_consumption () const
};
+template <int dim>
+bool
+FESystem<dim>::has_support_on_face (const unsigned int shape_index,
+ const unsigned int face_index) const
+{
+ const pair<unsigned int, unsigned int> component
+ = system_to_component_index(shape_index);
+ const unsigned int base = component_to_base(component.first);
+ return base_element(base).has_support_on_face(component.second,
+ face_index);
+}
+
+
+
template <int dim>
unsigned int