]> https://gitweb.dealii.org/ - dealii.git/commitdiff
matrix-free: do not use bool args
authorTimo Heister <timo.heister@gmail.com>
Tue, 26 May 2020 16:12:43 +0000 (12:12 -0400)
committerTimo Heister <timo.heister@gmail.com>
Wed, 27 May 2020 16:55:12 +0000 (12:55 -0400)
- replace evaluate*, integrate* calls in FEEvaluation

examples/step-37/step-37.cc
include/deal.II/matrix_free/fe_evaluation.h

index e7ecb56badd77db992494f796ff8bfaf9e0c1260..3bbabfad0798c38c7fd8021da33f5d734ba23ec3 100644 (file)
@@ -403,10 +403,10 @@ namespace Step37
 
         phi.reinit(cell);
         phi.read_dof_values(src);
-        phi.evaluate(false, true);
+        phi.evaluate(EvaluationFlags::gradients);
         for (unsigned int q = 0; q < phi.n_q_points; ++q)
           phi.submit_gradient(coefficient(cell, q) * phi.get_gradient(q), q);
-        phi.integrate(false, true);
+        phi.integrate(EvaluationFlags::gradients);
         phi.distribute_local_to_global(dst);
       }
   }
index a3a2684c26500987e22b9c21fe8b30a5e63121ab..28f7561ba9b7485b45906e429f2d27d95b93c5cd 100644 (file)
@@ -57,6 +57,99 @@ template <int dim,
 class FEEvaluation;
 
 
+/**
+ * @brief The EvaluationFlags enum
+ */
+namespace EvaluationFlags
+{
+  /**
+   * @brief The type enum
+   */
+  enum EvaluationFlags
+  {
+    /**
+     *
+     */
+    nothing = 0,
+    /**
+     *
+     */
+    values = 0x1,
+    /**
+     *
+     */
+    gradients = 0x2,
+    /**
+     *
+     */
+    hessians = 0x4
+  };
+
+
+  /**
+   * Global operator which returns an object in which all bits are set which are
+   * either set in the first or the second argument. This operator exists since
+   * if it did not then the result of the bit-or <tt>operator |</tt> would be an
+   * integer which would in turn trigger a compiler warning when we tried to
+   * assign it to an object of type UpdateFlags.
+   *
+   * @ref type
+   */
+  inline EvaluationFlags
+  operator|(const EvaluationFlags f1, const EvaluationFlags f2)
+  {
+    return static_cast<EvaluationFlags>(static_cast<unsigned int>(f1) |
+                                        static_cast<unsigned int>(f2));
+  }
+
+
+
+  /**
+   * Global operator which sets the bits from the second argument also in the
+   * first one.
+   *
+   * @ref type
+   */
+  inline EvaluationFlags &
+  operator|=(EvaluationFlags &f1, const EvaluationFlags f2)
+  {
+    f1 = f1 | f2;
+    return f1;
+  }
+
+
+  /**
+   * Global operator which returns an object in which all bits are set which are
+   * set in the first as well as the second argument. This operator exists since
+   * if it did not then the result of the bit-and <tt>operator &</tt> would be
+   * an integer which would in turn trigger a compiler warning when we tried to
+   * assign it to an object of type UpdateFlags.
+   *
+   * @ref UpdateFlags
+   */
+  inline EvaluationFlags operator&(const EvaluationFlags f1,
+                                   const EvaluationFlags f2)
+  {
+    return static_cast<EvaluationFlags>(static_cast<unsigned int>(f1) &
+                                        static_cast<unsigned int>(f2));
+  }
+
+
+  /**
+   * Global operator which clears all the bits in the first argument if they are
+   * not also set in the second argument.
+   *
+   * @ref UpdateFlags
+   */
+  inline EvaluationFlags &
+  operator&=(EvaluationFlags &f1, const EvaluationFlags f2)
+  {
+    f1 = f1 & f2;
+    return f1;
+  }
+
+} // namespace EvaluationFlags
+
 /**
  * This is the base class for the FEEvaluation classes. This class is a base
  * class and needs usually not be called in user code. It does not have any
@@ -2509,6 +2602,14 @@ public:
    * manually).
    */
   void
