]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Introduce FEEvaluationImplSelector
authorPeter Munch <peterrmuench@gmail.com>
Thu, 23 Mar 2023 18:34:19 +0000 (19:34 +0100)
committerPeter Munch <peterrmuench@gmail.com>
Thu, 23 Mar 2023 18:34:19 +0000 (19:34 +0100)
include/deal.II/matrix_free/evaluation_kernels.h

index f58e20fc108ae16752aa057b217b1455ce296d01..a2c6bb29b98a69ea021bff32a14f4a4f97c48a79 100644 (file)
@@ -2261,15 +2261,16 @@ namespace internal
    * currently supports $0\leq fe\_degree \leq 9$ and $degree+1\leq
    * n\_q\_points\_1d\leq fe\_degree+2$.
    */
-  template <int dim, typename Number>
-  struct FEEvaluationImplEvaluateSelector
+  template <int dim, typename Number, bool do_integrate>
+  struct FEEvaluationImplSelector
   {
-    template <int fe_degree, int n_q_points_1d>
+    template <int fe_degree, int n_q_points_1d, typename VNumber>
     static bool
     run(const unsigned int                     n_components,
         const EvaluationFlags::EvaluationFlags evaluation_flag,
-        const Number *                         values_dofs,
-        FEEvaluationData<dim, Number, false> & fe_eval)
+        VNumber *                              values_dofs,
+        FEEvaluationData<dim, Number, false> & fe_eval,
+        const bool                             sum_into_values_array = false)
     {
       const auto element_type = fe_eval.get_shape_info().element_type;
       using ElementType       = MatrixFreeFunctions::ElementType;
@@ -2283,8 +2284,13 @@ namespace internal
       if (fe_degree >= 0 && fe_degree + 1 == n_q_points_1d &&
           element_type == ElementType::tensor_symmetric_collocation)
         {
-          FEEvaluationImplCollocation<dim, fe_degree, Number>::evaluate(
-            n_components, evaluation_flag, values_dofs, fe_eval);
+          evaluate_or_integrate<
+            FEEvaluationImplCollocation<dim, fe_degree, Number>>(
+            n_components,
+            evaluation_flag,
+            values_dofs,
+            fe_eval,
+            sum_into_values_array);
         }
       // '<=' on type means tensor_symmetric or tensor_symmetric_hermite, see
       // shape_info.h for more details
@@ -2292,90 +2298,160 @@ namespace internal
                use_collocation_evaluation(fe_degree, n_q_points_1d) &&
                element_type <= ElementType::tensor_symmetric)
         {
-          FEEvaluationImplTransformToCollocation<
-            dim,
-            fe_degree,
-            n_q_points_1d,
-            Number>::evaluate(n_components,
-                              evaluation_flag,
-                              values_dofs,
-                              fe_eval);
+          evaluate_or_integrate<
+            FEEvaluationImplTransformToCollocation<dim,
+                                                   fe_degree,
+                                                   n_q_points_1d,
+                                                   Number>>(
+            n_components,
+            evaluation_flag,
+            values_dofs,
+            fe_eval,
+            sum_into_values_array);
         }
       else if (fe_degree >= 0 &&
                element_type <= ElementType::tensor_symmetric_no_collocation)
         {
-          FEEvaluationImpl<ElementType::tensor_symmetric,
-                           dim,
-                           fe_degree,
-                           n_q_points_1d,
-                           Number>::evaluate(n_components,
-                                             evaluation_flag,
-                                             values_dofs,
-                                             fe_eval);
+          evaluate_or_integrate<FEEvaluationImpl<ElementType::tensor_symmetric,
+                                                 dim,
+                                                 fe_degree,
+                                                 n_q_points_1d,
+                                                 Number>>(
+            n_components,
+            evaluation_flag,
+            values_dofs,
+            fe_eval,
+            sum_into_values_array);
         }
       else if (element_type == ElementType::tensor_symmetric_plus_dg0)
         {
-          FEEvaluationImpl<ElementType::tensor_symmetric_plus_dg0,
-                           dim,
-                           fe_degree,
-                           n_q_points_1d,
-                           Number>::evaluate(n_components,
-                                             evaluation_flag,
-                                             values_dofs,
-                                             fe_eval);
+          evaluate_or_integrate<
+            FEEvaluationImpl<ElementType::tensor_symmetric_plus_dg0,
+                             dim,
+                             fe_degree,
+                             n_q_points_1d,
+                             Number>>(n_components,
+                                      evaluation_flag,
+                                      values_dofs,
+                                      fe_eval,
+                                      sum_into_values_array);
         }
       else if (element_type == ElementType::truncated_tensor)
         {
-          FEEvaluationImpl<ElementType::truncated_tensor,
-                           dim,
-                           fe_degree,
-                           n_q_points_1d,
-                           Number>::evaluate(n_components,
-                                             evaluation_flag,
-                                             values_dofs,
-                                             fe_eval);
+          evaluate_or_integrate<FEEvaluationImpl<ElementType::truncated_tensor,
+                                                 dim,
+                                                 fe_degree,
+                                                 n_q_points_1d,
+                                                 Number>>(
+            n_components,
+            evaluation_flag,
+            values_dofs,
+            fe_eval,
+            sum_into_values_array);
         }
       else if (element_type == ElementType::tensor_none)
         {
-          FEEvaluationImpl<ElementType::tensor_none,
-                           dim,
-                           fe_degree,
-                           n_q_points_1d,
-                           Number>::evaluate(n_components,
-                                             evaluation_flag,
-                                             values_dofs,
-                                             fe_eval);
+          evaluate_or_integrate<FEEvaluationImpl<ElementType::tensor_none,
+                                                 dim,
+                                                 fe_degree,
+                                                 n_q_points_1d,
+                                                 Number>>(
+            n_components,
+            evaluation_flag,
+            values_dofs,
+            fe_eval,
+            sum_into_values_array);
         }
       else if (element_type == ElementType::tensor_raviart_thomas)
         {
-          FEEvaluationImpl<
-            ElementType::tensor_raviart_thomas,
-            dim,
-            (fe_degree == -1) ? 1 : fe_degree,
-            (n_q_points_1d < 1) ? 1 : n_q_points_1d,
-            Number>::template evaluate_or_integrate<false>(evaluation_flag,
-                                                           const_cast<Number *>(
-                                                             values_dofs),
-                                                           fe_eval);
+          FEEvaluationImpl<ElementType::tensor_raviart_thomas,
+                           dim,
+                           (fe_degree == -1) ? 1 : fe_degree,
+                           (n_q_points_1d < 1) ? 1 : n_q_points_1d,
+                           Number>::
+            template evaluate_or_integrate<do_integrate>(evaluation_flag,
+                                                         const_cast<Number *>(
+                                                           values_dofs),
+                                                         fe_eval,
+                                                         sum_into_values_array);
         }
       else
         {
-          FEEvaluationImpl<ElementType::tensor_general,
-                           dim,
-                           fe_degree,
-                           n_q_points_1d,
-                           Number>::evaluate(n_components,
-                                             evaluation_flag,
-                                             values_dofs,
-                                             fe_eval);
+          evaluate_or_integrate<FEEvaluationImpl<ElementType::tensor_general,
+                                                 dim,
+                                                 fe_degree,
+                                                 n_q_points_1d,
+                                                 Number>>(
+            n_components,
+            evaluation_flag,
+            values_dofs,
+            fe_eval,
+            sum_into_values_array);
         }
 
       return false;
     }
