]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Improve MatrixFree::is_supported() 11086/head
authorMartin Kronbichler <kronbichler@lnm.mw.tum.de>
Thu, 22 Oct 2020 16:31:13 +0000 (18:31 +0200)
committerMartin Kronbichler <kronbichler@lnm.mw.tum.de>
Thu, 22 Oct 2020 19:29:20 +0000 (21:29 +0200)
include/deal.II/matrix_free/matrix_free.templates.h
include/deal.II/matrix_free/shape_info.h
include/deal.II/matrix_free/shape_info.templates.h
include/deal.II/numerics/vector_tools_project.templates.h
source/matrix_free/shape_info.inst.in

index b6152e00769ea22d52d8d0850a807de727e57e09..64c08905f006f025495f8284e8fdfbd296c33eb4 100644 (file)
@@ -464,38 +464,7 @@ bool
 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);
 }
 
 
index 0637a5e775be7450e0cbf8f29123f763f860b757..64daf31106fba2ff3de9e477a0b20a3c35de0857 100644 (file)
@@ -331,6 +331,13 @@ namespace internal
              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
index 41a90beb54b82ac4313e396a691acea53ad88bd6..f41881d8692377b493cbd66ea6868d165d6aceab 100644 (file)
@@ -61,6 +61,8 @@ namespace internal
       return a;
     }
 
+
+
     template <typename Number, std::size_t width>
     Number
     get_first_array_element(const VectorizedArray<Number, width> a)
@@ -68,6 +70,8 @@ namespace internal
       return a[0];
     }
 
+
+
     template <typename Number>
     ShapeInfo<Number>::ShapeInfo()
       : element_type(tensor_general)
@@ -81,6 +85,48 @@ namespace internal
 
 
 
+    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
index 1988f3decd1d2ffc0b206e2b06a70722d3ebf64b..69083a0bdcab2e3319754d0fa9ac83d101355939 100644 (file)
@@ -706,7 +706,8 @@ namespace VectorTools
       // 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.
index f2c859da1d63a357c8b43b135c782c544f46a53f..293099d241c7573c6c7cf865325f78ac10c61bfa 100644 (file)
@@ -23,6 +23,15 @@ for (deal_II_dimension : DIMENSIONS; deal_II_scalar : REAL_SCALARS)
         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;

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.