+  evaluate(const EvaluationFlags::EvaluationFlags evaluation_flag);
+
+  /**
+   * Like above but with separate bool flags.
+   * @deprecated use evaluate() with the EvaluationFlags argument.
+   */
+  DEAL_II_DEPRECATED
+  void
   evaluate(const bool evaluate_values,
            const bool evaluate_gradients,
            const bool evaluate_hessians = false);
@@ -2526,6 +2627,15 @@ public:
    * useful information (unless these values have been set manually).
    */
   void
+  evaluate(const VectorizedArrayType *            values_array,
+           const EvaluationFlags::EvaluationFlags evaluation_flag);
+
+  /**
+   * Like above but using separate bool flags.
+   * @deprecated use evaluate() with the EvaluationFlags argument.
+   */
+  DEAL_II_DEPRECATED
+  void
   evaluate(const VectorizedArrayType *values_array,
            const bool                 evaluate_values,
            const bool                 evaluate_gradients,
@@ -2546,6 +2656,14 @@ public:
    */
   template <typename VectorType>
   void
+  gather_evaluate(const VectorType &                     input_vector,
+                  const EvaluationFlags::EvaluationFlags evaluation_flag);
+
+  /**
+   * @deprecated Please use the gather_evaluate() function with the EvaluationFlags argument.
+   */
+  template <typename VectorType>
+  DEAL_II_DEPRECATED void
   gather_evaluate(const VectorType &input_vector,
                   const bool        evaluate_values,
                   const bool        evaluate_gradients,
@@ -2562,6 +2680,13 @@ public:
    * distribute_local_to_global() or set_dof_values() methods).
    */
   void
+  integrate(const EvaluationFlags::EvaluationFlags integration_flag);
+
+
+  /**
+   * @deprecated Please use the integrate() function with the EvaluationFlags argument.
+   */
+  DEAL_II_DEPRECATED void
   integrate(const bool integrate_values, const bool integrate_gradients);
 
   /**
@@ -2576,6 +2701,14 @@ public:
    * internal data structures behind begin_dof_values().
    */
   void
+  integrate(const EvaluationFlags::EvaluationFlags integration_flag,
+            VectorizedArrayType *                  values_array);
+
+  /**
+   * @deprecated Please use the integrate() function with the EvaluationFlags argument.
+   */
+  DEAL_II_DEPRECATED
+  void
   integrate(const bool           integrate_values,
             const bool           integrate_gradients,
             VectorizedArrayType *values_array);
@@ -2595,6 +2728,14 @@ public:
    */
   template <typename VectorType>
   void
+  integrate_scatter(const EvaluationFlags::EvaluationFlags evaluation_flag,
+                    VectorType &                           output_vector);
+
+  /**
+   * @deprecated Please use the integrate_scatter() function with the EvaluationFlags argument.
+   */
+  template <typename VectorType>
+  DEAL_II_DEPRECATED void
   integrate_scatter(const bool  integrate_values,
                     const bool  integrate_gradients,
                     VectorType &output_vector);
@@ -2849,6 +2990,13 @@ public:
    * accessing the internal data pointers).
    */
   void
+  evaluate(const EvaluationFlags::EvaluationFlags evaluation_flag);
+
+  /**
+   * @deprecated Please use the evaluate() function with the EvaluationFlags argument.
+   */
+  DEAL_II_DEPRECATED
+  void
   evaluate(const bool evaluate_values, const bool evaluate_gradients);
 
   /**
@@ -2864,6 +3012,14 @@ public:
    * been set manually).
    */
   void
