]> https://gitweb.dealii.org/ - dealii.git/commitdiff
FEEval: do not cast const away during read_dof_values() 13240/head
authorPeter Munch <peterrmuench@gmail.com>
Fri, 14 Jan 2022 21:27:30 +0000 (22:27 +0100)
committerPeter Munch <peterrmuench@gmail.com>
Sat, 15 Jan 2022 12:46:08 +0000 (13:46 +0100)
include/deal.II/matrix_free/fe_evaluation.h
include/deal.II/matrix_free/type_traits.h
include/deal.II/matrix_free/vector_access_internal.h

index ac12008a35112966fffc075bab29b1dcb44fac97..0bdcbe68900f0f83b5390975bf1d904577a0c892 100644 (file)
@@ -3270,17 +3270,35 @@ FEEvaluationBase<dim, n_components_, Number, is_face, VectorizedArrayType>::
 
 namespace internal
 {
+  // given a block vector return the underlying vector type
+  // including constness (specified by bool)
+  template <typename VectorType, bool>
+  struct ConstBlockVectorSelector;
+
+  template <typename VectorType>
+  struct ConstBlockVectorSelector<VectorType, true>
+  {
+    using BaseVectorType = const typename VectorType::BlockType;
+  };
+
+  template <typename VectorType>
+  struct ConstBlockVectorSelector<VectorType, false>
+  {
+    using BaseVectorType = typename VectorType::BlockType;
+  };
+
   // allows to select between block vectors and non-block vectors, which
   // allows to use a unified interface for extracting blocks on block vectors
   // and doing nothing on usual vectors
   template <typename VectorType, bool>
-  struct BlockVectorSelector
-  {};
+  struct BlockVectorSelector;
 
   template <typename VectorType>
   struct BlockVectorSelector<VectorType, true>
   {
-    using BaseVectorType = typename VectorType::BlockType;
+    using BaseVectorType = typename ConstBlockVectorSelector<
+      VectorType,
+      std::is_const<VectorType>::value>::BaseVectorType;
 
     static BaseVectorType *
     get_vector_component(VectorType &vec, const unsigned int component)
@@ -3329,6 +3347,20 @@ namespace internal
     }
   };
 
+  template <typename VectorType>
+  struct BlockVectorSelector<const std::vector<VectorType>, false>
+  {
+    using BaseVectorType = const VectorType;
+
+    static const BaseVectorType *
+    get_vector_component(const std::vector<VectorType> &vec,
+                         const unsigned int             component)
+    {
+      AssertIndexRange(component, vec.size());
+      return &vec[component];
+    }
+  };
+
   template <typename VectorType>
   struct BlockVectorSelector<std::vector<VectorType *>, false>
   {
@@ -3342,6 +3374,20 @@ namespace internal
       return vec[component];
     }
   };
+
+  template <typename VectorType>
+  struct BlockVectorSelector<const std::vector<VectorType *>, false>
+  {
+    using BaseVectorType = const VectorType;
+
+    static const BaseVectorType *
+    get_vector_component(const std::vector<VectorType *> &vec,
+                         const unsigned int               component)
+    {
+      AssertIndexRange(component, vec.size());
+      return vec[component];
+    }
+  };
 } // namespace internal
 
 
@@ -4183,15 +4229,13 @@ namespace internal
   template <int n_components, typename VectorType>
   std::pair<
     std::array<typename internal::BlockVectorSelector<
-                 typename std::remove_const<VectorType>::type,
-                 IsBlockVector<typename std::remove_const<VectorType>::type>::
-                   value>::BaseVectorType *,
+                 VectorType,
+                 IsBlockVector<VectorType>::value>::BaseVectorType *,
                n_components>,
     std::array<
       const std::vector<ArrayView<const typename internal::BlockVectorSelector<
