private:
template <int fe_degree, unsigned int side, bool transpose>
static void
- interpolate_2D(const unsigned int given_degree,
- bool is_subface_0,
- const unsigned int v,
- const Number * weight,
- Number * values)
- {
- if (is_subface_0)
- interpolate_2D<fe_degree, side, transpose, true>(given_degree,
- v,
- weight,
- values);
- else
- interpolate_2D<fe_degree, side, transpose, false>(given_degree,
- v,
- weight,
- values);
- }
-
- template <int fe_degree,
- unsigned int side,
- bool transpose,
- bool is_subface_0>
- static void
interpolate_2D(const unsigned int given_degree,
const unsigned int v,
const Number * weight,
{
typename Number::value_type sum = 0.0;
for (unsigned int h = 0; h < points; ++h)
- sum += weight[((transpose ? 1 : points) *
- (is_subface_0 ? k : (points - 1 - k))) +
- ((transpose ? points : 1) *
- (is_subface_0 ? h : (points - 1 - h)))][v] *
+ sum += weight[(transpose ? 1 : points) * k +
+ (transpose ? points : 1) * h][v] *
temp[h];
values[i * offset + stride + j][v] = sum;
}
template <int fe_degree,
unsigned int direction,
- unsigned int side,
+ unsigned int d,
bool transpose>
static void
- interpolate_3D_face(const unsigned int dof_offset,
- const unsigned int given_degree,
- bool is_subface_0,
- const unsigned int v,
- const Number * weight,
- Number * values)
- {
- if (is_subface_0)
- interpolate_3D_face<fe_degree, direction, side, transpose, true>(
- dof_offset, given_degree, v, weight, values);
- else
- interpolate_3D_face<fe_degree, direction, side, transpose, false>(
- dof_offset, given_degree, v, weight, values);
- }
-
- template <int fe_degree,
- unsigned int direction,
- unsigned int side,
- bool transpose,
- bool is_subface_0>
- static void
interpolate_3D_face(const unsigned int dof_offset,
const unsigned int given_degree,
const unsigned int v,
AssertIndexRange(points, 40);
const unsigned int stride = Utilities::pow(points, direction);
- const unsigned int d = side / 2;
// direction side0 side1 side2
// 0 - p^2 p
{
typename Number::value_type sum = 0.0;
for (unsigned int h = 0; h < points; ++h)
- sum += weight[((transpose ? 1 : points) *
- (is_subface_0 ? k : (points - 1 - k))) +
- ((transpose ? points : 1) *
- (is_subface_0 ? h : (points - 1 - h)))][v] *
+ sum += weight[(transpose ? 1 : points) * k +
+ (transpose ? points : 1) * h][v] *
temp[h];
values[dof_offset + k * stride + stride2 * g][v] = sum;
}
template <int fe_degree, unsigned int direction, bool transpose>
static void
- interpolate_3D_edge(const unsigned int p,
- const unsigned int given_degree,
- bool is_subface_0,
- const unsigned int v,
- const Number * weight,
- Number * values)
- {
- if (is_subface_0)
- interpolate_3D_edge<fe_degree, direction, transpose, true>(
- p, given_degree, v, weight, values);
- else
- interpolate_3D_edge<fe_degree, direction, transpose, false>(
- p, given_degree, v, weight, values);
- }
-
- template <int fe_degree,
- unsigned int direction,
- bool transpose,
- bool is_subface_0>
- static void
interpolate_3D_edge(const unsigned int p,
const unsigned int given_degree,
const unsigned int v,
{
typename Number::value_type sum = 0.0;
for (unsigned int h = 0; h < points; ++h)
- sum += weight[((transpose ? 1 : points) *
- (is_subface_0 ? k : (points - 1 - k))) +
- ((transpose ? points : 1) *
- (is_subface_0 ? h : (points - 1 - h)))][v] *
+ sum += weight[(transpose ? 1 : points) * k +
+ (transpose ? points : 1) * h][v] *
temp[h];
values[p + k * stride][v] = sum;
}
Number::size()> & constraint_mask,
Number * values)
{
- const Number *weights = fe_eval.get_shape_info()
- .data.front()
- .subface_interpolation_matrix.data();
-
const unsigned int given_degree =
fe_degree != -1 ? fe_degree :
fe_eval.get_shape_info().data.front().fe_degree;
+ const auto &interpolation_matrices =
+ fe_eval.get_shape_info().data.front().subface_interpolation_matrices;
+
const auto is_set = [](const auto a, const auto b) -> bool {
return (a & b) == b;
};
MatrixFreeFunctions::ConstraintKinds::unconstrained)
{
const bool is_subface_0 =
- (mask & MatrixFreeFunctions::ConstraintKinds::type_x) !=
+ (mask & MatrixFreeFunctions::ConstraintKinds::type_x) ==
MatrixFreeFunctions::ConstraintKinds::unconstrained;
+
+ const Number *weights =
+ interpolation_matrices[is_subface_0].data();
+
if (is_set(mask,
MatrixFreeFunctions::ConstraintKinds::type_y))
interpolate_2D<fe_degree, 2, transpose>(
given_degree,
- is_subface_0,
v,
weights,
values); // face 2
else
interpolate_2D<fe_degree, 3, transpose>(
given_degree,
- is_subface_0,
v,
weights,
values); // face 3
MatrixFreeFunctions::ConstraintKinds::unconstrained)
{
const bool is_subface_0 =
- (mask & MatrixFreeFunctions::ConstraintKinds::type_y) !=
+ (mask & MatrixFreeFunctions::ConstraintKinds::type_y) ==
MatrixFreeFunctions::ConstraintKinds::unconstrained;
+
+ const Number *weights =
+ interpolation_matrices[is_subface_0].data();
+
if (is_set(mask,
MatrixFreeFunctions::ConstraintKinds::type_x))
interpolate_2D<fe_degree, 0, transpose>(
given_degree,
- is_subface_0,
v,
weights,
values); // face 0
else
interpolate_2D<fe_degree, 1, transpose>(
given_degree,
- is_subface_0,
v,
weights,
values); // face 1
// direction 0:
{
const bool is_subface_0 =
- (mask & MatrixFreeFunctions::ConstraintKinds::type_x) !=
+ (mask & MatrixFreeFunctions::ConstraintKinds::type_x) ==
MatrixFreeFunctions::ConstraintKinds::unconstrained;
+ const Number *weights =
+ interpolation_matrices[is_subface_0].data();
+
// ... faces
if (is_face_2)
- interpolate_3D_face<fe_degree, 0, 2, transpose>(
+ interpolate_3D_face<fe_degree, 0, 1, transpose>(
p0,
given_degree,
- is_subface_0,
v,
weights,
values); // face 2
else if (is_face_3)
- interpolate_3D_face<fe_degree, 0, 3, transpose>(
+ interpolate_3D_face<fe_degree, 0, 1, transpose>(
p2,
given_degree,
- is_subface_0,
v,
weights,
values); // face 3
if (is_face_4)
- interpolate_3D_face<fe_degree, 0, 4, transpose>(
+ interpolate_3D_face<fe_degree, 0, 2, transpose>(
p0,
given_degree,
- is_subface_0,
v,
weights,
values); // face 4
else if (is_face_5)
- interpolate_3D_face<fe_degree, 0, 5, transpose>(
+ interpolate_3D_face<fe_degree, 0, 2, transpose>(
p4,
given_degree,
- is_subface_0,
v,
weights,
values); // face 5
interpolate_3D_edge<fe_degree, 0, transpose>(
p0,
given_degree,
- is_subface_0,
v,
weights,
values); // edge 2
interpolate_3D_edge<fe_degree, 0, transpose>(
p2,
given_degree,
- is_subface_0,
v,
weights,
values); // edge 3
interpolate_3D_edge<fe_degree, 0, transpose>(
p4,
given_degree,
- is_subface_0,
v,
weights,
values); // edge 6
interpolate_3D_edge<fe_degree, 0, transpose>(
p6,
given_degree,
- is_subface_0,
v,
weights,
values); // edge 7
// direction 1:
{
const bool is_subface_0 =
- (mask & MatrixFreeFunctions::ConstraintKinds::type_y) !=
+ (mask & MatrixFreeFunctions::ConstraintKinds::type_y) ==
MatrixFreeFunctions::ConstraintKinds::unconstrained;
+ const Number *weights =
+ interpolation_matrices[is_subface_0].data();
+
// ... faces
if (is_face_0)
interpolate_3D_face<fe_degree, 1, 0, transpose>(
p0,
given_degree,
- is_subface_0,
v,
weights,
values); // face 0
else if (is_face_1)
- interpolate_3D_face<fe_degree, 1, 1, transpose>(
+ interpolate_3D_face<fe_degree, 1, 0, transpose>(
p1,
given_degree,
- is_subface_0,
v,
weights,
values); // face 1
if (is_face_4)
- interpolate_3D_face<fe_degree, 1, 4, transpose>(
+ interpolate_3D_face<fe_degree, 1, 2, transpose>(
p0,
given_degree,
- is_subface_0,
v,
weights,
values); // face 4
else if (is_face_5)
- interpolate_3D_face<fe_degree, 1, 5, transpose>(
+ interpolate_3D_face<fe_degree, 1, 2, transpose>(
p4,
given_degree,
- is_subface_0,
v,
weights,
values); // face 5
interpolate_3D_edge<fe_degree, 1, transpose>(
p0,
given_degree,
- is_subface_0,
v,
weights,
values); // edge 0
interpolate_3D_edge<fe_degree, 1, transpose>(
p1,
given_degree,
- is_subface_0,
v,
weights,
values); // edge 1
interpolate_3D_edge<fe_degree, 1, transpose>(
p4,
given_degree,
- is_subface_0,
v,
weights,
values); // edge 4
interpolate_3D_edge<fe_degree, 1, transpose>(
p5,
given_degree,
- is_subface_0,
v,
weights,
values); // edge 5
// direction 2:
{
const bool is_subface_0 =
- (mask & MatrixFreeFunctions::ConstraintKinds::type_z) !=
+ (mask & MatrixFreeFunctions::ConstraintKinds::type_z) ==
MatrixFreeFunctions::ConstraintKinds::unconstrained;
+ const Number *weights =
+ interpolation_matrices[is_subface_0].data();
+
// ... faces
if (is_face_0)
interpolate_3D_face<fe_degree, 2, 0, transpose>(
p0,
given_degree,
- is_subface_0,
v,
weights,
values); // face 0
else if (is_face_1)
- interpolate_3D_face<fe_degree, 2, 1, transpose>(
+ interpolate_3D_face<fe_degree, 2, 0, transpose>(
p1,
given_degree,
- is_subface_0,
v,
weights,
values); // face 1
if (is_face_2)
- interpolate_3D_face<fe_degree, 2, 2, transpose>(
+ interpolate_3D_face<fe_degree, 2, 1, transpose>(
p0,
given_degree,
- is_subface_0,
v,
weights,
values); // face 2
else if (is_face_3)
- interpolate_3D_face<fe_degree, 2, 3, transpose>(
+ interpolate_3D_face<fe_degree, 2, 1, transpose>(
p2,
given_degree,
- is_subface_0,
v,
weights,
values); // face 3
interpolate_3D_edge<fe_degree, 2, transpose>(
p0,
given_degree,
- is_subface_0,
v,
weights,
values); // edge 8
interpolate_3D_edge<fe_degree, 2, transpose>(
p1,
given_degree,
- is_subface_0,
v,
weights,
values); // edge 9
interpolate_3D_edge<fe_degree, 2, transpose>(
p2,
given_degree,
- is_subface_0,
v,
weights,
values); // edge 10
interpolate_3D_edge<fe_degree, 2, transpose>(
p3,
given_degree,
- is_subface_0,
v,
weights,
values); // edge 11
if (dim > 1 && dynamic_cast<const FE_Q<dim> *>(&fe))
{
- auto &subface_interpolation_matrix =
- univariate_shape_data.subface_interpolation_matrix;
+ auto &subface_interpolation_matrix_0 =
+ univariate_shape_data.subface_interpolation_matrices[0];
+ auto &subface_interpolation_matrix_1 =
+ univariate_shape_data.subface_interpolation_matrices[1];
const auto fe_1d = create_fe<1>(fe);
const auto fe_2d = create_fe<2>(fe);
- FullMatrix<double> interpolation_matrix(fe_2d->n_dofs_per_face(0),
- fe_2d->n_dofs_per_face(0));
+ FullMatrix<double> interpolation_matrix_0(fe_2d->n_dofs_per_face(0),
+ fe_2d->n_dofs_per_face(0));
+ FullMatrix<double> interpolation_matrix_1(fe_2d->n_dofs_per_face(0),
+ fe_2d->n_dofs_per_face(0));
fe_2d->get_subface_interpolation_matrix(*fe_2d,
0,
- interpolation_matrix,
+ interpolation_matrix_0,
+ 0);
+
+ fe_2d->get_subface_interpolation_matrix(*fe_2d,
+ 1,
+ interpolation_matrix_1,
0);
ElementType element_type;
scalar_lexicographic,
lexicographic_numbering);
- subface_interpolation_matrix.resize(fe_1d->n_dofs_per_cell() *
- fe_1d->n_dofs_per_cell());
+ subface_interpolation_matrix_0.resize(fe_1d->n_dofs_per_cell() *
+ fe_1d->n_dofs_per_cell());
+ subface_interpolation_matrix_1.resize(fe_1d->n_dofs_per_cell() *
+ fe_1d->n_dofs_per_cell());
for (unsigned int i = 0, c = 0; i < fe_1d->n_dofs_per_cell(); ++i)
for (unsigned int j = 0; j < fe_1d->n_dofs_per_cell(); ++j, ++c)
- subface_interpolation_matrix[c] =
- interpolation_matrix(scalar_lexicographic[i],
- scalar_lexicographic[j]);
+ {
+ subface_interpolation_matrix_0[c] =
+ interpolation_matrix_0(scalar_lexicographic[i],
+ scalar_lexicographic[j]);
+ subface_interpolation_matrix_1[c] =
+ interpolation_matrix_1(scalar_lexicographic[i],
+ scalar_lexicographic[j]);
+ }
}
// get gradient and Hessian transformation matrix for the polynomial