+  evaluate(const VectorizedArrayType *            values_array,
+           const EvaluationFlags::EvaluationFlags evaluation_flag);
+
+  /**
+   * @deprecated Please use the evaluate() function with the EvaluationFlags argument.
+   */
+  DEAL_II_DEPRECATED
+  void
   evaluate(const VectorizedArrayType *values_array,
            const bool                 evaluate_values,
            const bool                 evaluate_gradients);
@@ -2881,6 +3037,14 @@ public:
    */
   template <typename VectorType>
   void
+  gather_evaluate(const VectorType &                     input_vector,
+                  const EvaluationFlags::EvaluationFlags evaluation_flag);
+
+  /**
+   * @deprecated Please use the gather_evaluate() function with the EvaluationFlags argument.
+   */
+  template <typename VectorType>
+  DEAL_II_DEPRECATED void
   gather_evaluate(const VectorType &input_vector,
                   const bool        evaluate_values,
                   const bool        evaluate_gradients);
@@ -2895,6 +3059,13 @@ public:
    * distribute_local_to_global() or set_dof_values() methods).
    */
   void
+  integrate(const EvaluationFlags::EvaluationFlags evaluation_flag);
+
+  /**
+   * @deprecated Please use the integrate() function with the EvaluationFlags argument.
+   */
+  DEAL_II_DEPRECATED
+  void
   integrate(const bool integrate_values, const bool integrate_gradients);
 
   /**
@@ -2906,6 +3077,14 @@ public:
    * call stores the result of the testing in the given array `values_array`.
    */
   void
+  integrate(const EvaluationFlags::EvaluationFlags evaluation_flag,
+            VectorizedArrayType *                  values_array);
+
+  /**
+   * @deprecated Please use the integrate() function with the EvaluationFlags argument.
+   */
+  DEAL_II_DEPRECATED
+  void
   integrate(const bool           integrate_values,
             const bool           integrate_gradients,
             VectorizedArrayType *values_array);
@@ -2923,6 +3102,14 @@ public:
    */
   template <typename VectorType>
   void
+  integrate_scatter(const EvaluationFlags::EvaluationFlags evaluation_flag,
+                    VectorType &                           output_vector);
+
+  /**
+   * @deprecated Please use the integrate_scatter() function with the EvaluationFlags argument.
+   */
+  template <typename VectorType>
+  DEAL_II_DEPRECATED void
   integrate_scatter(const bool  integrate_values,
                     const bool  integrate_gradients,
                     VectorType &output_vector);
@@ -6971,6 +7158,29 @@ FEEvaluation<dim,
 }
 
 
+template <int dim,
+          int fe_degree,
+          int n_q_points_1d,
+          int n_components_,
+          typename Number,
+          typename VectorizedArrayType>
+inline void
+FEEvaluation<dim,
+             fe_degree,
+             n_q_points_1d,
+             n_components_,
+             Number,
+             VectorizedArrayType>::
+  evaluate(const EvaluationFlags::EvaluationFlags evaluation_flags)
+{
+#  ifdef DEBUG
+  Assert(this->dof_values_initialized == true,
+         internal::ExcAccessToUninitializedField());
+#  endif
+  evaluate(this->values_dofs[0], evaluation_flags);
+}
+
+
 
 template <int dim,
           int fe_degree,
@@ -7018,6 +7228,49 @@ FEEvaluation<dim,
 
 
 
