return unit_points;
}
+ const auto reference_cell = ReferenceCells::get_simplex<dim>();
// Piecewise constants are a special case: use a support point at the
// centroid and only the centroid
if (degree == 0)
{
- unit_points.emplace_back(
- ReferenceCells::get_simplex<dim>().template barycenter<dim>());
+ unit_points.emplace_back(reference_cell.template barycenter<dim>());
return unit_points;
}
- if (dim == 1)
- {
- // We don't really have dim = 1 support for simplex elements yet, but
- // its convenient for populating the face array
- Assert(degree <= 2, ExcNotImplemented());
- if (degree >= 1)
- {
- unit_points.emplace_back(0.0);
- unit_points.emplace_back(1.0);
+ Assert(degree <= 2, ExcNotImplemented());
+ for (const auto &vertex_no : reference_cell.vertex_indices())
+ unit_points.emplace_back(reference_cell.template vertex<dim>(vertex_no));
- if (degree == 2)
- unit_points.emplace_back(0.5);
- }
- }
- else if (dim == 2)
- {
- Assert(degree <= 2, ExcNotImplemented());
- if (degree >= 1)
- {
- unit_points.emplace_back(0.0, 0.0);
- unit_points.emplace_back(1.0, 0.0);
- unit_points.emplace_back(0.0, 1.0);
-
- if (degree == 2)
- {
- unit_points.emplace_back(0.5, 0.0);
- unit_points.emplace_back(0.5, 0.5);
- unit_points.emplace_back(0.0, 0.5);
- }
- }
- }
- else if (dim == 3)
- {
- Assert(degree <= 2, ExcNotImplemented());
- if (degree >= 1)
- {
- unit_points.emplace_back(0.0, 0.0, 0.0);
- unit_points.emplace_back(1.0, 0.0, 0.0);
- unit_points.emplace_back(0.0, 1.0, 0.0);
- unit_points.emplace_back(0.0, 0.0, 1.0);
-
- if (degree == 2)
- {
- unit_points.emplace_back(0.5, 0.0, 0.0);
- unit_points.emplace_back(0.5, 0.5, 0.0);
- unit_points.emplace_back(0.0, 0.5, 0.0);
- unit_points.emplace_back(0.0, 0.0, 0.5);
- unit_points.emplace_back(0.5, 0.0, 0.5);
- unit_points.emplace_back(0.0, 0.5, 0.5);
- }
- }
- }
- else
- {
- Assert(false, ExcNotImplemented());
- }
+ if (degree == 2)
+ for (const auto &line_no : reference_cell.line_indices())
+ {
+ const auto v0 = reference_cell.template vertex<dim>(
+ reference_cell.line_to_cell_vertices(line_no, 0));
+ const auto v1 = reference_cell.template vertex<dim>(
+ reference_cell.line_to_cell_vertices(line_no, 1));
+ unit_points.emplace_back((v0 + v1) / 2.0);
+ }
return unit_points;
}
FE_SimplexP<dim> fe_p(degree);
std::vector<Point<dim>> points = fe_p.get_unit_support_points();
- const Point<dim> centroid =
- fe_p.reference_cell().template barycenter<dim>();
+ const auto reference_cell = fe_p.reference_cell();
+ const Point<dim> centroid = reference_cell.template barycenter<dim>();
switch (dim)
{
{
if (degree == 2)
{
- const double q13 = 1.0 / 3.0;
- points.emplace_back(q13, q13, 0.0);
- points.emplace_back(q13, 0.0, q13);
- points.emplace_back(0.0, q13, q13);
- points.emplace_back(q13, q13, q13);
+ for (const auto &face_no : reference_cell.face_indices())
+ {
+ Point<dim> midpoint;
+ for (const auto face_vertex_no :
+ reference_cell.face_reference_cell(0).vertex_indices())
+ {
+ const auto vertex_no =
+ reference_cell.face_to_cell_vertices(
+ face_no,
+ face_vertex_no,
+ ReferenceCell::default_combined_face_orientation());
+
+ midpoint +=
+ reference_cell.template vertex<dim>(vertex_no);
+ }
+
+ midpoint /=
+ reference_cell.face_reference_cell(0).n_vertices();
+ points.push_back(midpoint);
+ }
+
points.push_back(centroid);
}
return points;
BarycentricPolynomials<dim>
get_basis(const unsigned int degree)
{
- const Point<dim> centroid =
- ReferenceCells::get_simplex<dim>().template barycenter<dim>();
+ const auto reference_cell = ReferenceCells::get_simplex<dim>();
+ const Point<dim> centroid = reference_cell.template barycenter<dim>();
auto M = [](const unsigned int d) {
return BarycentricPolynomial<dim, double>::monomial(d);
// in 2D and 3D we add a centroid bubble function
auto c_bubble = BarycentricPolynomial<dim>() + 1;
- for (unsigned int d = 0; d < dim + 1; ++d)
- c_bubble = c_bubble * M(d);
+ for (const auto &vertex : reference_cell.vertex_indices())
+ c_bubble = c_bubble * M(vertex);
c_bubble = c_bubble / c_bubble.value(centroid);
std::vector<BarycentricPolynomial<dim>> bubble_functions;
// need 'face bubble' functions in addition to the centroid.
// Furthermore we need to subtract them off from the other
// functions so that we end up with an interpolatory basis
- auto b0 = 27 * M(0) * M(1) * M(2);
- bubble_functions.push_back(b0 - b0.value(centroid) * c_bubble);
- auto b1 = 27 * M(0) * M(1) * M(3);
- bubble_functions.push_back(b1 - b1.value(centroid) * c_bubble);
- auto b2 = 27 * M(0) * M(2) * M(3);
- bubble_functions.push_back(b2 - b2.value(centroid) * c_bubble);
- auto b3 = 27 * M(1) * M(2) * M(3);
- bubble_functions.push_back(b3 - b3.value(centroid) * c_bubble);
+ for (const auto &face_no : reference_cell.face_indices())
+ {
+ std::vector<unsigned int> vertices;
+ for (const auto face_vertex_no :
+ reference_cell.face_reference_cell(0).vertex_indices())
+ vertices.push_back(reference_cell.face_to_cell_vertices(
+ face_no,
+ face_vertex_no,
+ ReferenceCell::default_combined_face_orientation()));
+
+ Assert(vertices.size() == 3, ExcInternalError());
+ auto b =
+ 27.0 * M(vertices[0]) * M(vertices[1]) * M(vertices[2]);
+ bubble_functions.push_back(b -
+ b.value(centroid) * c_bubble);
+ }
bubble_functions.push_back(c_bubble);
}