+
+  private:
+    template <typename T>
+    static void
+    evaluate_or_integrate(
+      const unsigned int                     n_components,
+      const EvaluationFlags::EvaluationFlags evaluation_flag,
+      const Number *                         values_dofs,
+      FEEvaluationData<dim, Number, false> & fe_eval,
+      const bool                             sum_into_values_array,
+      std::integral_constant<bool, false>)
+    {
+      (void)sum_into_values_array;
+
+      T::evaluate(n_components, evaluation_flag, values_dofs, fe_eval);
+    }
+
+    template <typename T>
+    static void
+    evaluate_or_integrate(
+      const unsigned int                     n_components,
+      const EvaluationFlags::EvaluationFlags evaluation_flag,
+      Number *                               values_dofs,
+      FEEvaluationData<dim, Number, false> & fe_eval,
+      const bool                             sum_into_values_array,
+      std::integral_constant<bool, true>)
+    {
+      T::integrate(n_components,
+                   evaluation_flag,
+                   values_dofs,
+                   fe_eval,
+                   sum_into_values_array);
+    }
+
+    template <typename T, typename VNumber>
+    static void
+    evaluate_or_integrate(
+      const unsigned int                     n_components,
+      const EvaluationFlags::EvaluationFlags evaluation_flag,
+      VNumber *                              values_dofs,
+      FEEvaluationData<dim, Number, false> & fe_eval,
+      const bool                             sum_into_values_array)
+    {
+      evaluate_or_integrate<T>(n_components,
+                               evaluation_flag,
+                               values_dofs,
+                               fe_eval,
+                               sum_into_values_array,
+                               std::integral_constant<bool, do_integrate>());
+    }
   };
 
 
 