+template <int dim,
+          int fe_degree,
+          int n_q_points_1d,
+          int n_components_,
+          typename Number,
+          typename VectorizedArrayType>
+inline void
+FEEvaluation<dim,
+             fe_degree,
+             n_q_points_1d,
+             n_components_,
+             Number,
+             VectorizedArrayType>::
+  evaluate(const VectorizedArrayType *            values_array,
+           const EvaluationFlags::EvaluationFlags evaluation_flags)
+{
+  SelectEvaluator<dim,
+                  fe_degree,
+                  n_q_points_1d,
+                  n_components,
+                  VectorizedArrayType>::
+    evaluate(*this->data,
+             const_cast<VectorizedArrayType *>(values_array),
+             this->values_quad[0],
+             this->gradients_quad[0][0],
+             this->hessians_quad[0][0],
+             this->scratch_data,
+             evaluation_flags & EvaluationFlags::values,
+             evaluation_flags & EvaluationFlags::gradients,
+             evaluation_flags & EvaluationFlags::hessians);
+
+#  ifdef DEBUG
+  if (evaluation_flags & EvaluationFlags::values)
+    this->values_quad_initialized = true;
+  if (evaluation_flags & EvaluationFlags::gradients)
+    this->gradients_quad_initialized = true;
+  if (evaluation_flags & EvaluationFlags::hessians)
+    this->hessians_quad_initialized = true;
+#  endif
+}
+
+
+
 template <int dim,
           int fe_degree,
           int n_q_points_1d,
@@ -7033,9 +7286,37 @@ FEEvaluation<
   n_components_,
   Number,
   VectorizedArrayType>::gather_evaluate(const VectorType &input_vector,
-                                        const bool        evaluate_values,
-                                        const bool        evaluate_gradients,
-                                        const bool        evaluate_hessians)
+
+                                        const bool evaluate_values,
+                                        const bool evaluate_gradients,
+                                        const bool evaluate_hessians)
+{
+  const EvaluationFlags::EvaluationFlags flag =
+    ((evaluate_values) ? EvaluationFlags::values : EvaluationFlags::nothing) |
+    ((evaluate_gradients) ? EvaluationFlags::gradients :
+                            EvaluationFlags::nothing) |
+    ((evaluate_hessians) ? EvaluationFlags::hessians :
+                           EvaluationFlags::nothing);
+
+  gather_evaluate(input_vector, flag);
+}
+
+template <int dim,
+          int fe_degree,
+          int n_q_points_1d,
+          int n_components_,
+          typename Number,
+          typename VectorizedArrayType>
+template <typename VectorType>
+inline void
+FEEvaluation<dim,
+             fe_degree,
+             n_q_points_1d,
+             n_components_,
+             Number,
+             VectorizedArrayType>::
+  gather_evaluate(const VectorType &                     input_vector,
+                  const EvaluationFlags::EvaluationFlags evaluation_flag)
 {
   // If the index storage is interleaved and contiguous and the vector storage
   // has the correct alignment, we can directly pass the pointer into the
@@ -7066,17 +7347,17 @@ FEEvaluation<
             VectorizedArrayType::size());
 
       evaluate(vec_values,
-               evaluate_values,
-               evaluate_gradients,
-               evaluate_hessians);
+               evaluation_flag & EvaluationFlags::values,
+               evaluation_flag & EvaluationFlags::gradients,
+               evaluation_flag & EvaluationFlags::hessians);
     }
   else
     {
       this->read_dof_values(input_vector);
       evaluate(this->begin_dof_values(),
-               evaluate_values,
-               evaluate_gradients,
-               evaluate_hessians);
+               evaluation_flag & EvaluationFlags::values,
+               evaluation_flag & EvaluationFlags::gradients,
+               evaluation_flag & EvaluationFlags::hessians);
     }
 }
 
@@ -7106,6 +7387,30 @@ FEEvaluation<dim,
 
 
 
+template <int dim,
+          int fe_degree,
+          int n_q_points_1d,
+          int n_components_,
+          typename Number,
+          typename VectorizedArrayType>
+inline void
+FEEvaluation<dim,
+             fe_degree,
+             n_q_points_1d,
+             n_components_,
+             Number,
+             VectorizedArrayType>::
+  integrate(const EvaluationFlags::EvaluationFlags integration_flag)
+{
+  integrate(integration_flag, this->values_dofs[0]);
+
+#  ifdef DEBUG
+  this->dof_values_initialized = true;
+#  endif
+}
+
+
+
 template <int dim,
           int fe_degree,
           int n_q_points_1d,
