+ /**
+ * This struct implements the action of the inverse mass matrix operation
+ */
template <int dim, int fe_degree, int n_components, typename Number>
struct CellwiseInverseMassMatrixImpl
{
Number * out = out_array + d * dofs_per_component;
// Need to select 'apply' method with hessian slot because values
// assume symmetries that do not exist in the inverse shapes
- evaluator.template hessians<0, false, false>(in, out);
+ evaluator.template hessians<0, true, false>(in, out);
if (dim > 1)
{
- evaluator.template hessians<1, false, false>(out, out);
+ evaluator.template hessians<1, true, false>(out, out);
if (dim == 3)
{
- evaluator.template hessians<2, false, false>(out, out);
+ evaluator.template hessians<2, true, false>(out, out);
for (unsigned int q = 0; q < dofs_per_component; ++q)
out[q] *= inv_coefficient[q];
- evaluator.template hessians<2, true, false>(out, out);
+ evaluator.template hessians<2, false, false>(out, out);
}
else if (dim == 2)
for (unsigned int q = 0; q < dofs_per_component; ++q)
out[q] *= inv_coefficient[q];
- evaluator.template hessians<1, true, false>(out, out);
+ evaluator.template hessians<1, false, false>(out, out);
}
else
{
for (unsigned int q = 0; q < dofs_per_component; ++q)
out[q] *= inv_coefficient[q];
}
- evaluator.template hessians<0, true, false>(out, out);
+ evaluator.template hessians<0, false, false>(out, out);
inv_coefficient += shift_coefficient;
}
if (dim == 3)
{
- evaluator.template hessians<2, true, false>(in, out);
- evaluator.template hessians<1, true, false>(out, out);
- evaluator.template hessians<0, true, false>(out, out);
+ evaluator.template hessians<2, false, false>(in, out);
+ evaluator.template hessians<1, false, false>(out, out);
+ evaluator.template hessians<0, false, false>(out, out);
}
if (dim == 2)
{
- evaluator.template hessians<1, true, false>(in, out);
- evaluator.template hessians<0, true, false>(out, out);
+ evaluator.template hessians<1, false, false>(in, out);
+ evaluator.template hessians<0, false, false>(out, out);
}
if (dim == 1)
- evaluator.template hessians<0, true, false>(in, out);
+ evaluator.template hessians<0, false, false>(in, out);
}
}
};
Number,
false,
VectorizedArrayType> &fe_eval;
-
- /**
- * A structure to hold inverse shape functions
- */
- AlignedVector<VectorizedArrayType> inverse_shape;
};
false,
VectorizedArrayType> &fe_eval)
: fe_eval(fe_eval)
- {
- FullMatrix<double> shapes_1d(fe_degree + 1, fe_degree + 1);
- for (unsigned int i = 0, c = 0; i < shapes_1d.m(); ++i)
- for (unsigned int j = 0; j < shapes_1d.n(); ++j, ++c)
- shapes_1d(i, j) = fe_eval.get_shape_info().shape_values[c][0];
- shapes_1d.gauss_jordan();
- const unsigned int stride = (fe_degree + 2) / 2;
- inverse_shape.resize(stride * (fe_degree + 1));
- for (unsigned int i = 0; i < stride; ++i)
- for (unsigned int q = 0; q < (fe_degree + 2) / 2; ++q)
- {
- inverse_shape[i * stride + q] =
- 0.5 * (shapes_1d(i, q) + shapes_1d(i, fe_degree - q));
- inverse_shape[(fe_degree - i) * stride + q] =
- 0.5 * (shapes_1d(i, q) - shapes_1d(i, fe_degree - q));
- }
- if (fe_degree % 2 == 0)
- for (unsigned int q = 0; q < (fe_degree + 2) / 2; ++q)
- inverse_shape[fe_degree / 2 * stride + q] = shapes_1d(fe_degree / 2, q);
- }
+ {}
const VectorizedArrayType * in_array,
VectorizedArrayType * out_array) const
{
- internal::CellwiseInverseMassMatrixImpl<
- dim,
- fe_degree,
- n_components,
- VectorizedArrayType>::apply(inverse_shape,
- inverse_coefficients,
- n_actual_components,
- in_array,
- out_array);
+ internal::CellwiseInverseMassMatrixImpl<dim,
+ fe_degree,
+ n_components,
+ VectorizedArrayType>::
+ apply(fe_eval.get_shape_info().inverse_shape_values_eo,
+ inverse_coefficients,
+ n_actual_components,
+ in_array,
+ out_array);
}
fe_degree,
n_components,
VectorizedArrayType>::
- transform_from_q_points_to_basis(inverse_shape,
- n_actual_components,
- in_array,
- out_array);
+ transform_from_q_points_to_basis(
+ fe_eval.get_shape_info().inverse_shape_values_eo,
+ n_actual_components,
+ in_array,
+ out_array);
}