-        typename std::remove_const<VectorType>::type,
-        IsBlockVector<typename std::remove_const<VectorType>::type>::value>::
-                                    BaseVectorType::value_type>> *,
+        VectorType,
+        IsBlockVector<VectorType>::value>::BaseVectorType::value_type>> *,
       n_components>>
   get_vector_data(VectorType &       src,
                   const unsigned int first_index,
@@ -4203,32 +4247,33 @@ namespace internal
     // of components is checked in the internal data
     std::pair<
       std::array<typename internal::BlockVectorSelector<
-                   typename std::remove_const<VectorType>::type,
-                   IsBlockVector<typename std::remove_const<VectorType>::type>::
-                     value>::BaseVectorType *,
+                   VectorType,
+                   IsBlockVector<VectorType>::value>::BaseVectorType *,
                  n_components>,
       std::array<
         const std::vector<
           ArrayView<const typename internal::BlockVectorSelector<
-            typename std::remove_const<VectorType>::type,
-            IsBlockVector<typename std::remove_const<VectorType>::type>::
-              value>::BaseVectorType::value_type>> *,
+            VectorType,
+            IsBlockVector<VectorType>::value>::BaseVectorType::value_type>> *,
         n_components>>
       src_data;
 
     for (unsigned int d = 0; d < n_components; ++d)
       src_data.first[d] = internal::BlockVectorSelector<
-        typename std::remove_const<VectorType>::type,
-        IsBlockVector<typename std::remove_const<VectorType>::type>::value>::
-        get_vector_component(
-          const_cast<typename std::remove_const<VectorType>::type &>(src),
-          d + first_index);
+        VectorType,
+        IsBlockVector<VectorType>::value>::get_vector_component(src,
+                                                                d +
+                                                                  first_index);
 
     for (unsigned int d = 0; d < n_components; ++d)
-      src_data.second[d] = get_shared_vector_data(*src_data.first[d],
-                                                  is_valid_mode_for_sm,
-                                                  active_fe_index,
-                                                  dof_info);
+      src_data.second[d] = get_shared_vector_data(
+        const_cast<typename internal::BlockVectorSelector<
+          typename std::remove_const<VectorType>::type,
+          IsBlockVector<typename std::remove_const<VectorType>::type>::value>::
+                     BaseVectorType &>(*src_data.first[d]),
+        is_valid_mode_for_sm,
+        active_fe_index,
+        dof_info);
 
     return src_data;
   }
index b57c05049af3e9d13a9b8f9a8894b8dd9090b315..bce4761ae02635978670f4cbc9e4621daeca4f74 100644 (file)
@@ -199,7 +199,8 @@ namespace internal
   {
     static const bool value =
       has_begin<T>::value &&
-      (has_local_element<T>::value || is_serial_vector<T>::value) &&
+      (has_local_element<T>::value ||
+       is_serial_vector<typename std::remove_const<T>::type>::value) &&
       std::is_same<typename T::value_type, Number>::value;
   };
 
index 3164675497237f90f62981c334e9fda17db0b097..7222b3321bdf155ea5eb2f142165c0f09c358d99 100644 (file)
@@ -247,10 +247,20 @@ namespace internal
                             VectorizedArrayType *dof_values,
                             std::integral_constant<bool, true>) const
     {
+#ifdef DEBUG
+      // in debug mode, run non-vectorized version because this path
+      // has additional checks (e.g., regarding ghosting)
+      process_dofs_vectorized(dofs_per_cell,
+                              dof_index,
+                              vec,
+                              dof_values,
+                              std::integral_constant<bool, false>());
+#else
       const Number *vec_ptr = vec.begin() + dof_index;
       for (unsigned int i = 0; i < dofs_per_cell;
            ++i, vec_ptr += VectorizedArrayType::size())
         dof_values[i].load(vec_ptr);
+#endif
     }
 
 
@@ -340,7 +350,17 @@ namespace internal
                        VectorizedArrayType &res,
                        std::integral_constant<bool, true>) const
     {
+#ifdef DEBUG
+      // in debug mode, run non-vectorized version because this path
+      // has additional checks (e.g., regarding ghosting)
+      process_dof_gather(indices,
+                         vec,
+                         constant_offset,
+                         res,
+                         std::integral_constant<bool, false>());
+#else
       res.gather(vec.begin() + constant_offset, indices);
+#endif
     }
 
 

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.