@@ -7154,6 +7459,62 @@ FEEvaluation<dim,
 
 
 
+template <int dim,
+          int fe_degree,
+          int n_q_points_1d,
+          int n_components_,
+          typename Number,
+          typename VectorizedArrayType>
+inline void
+FEEvaluation<dim,
+             fe_degree,
+             n_q_points_1d,
+             n_components_,
+             Number,
+             VectorizedArrayType>::
+  integrate(const EvaluationFlags::EvaluationFlags integration_flag,
+            VectorizedArrayType *                  values_array)
+{
+#  ifdef DEBUG
+  if (integration_flag & EvaluationFlags::values)
+    Assert(this->values_quad_submitted == true,
+           internal::ExcAccessToUninitializedField());
+  if (integration_flag & EvaluationFlags::gradients)
+    Assert(this->gradients_quad_submitted == true,
+           internal::ExcAccessToUninitializedField());
+#  endif
+  Assert(this->matrix_info != nullptr ||
+           this->mapped_geometry->is_initialized(),
+         ExcNotInitialized());
+
+  Assert(
+    (integration_flag &
+     ~(EvaluationFlags::values | EvaluationFlags::gradients)) == 0,
+    ExcMessage(
+      "Only EvaluationFlags::values and EvaluationFlags::gradients are supported."));
+
+  SelectEvaluator<dim,
+                  fe_degree,
+                  n_q_points_1d,
+                  n_components,
+                  VectorizedArrayType>::integrate(*this->data,
+                                                  values_array,
+                                                  this->values_quad[0],
+                                                  this->gradients_quad[0][0],
+                                                  this->scratch_data,
+                                                  integration_flag &
+                                                    EvaluationFlags::values,
+                                                  integration_flag &
+                                                    EvaluationFlags::gradients,
+                                                  false);
+
+#  ifdef DEBUG
+  this->dof_values_initialized = true;
+#  endif
+}
+
+
+
 template <int dim,
           int fe_degree,
           int n_q_points_1d,
@@ -7171,6 +7532,33 @@ FEEvaluation<
   VectorizedArrayType>::integrate_scatter(const bool  integrate_values,
                                           const bool  integrate_gradients,
                                           VectorType &destination)
+{
+  const EvaluationFlags::EvaluationFlags flag =
+    ((integrate_values) ? EvaluationFlags::values : EvaluationFlags::nothing) |
+    ((integrate_gradients) ? EvaluationFlags::gradients :
+                             EvaluationFlags::nothing);
+
+  integrate_scatter(flag, destination);
+}
+
+
+
+template <int dim,
+          int fe_degree,
+          int n_q_points_1d,
+          int n_components_,
+          typename Number,
+          typename VectorizedArrayType>
+template <typename VectorType>
+inline void
+FEEvaluation<dim,
+             fe_degree,
+             n_q_points_1d,
+             n_components_,
+             Number,
+             VectorizedArrayType>::
+  integrate_scatter(const EvaluationFlags::EvaluationFlags evaluation_flag,
+                    VectorType &                           destination)
 {
   // If the index storage is interleaved and contiguous and the vector storage
   // has the correct alignment, we can directly pass the pointer into the
@@ -7199,24 +7587,26 @@ FEEvaluation<
             ->component_dof_indices_offset[this->active_fe_index]
                                           [this->first_selected_component] *
           VectorizedArrayType::size());