+  template <int dim, typename Number>
+  struct FEEvaluationImplEvaluateSelector
+    : public FEEvaluationImplSelector<dim, Number, false>
+  {};
+
+
+
   /**
    * This class chooses an appropriate evaluation strategy based on the
    * template parameters and the shape_info variable which contains runtime
@@ -2393,128 +2469,8 @@ namespace internal
    */
   template <int dim, typename Number>
   struct FEEvaluationImplIntegrateSelector
-  {
-    template <int fe_degree, int n_q_points_1d>
-    static bool
-    run(const unsigned int                     n_components,
-        const EvaluationFlags::EvaluationFlags integration_flag,
-        Number *                               values_dofs,
-        FEEvaluationData<dim, Number, false> & fe_eval,
-        const bool                             sum_into_values_array)
-    {
-      const auto element_type = fe_eval.get_shape_info().element_type;
-      using ElementType       = MatrixFreeFunctions::ElementType;
-
-      Assert(fe_eval.get_shape_info().data.size() == 1 ||
-               (fe_eval.get_shape_info().data.size() == dim &&
-                element_type == ElementType::tensor_general) ||
-               element_type == ElementType::tensor_raviart_thomas,
-             ExcNotImplemented());
-
-      if (fe_degree >= 0 && fe_degree + 1 == n_q_points_1d &&
-          element_type == ElementType::tensor_symmetric_collocation)
-        {
-          FEEvaluationImplCollocation<dim, fe_degree, Number>::integrate(
-            n_components,
-            integration_flag,
-            values_dofs,
-            fe_eval,
-            sum_into_values_array);
-        }
-      // '<=' on type means tensor_symmetric or tensor_symmetric_hermite, see
-      // shape_info.h for more details
-      else if (fe_degree >= 0 &&
-               use_collocation_evaluation(fe_degree, n_q_points_1d) &&
-               element_type <= ElementType::tensor_symmetric)
-        {
-          FEEvaluationImplTransformToCollocation<
-            dim,
-            fe_degree,
-            n_q_points_1d,
-            Number>::integrate(n_components,
-                               integration_flag,
-                               values_dofs,
-                               fe_eval,
-                               sum_into_values_array);
-        }
-      else if (fe_degree >= 0 &&
-               element_type <= ElementType::tensor_symmetric_no_collocation)
-        {
-          FEEvaluationImpl<ElementType::tensor_symmetric,
-                           dim,
-                           fe_degree,
-                           n_q_points_1d,
-                           Number>::integrate(n_components,
-                                              integration_flag,
-                                              values_dofs,
-                                              fe_eval,
-                                              sum_into_values_array);
-        }
-      else if (element_type == ElementType::tensor_symmetric_plus_dg0)
-        {
-          FEEvaluationImpl<ElementType::tensor_symmetric_plus_dg0,
-                           dim,
-                           fe_degree,
-                           n_q_points_1d,
-                           Number>::integrate(n_components,
-                                              integration_flag,
-                                              values_dofs,
-                                              fe_eval,
-                                              sum_into_values_array);
-        }
-      else if (element_type == ElementType::truncated_tensor)
-        {
-          FEEvaluationImpl<ElementType::truncated_tensor,
-                           dim,
-                           fe_degree,
-                           n_q_points_1d,
-                           Number>::integrate(n_components,
-                                              integration_flag,
-                                              values_dofs,
-                                              fe_eval,
-                                              sum_into_values_array);
-        }
-      else if (element_type == ElementType::tensor_none)
-        {
-          FEEvaluationImpl<ElementType::tensor_none,
-                           dim,
-                           fe_degree,
-                           n_q_points_1d,
-                           Number>::integrate(n_components,
-                                              integration_flag,
-                                              values_dofs,
-                                              fe_eval,
-                                              sum_into_values_array);
-        }
-      else if (element_type == ElementType::tensor_raviart_thomas)
-        {
-          FEEvaluationImpl<ElementType::tensor_raviart_thomas,
-                           dim,
-                           (fe_degree == -1) ? 1 : fe_degree,
-                           (n_q_points_1d < 1) ? 1 : n_q_points_1d,
-                           Number>::
-            template evaluate_or_integrate<true>(integration_flag,
-                                                 const_cast<Number *>(
-                                                   values_dofs),
-                                                 fe_eval,
-                                                 sum_into_values_array);
-        }
-      else
-        {
-          FEEvaluationImpl<ElementType::tensor_general,
-                           dim,
-                           fe_degree,
-                           n_q_points_1d,
-                           Number>::integrate(n_components,
-                                              integration_flag,
-                                              values_dofs,
-                                              fe_eval,
-                                              sum_into_values_array);
-        }
-
-      return false;
-    }
-  };
+    : public FEEvaluationImplSelector<dim, Number, true>
+  {};
 
 
 

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.