Reference documentation for deal.II version GIT 7bd1c95dbb 2022-06-29 20:50:01+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
type_traits.h
Go to the documentation of this file.
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2019 - 2022 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 
17 #ifndef dealii_matrix_free_type_traits_h
18 #define dealii_matrix_free_type_traits_h
19 
20 // various type-traits used exclusively within the matrix-free framework
21 
22 #include <deal.II/base/config.h>
23 
25 
27 
28 
30 
31 #ifndef DOXYGEN
32 namespace internal
33 {
34  //
35  // type traits for FEEvaluation
36  //
37 
38  // a helper type-trait that leverage SFINAE to figure out if type T has
39  // ... T::local_element() const
40  template <typename T>
41  using local_element_t = decltype(std::declval<T const>().local_element(0));
42 
43  template <typename T>
44  constexpr bool has_local_element = is_supported_operation<local_element_t, T>;
45 
46 
47 
48  // a helper type-trait that leverage SFINAE to figure out if type T has
49  // void T::add_local_element(const uint, const typename T::value_type)
50  template <typename T>
51  using add_local_element_t =
52  decltype(std::declval<T>().add_local_element(0, typename T::value_type()));
53 
54  template <typename T>
55  constexpr bool has_add_local_element =
56  is_supported_operation<add_local_element_t, T>;
57 
58 
59 
60  // a helper type-trait that leverage SFINAE to figure out if type T has
61  // void T::set_local_element(const uint, const typename T::value_type)
62  template <typename T>
63  using set_local_element_t =
64  decltype(std::declval<T>().set_local_element(0, typename T::value_type()));
65 
66  template <typename T>
67  constexpr bool has_set_local_element =
68  is_supported_operation<set_local_element_t, T>;
69 
70 
71 
72  // same as above to check
73  // bool T::partitioners_are_compatible(const Utilities::MPI::Partitioner &)
74  // const
75  template <typename T>
76  using partitioners_are_compatible_t =
77  decltype(std::declval<T const>().partitioners_are_compatible(
78  std::declval<Utilities::MPI::Partitioner>()));
79 
80  template <typename T>
81  constexpr bool has_partitioners_are_compatible =
82  is_supported_operation<partitioners_are_compatible_t, T>;
83 
84 
85 
86  // same as above to check
87  // ... T::begin() const
88  template <typename T>
89  using begin_t = decltype(std::declval<T const>().begin());
90 
91  template <typename T>
92  constexpr bool has_begin = is_supported_operation<begin_t, T>;
93 
94 
95 
96  // same as above to check
97  // ... T::shared_vector_data() const
98  template <typename T>
99  using shared_vector_data_t =
100  decltype(std::declval<T const>().shared_vector_data());
101 
102  template <typename T>
103  constexpr bool has_shared_vector_data =
104  is_supported_operation<shared_vector_data_t, T>;
105 
106 
107 
108  // type trait for vector T and Number to see if
109  // we can do vectorized load/save.
110  // for VectorReader and VectorDistributorLocalToGlobal we assume that
111  // if both begin() and local_element()
112  // exist, then begin() + offset == local_element(offset)
113  template <typename T, typename Number>
114  struct is_vectorizable
115  {
116  static const bool value =
117  has_begin<T> &&
118  (has_local_element<T> ||
120  std::is_same<typename T::value_type, Number>::value;
121  };
122 
123  // We need to have a separate declaration for static const members
124  template <typename T, typename Number>
125  const bool is_vectorizable<T, Number>::value;
126 
127 
128  //
129  // type-traits for Matrix-Free
130  //
131  // similar to type traits in FEEvaluation, below we add type-traits
132  // to distinguish between vectors that provide different interface for
133  // operations like update_ghost_values(), compress(), etc.
134  // see internal::has_local_element in fe_evaluation.h that documents
135  // how those type traits work.
136 
137  // a helper type-trait that leverage SFINAE to figure out if type T has
138  // void T::update_ghost_values_start(const uint) const
139  template <typename T>
140  using update_ghost_values_start_t =
141  decltype(std::declval<T const>().update_ghost_values_start(0));
142 
143  template <typename T>
144  constexpr bool has_update_ghost_values_start =
145  is_supported_operation<update_ghost_values_start_t, T>;
146 
147 
148 
149  // a helper type-trait that leverage SFINAE to figure out if type T has
150  // void T:: compress_start(const uint, VectorOperation::values)
151  template <typename T>
152  using compress_start_t =
153  decltype(std::declval<T>().compress_start(0, VectorOperation::add));
154 
155  template <typename T>
156  constexpr bool has_compress_start =
157  is_supported_operation<compress_start_t, T>;
158 
159 
160 
161  // type trait for vector T to see if
162  // we do a custom data exchange route.
163  // We assume that if both begin() and local_element()
164  // exist, then begin() + offset == local_element(offset)
165  template <typename T>
166  constexpr bool has_exchange_on_subset =
167  has_begin<T> &&has_local_element<T> &&has_partitioners_are_compatible<T>;
168 
169 
170 
171  // a helper type-trait that leverage SFINAE to figure out if type T has
172  // T::communication_block_size
173  template <typename T>
174  using communication_block_size_t = decltype(T::communication_block_size);
175 
176  template <typename T>
177  constexpr bool has_communication_block_size =
178  is_supported_operation<communication_block_size_t, T>;
179 
180 
181 
182  // type trait for vector T to see if
183  // we need to do any data exchange for this vector type at all.
184  // is_serial_vector<> would have been enough, but in some circumstances
185  // (like calculation of diagonals for matrix-free operators)
186  // a dummy InVector == unsigned int is provided.
187  // Thus we have to treat this case as well.
188  template <class T, class IsSerialVectorNotSpecialized = void>
189  using not_parallel_vector_t =
190  std::integral_constant<bool, is_serial_vector<T>::value>;
191 
197  template <class VectorType>
198  using is_vector_type = decltype(is_serial_vector<VectorType>::value);
199 
204  template <class VectorType>
205  using is_serial_vector_type = decltype(
206  typename std::enable_if<is_serial_vector<VectorType>::value, int>::type());
207 
213  template <class VectorType>
214  constexpr bool is_not_parallel_vector =
215  (is_supported_operation<is_vector_type, VectorType> == false) ||
216  (is_supported_operation<is_serial_vector_type, VectorType> == true);
217 } // namespace internal
218 #endif
219 
221 
222 #endif
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:442
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:443
VectorType::value_type * begin(VectorType &V)