-      SelectEvaluator<dim,
-                      fe_degree,
-                      n_q_points_1d,
-                      n_components,
-                      VectorizedArrayType>::integrate(*this->data,
-                                                      vec_values,
-                                                      this->values_quad[0],
-                                                      this
-                                                        ->gradients_quad[0][0],
-                                                      this->scratch_data,
-                                                      integrate_values,
-                                                      integrate_gradients,
-                                                      true);
+      SelectEvaluator<
+        dim,
+        fe_degree,
+        n_q_points_1d,
+        n_components,
+        VectorizedArrayType>::integrate(*this->data,
+                                        vec_values,
+                                        this->values_quad[0],
+                                        this->gradients_quad[0][0],
+                                        this->scratch_data,
+                                        evaluation_flag &
+                                          EvaluationFlags::values,
+                                        evaluation_flag &
+                                          EvaluationFlags::gradients,
+                                        true);
     }
   else
     {
-      integrate(integrate_values,
-                integrate_gradients,
+      integrate(evaluation_flag & EvaluationFlags::values,
+                evaluation_flag & EvaluationFlags::gradients,
                 this->begin_dof_values());
       this->distribute_local_to_global(destination);
     }
@@ -7431,6 +7821,30 @@ FEFaceEvaluation<dim,
 
 
 
+template <int dim,
+          int fe_degree,
+          int n_q_points_1d,
+          int n_components,
+          typename Number,
+          typename VectorizedArrayType>
+inline void
+FEFaceEvaluation<dim,
+                 fe_degree,
+                 n_q_points_1d,
+                 n_components,
+                 Number,
+                 VectorizedArrayType>::
+  evaluate(const EvaluationFlags::EvaluationFlags evaluation_flag)
+{
+#  ifdef DEBUG
+  Assert(this->dof_values_initialized, ExcNotInitialized());
+#  endif
+
+  evaluate(this->values_dofs[0], evaluation_flag);
+}
+
+
+
 template <int dim,
           int fe_degree,
           int n_q_points_1d,
@@ -7448,7 +7862,40 @@ FEFaceEvaluation<dim,
                                                 const bool evaluate_values,
                                                 const bool evaluate_gradients)
 {
-  if (!(evaluate_values + evaluate_gradients))
+  const EvaluationFlags::EvaluationFlags flag =
+    ((evaluate_values) ? EvaluationFlags::values : EvaluationFlags::nothing) |
+    ((evaluate_gradients) ? EvaluationFlags::gradients :
+                            EvaluationFlags::nothing);
+
+  evaluate(values_array, flag);
+}
+
+
+
+template <int dim,
+          int fe_degree,
+          int n_q_points_1d,
+          int n_components,
+          typename Number,
+          typename VectorizedArrayType>
+inline void
+FEFaceEvaluation<dim,
+                 fe_degree,
+                 n_q_points_1d,
+                 n_components,
+                 Number,
+                 VectorizedArrayType>::
+  evaluate(const VectorizedArrayType *            values_array,
+           const EvaluationFlags::EvaluationFlags evaluation_flag)
+{
+  Assert(
+    (evaluation_flag &
+     ~(EvaluationFlags::values | EvaluationFlags::gradients)) == 0,
+    ExcMessage(
+      "Only EvaluationFlags::values and EvaluationFlags::gradients are supported."));
+
+  if (!(evaluation_flag & EvaluationFlags::values) &&
+      !(evaluation_flag & EvaluationFlags::gradients))
     return;
 
   internal::FEFaceEvaluationSelector<
@@ -7462,8 +7909,8 @@ FEFaceEvaluation<dim,
                                    this->begin_values(),
                                    this->begin_gradients(),
                                    this->scratch_data,
-                                   evaluate_values,
-                                   evaluate_gradients,
+                                   evaluation_flag & EvaluationFlags::values,
+                                   evaluation_flag & EvaluationFlags::gradients,
                                    this->face_no,
                                    this->subface_index,
                                    this->face_orientation,
@@ -7472,15 +7919,39 @@ FEFaceEvaluation<dim,
                                      .face_orientations);
 
 #  ifdef DEBUG
-  if (evaluate_values == true)
+  if (evaluation_flag & EvaluationFlags::values)
     this->values_quad_initialized = true;
-  if (evaluate_gradients == true)
+  if (evaluation_flag & EvaluationFlags::gradients)
     this->gradients_quad_initialized = true;
 #  endif
 }
 
 
 
