MatrixFree<dim, Number, VectorizedArrayType>::is_supported(
const FiniteElement<dim, spacedim> &fe)
{
- if (dim != spacedim)
- return false;
-
- // first check for degree, number of base_elemnt and number of its components
- if (fe.degree == 0 || fe.n_base_elements() != 1)
- return false;
-
- const FiniteElement<dim, spacedim> *fe_ptr = &(fe.base_element(0));
- if (fe_ptr->n_components() != 1)
- return false;
-
- // then check of the base element is supported
- if (dynamic_cast<const FE_Poly<dim, spacedim> *>(fe_ptr) != nullptr)
- {
- const FE_Poly<dim, spacedim> *fe_poly_ptr =
- dynamic_cast<const FE_Poly<dim, spacedim> *>(fe_ptr);
- if (dynamic_cast<const TensorProductPolynomials<dim> *>(
- &fe_poly_ptr->get_poly_space()) != nullptr)
- return true;
- if (dynamic_cast<const TensorProductPolynomials<
- dim,
- Polynomials::PiecewisePolynomial<double>> *>(
- &fe_poly_ptr->get_poly_space()) != nullptr)
- return true;
- }
- if (dynamic_cast<const FE_DGP<dim, spacedim> *>(fe_ptr) != nullptr)
- return true;
- if (dynamic_cast<const FE_Q_DG0<dim, spacedim> *>(fe_ptr) != nullptr)
- return true;
-
- // if the base element is not in the above list it is not supported
- return false;
+ return internal::MatrixFreeFunctions::ShapeInfo<double>::is_supported(fe);
}
const FiniteElement<dim> &fe_dim,
const unsigned int base_element = 0);
+ /**
+ * Return which kinds of elements are supported by MatrixFree.
+ */
+ template <int dim, int spacedim>
+ static bool
+ is_supported(const FiniteElement<dim, spacedim> &fe);
+
/**
* Return data of univariate shape functions which defines the
* dimension @p dimension of tensor product shape functions
return a;
}
+
+
template <typename Number, std::size_t width>
Number
get_first_array_element(const VectorizedArray<Number, width> a)
return a[0];
}
+
+
template <typename Number>
ShapeInfo<Number>::ShapeInfo()
: element_type(tensor_general)
+ template <typename Number>
+ template <int dim, int spacedim>
+ bool
+ ShapeInfo<Number>::is_supported(const FiniteElement<dim, spacedim> &fe)
+ {
+ if (dim != spacedim)
+ return false;
+
+ for (unsigned int base = 0; base < fe.n_base_elements(); ++base)
+ {
+ const FiniteElement<dim, spacedim> *fe_ptr = &(fe.base_element(base));
+ if (fe_ptr->n_components() != 1)
+ return false;
+
+ // then check if the base element is supported or not
+ if (dynamic_cast<const FE_Poly<dim, spacedim> *>(fe_ptr) != nullptr)
+ {
+ const FE_Poly<dim, spacedim> *fe_poly_ptr =
+ dynamic_cast<const FE_Poly<dim, spacedim> *>(fe_ptr);
+ if (dynamic_cast<const TensorProductPolynomials<dim> *>(
+ &fe_poly_ptr->get_poly_space()) == nullptr &&
+ dynamic_cast<const TensorProductPolynomials<
+ dim,
+ Polynomials::PiecewisePolynomial<double>> *>(
+ &fe_poly_ptr->get_poly_space()) == nullptr &&
+ dynamic_cast<const FE_DGP<dim, spacedim> *>(fe_ptr) ==
+ nullptr &&
+ dynamic_cast<const FE_Q_DG0<dim, spacedim> *>(fe_ptr) ==
+ nullptr)
+ return false;
+ }
+ else
+ return false;
+ }
+
+ // if we arrived here, all base elements were supported so we can
+ // support the present element
+ return true;
+ }
+
+
+
template <typename Number>
template <int dim>
void
// If we can, use the matrix-free implementation
bool use_matrix_free =
MatrixFree<dim, typename VectorType::value_type>::is_supported(
- dof.get_fe());
+ dof.get_fe()) &&
+ dof.get_fe().n_base_elements() == 1;
// enforce_zero_boundary and project_to_boundary_first
// are not yet supported.
const unsigned int);
}
+for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension : SPACE_DIMENSIONS)
+ {
+#if deal_II_dimension <= deal_II_space_dimension
+ template bool
+ internal::MatrixFreeFunctions::ShapeInfo<double>::is_supported(
+ const FiniteElement<deal_II_dimension, deal_II_space_dimension> &);
+#endif
+ }
+
for (deal_II_dimension : DIMENSIONS;