+template <int dim,
+          int fe_degree,
+          int n_q_points_1d,
+          int n_components,
+          typename Number,
+          typename VectorizedArrayType>
+inline void
+FEFaceEvaluation<dim,
+                 fe_degree,
+                 n_q_points_1d,
+                 n_components,
+                 Number,
+                 VectorizedArrayType>::
+  integrate(const EvaluationFlags::EvaluationFlags evaluation_flag)
+{
+  integrate(evaluation_flag, this->values_dofs[0]);
+
+#  ifdef DEBUG
+  this->dof_values_initialized = true;
+#  endif
+}
+
+
+
 template <int dim,
           int fe_degree,
           int n_q_points_1d,
@@ -7522,28 +7993,60 @@ FEFaceEvaluation<dim,
                                                  VectorizedArrayType
                                                    *values_array)
 {
-  if (!(integrate_values + integrate_gradients))
+  const EvaluationFlags::EvaluationFlags flag =
+    ((integrate_values) ? EvaluationFlags::values : EvaluationFlags::nothing) |
+    ((integrate_gradients) ? EvaluationFlags::gradients :
+                             EvaluationFlags::nothing);
+
+  integrate(flag, values_array);
+}
+
+
+
+template <int dim,
+          int fe_degree,
+          int n_q_points_1d,
+          int n_components,
+          typename Number,
+          typename VectorizedArrayType>
+inline void
+FEFaceEvaluation<dim,
+                 fe_degree,
+                 n_q_points_1d,
+                 n_components,
+                 Number,
+                 VectorizedArrayType>::
+  integrate(const EvaluationFlags::EvaluationFlags evaluation_flag,
+            VectorizedArrayType *                  values_array)
+{
+  Assert(
+    (evaluation_flag &
+     ~(EvaluationFlags::values | EvaluationFlags::gradients)) == 0,
+    ExcMessage(
+      "Only EvaluationFlags::values and EvaluationFlags::gradients are supported."));
+
+  if (!(evaluation_flag & EvaluationFlags::values) &&
+      !(evaluation_flag & EvaluationFlags::gradients))
     return;
 
-  internal::FEFaceEvaluationSelector<
-    dim,
-    fe_degree,
-    n_q_points_1d,
-    n_components,
-    Number,
-    VectorizedArrayType>::integrate(*this->data,
-                                    values_array,
-                                    this->begin_values(),
-                                    this->begin_gradients(),
-                                    this->scratch_data,
-                                    integrate_values,
-                                    integrate_gradients,
-                                    this->face_no,
-                                    this->subface_index,
-                                    this->face_orientation,
-                                    this->mapping_data
-                                      ->descriptor[this->active_fe_index]
-                                      .face_orientations);
+  internal::FEFaceEvaluationSelector<dim,
+                                     fe_degree,
+                                     n_q_points_1d,
+                                     n_components,
+                                     Number,
+                                     VectorizedArrayType>::
+    integrate(
+      *this->data,
+      values_array,
+      this->begin_values(),
+      this->begin_gradients(),
+      this->scratch_data,
+      evaluation_flag & EvaluationFlags::values,
+      evaluation_flag & EvaluationFlags::gradients,
+      this->face_no,
+      this->subface_index,
+      this->face_orientation,
+      this->mapping_data->descriptor[this->active_fe_index].face_orientations);
 }
 
 
@@ -7565,6 +8068,33 @@ FEFaceEvaluation<
   VectorizedArrayType>::gather_evaluate(const VectorType &input_vector,
                                         const bool        evaluate_values,
                                         const bool        evaluate_gradients)
+{
+  const EvaluationFlags::EvaluationFlags flag =
+    ((evaluate_values) ? EvaluationFlags::values : EvaluationFlags::nothing) |
+    ((evaluate_gradients) ? EvaluationFlags::gradients :
+                            EvaluationFlags::nothing);
+
+  gather_evaluate(input_vector, flag);
+}
+
+
+
+template <int dim,
+          int fe_degree,
+          int n_q_points_1d,
+          int n_components_,
+          typename Number,
+          typename VectorizedArrayType>
+template <typename VectorType>
+inline void
+FEFaceEvaluation<dim,
+                 fe_degree,
+                 n_q_points_1d,
+                 n_components_,
+                 Number,
+                 VectorizedArrayType>::
+  gather_evaluate(const VectorType &                     input_vector,
+                  const EvaluationFlags::EvaluationFlags evaluation_flag)
 {
   static_assert(internal::has_begin<VectorType>::value &&
                   (std::is_same<decltype(std::declval<VectorType>().begin()),
@@ -7575,6 +8105,12 @@ FEFaceEvaluation<
                 "evaluating to a pointer to basic number (float,double). "
                 "Use read_dof_values() followed by evaluate() instead.");
 
+  Assert(
+    (evaluation_flag &
+     ~(EvaluationFlags::values | EvaluationFlags::gradients)) == 0,
+    ExcMessage(
+      "Only EvaluationFlags::values and EvaluationFlags::gradients are supported."));
+
   if (!internal::FEFaceEvaluationSelector<dim,
                                           fe_degree,
                                           n_q_points_1d,
@@ -7587,8 +8123,8 @@ FEFaceEvaluation<
                         this->begin_values(),
                         this->begin_gradients(),
                         this->scratch_data,
-                        evaluate_values,
-                        evaluate_gradients,
+                        evaluation_flag & EvaluationFlags::values,
+                        evaluation_flag & EvaluationFlags::gradients,
                         this->active_fe_index,
                         this->first_selected_component,
                         this->cell,
@@ -7600,13 +8136,13 @@ FEFaceEvaluation<
                           .face_orientations))
     {
       this->read_dof_values(input_vector);
-      this->evaluate(evaluate_values, evaluate_gradients);
+      this->evaluate(evaluation_flag);
     }
 
 #  ifdef DEBUG
-  if (evaluate_values == true)
+  if (evaluation_flag & EvaluationFlags::values)
     this->values_quad_initialized = true;
-  if (evaluate_gradients == true)
+  if (evaluation_flag & EvaluationFlags::gradients)
     this->gradients_quad_initialized = true;
 #  endif
 }
@@ -7630,6 +8166,33 @@ FEFaceEvaluation<
   VectorizedArrayType>::integrate_scatter(const bool  integrate_values,
                                           const bool  integrate_gradients,
                                           VectorType &destination)
+{
+  const EvaluationFlags::EvaluationFlags flag =
+    ((integrate_values) ? EvaluationFlags::values : EvaluationFlags::nothing) |
+    ((integrate_gradients) ? EvaluationFlags::gradients :
+                             EvaluationFlags::nothing);
+
+  integrate_scatter(flag, destination);
+}
+
+
+
+template <int dim,
+          int fe_degree,
+          int n_q_points_1d,
+          int n_components_,
+          typename Number,
+          typename VectorizedArrayType>
+template <typename VectorType>
+inline void
+FEFaceEvaluation<dim,
+                 fe_degree,
+                 n_q_points_1d,
+                 n_components_,
+                 Number,
+                 VectorizedArrayType>::
+  integrate_scatter(const EvaluationFlags::EvaluationFlags evaluation_flag,
+                    VectorType &                           destination)
 {
   static_assert(internal::has_begin<VectorType>::value &&
                   (std::is_same<decltype(std::declval<VectorType>().begin()),
@@ -7654,8 +8217,8 @@ FEFaceEvaluation<
                           this->begin_values(),
                           this->begin_gradients(),
                           this->scratch_data,
-                          integrate_values,
-                          integrate_gradients,
+                          evaluation_flag & EvaluationFlags::values,
+                          evaluation_flag & EvaluationFlags::gradients,
                           this->active_fe_index,
                           this->first_selected_component,
                           this->cell,

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.