Reference documentation for deal.II version 9.2.0
\(\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 - 2020 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  struct has_local_element
42  {
43  private:
44  // this will work always.
45  // we let it be void as we know T::local_element() (if exists) should
46  // certainly return something
47  static void
48  detect(...);
49 
50  // this detecter will work only if we have "... T::local_element() const"
51  // and its return type will be the same as local_element(),
52  // that we expect to be T::value_type
53  template <typename U>
54  static decltype(std::declval<U const>().local_element(0))
55  detect(const U &);
56 
57  public:
58  // finally here we check if our detector has non-void return type
59  // T::value_type. This will happen if compiler can use second detector,
60  // otherwise SFINAE let it work with the more general first one that is void
61  static const bool value =
62  !std::is_same<void, decltype(detect(std::declval<T>()))>::value;
63  };
64 
65  // We need to have a separate declaration for static const members
66  template <typename T>
67  const bool has_local_element<T>::value;
68 
69 
70 
71  // a helper type-trait that leverage SFINAE to figure out if type T has
72  // void T::add_local_element(const uint, const typename T::value_type)
73  template <typename T>
74  struct has_add_local_element
75  {
76  private:
77  static int
78  detect(...);
79 
80  template <typename U>
81  static decltype(
82  std::declval<U>().add_local_element(0, typename T::value_type()))
83  detect(const U &);
84 
85  public:
86  static const bool value =
87  !std::is_same<int, decltype(detect(std::declval<T>()))>::value;
88  };
89 
90  // We need to have a separate declaration for static const members
91  template <typename T>
92  const bool has_add_local_element<T>::value;
93 
94 
95 
96  // a helper type-trait that leverage SFINAE to figure out if type T has
97  // void T::set_local_element(const uint, const typename T::value_type)
98  template <typename T>
99  struct has_set_local_element
100  {
101  private:
102  static int
103  detect(...);
104 
105  template <typename U>
106  static decltype(
107  std::declval<U>().set_local_element(0, typename T::value_type()))
108  detect(const U &);
109 
110  public:
111  static const bool value =
112  !std::is_same<int, decltype(detect(std::declval<T>()))>::value;
113  };
114 
115  // We need to have a separate declaration for static const members
116  template <typename T>
117  const bool has_set_local_element<T>::value;
118 
119 
120 
121  // same as above to check
122  // bool T::partitioners_are_compatible(const Utilities::MPI::Partitioner &)
123  // const
124  template <typename T>
125  struct has_partitioners_are_compatible
126  {
127  private:
128  static void
129  detect(...);
130 
131  template <typename U>
132  static decltype(std::declval<U const>().partitioners_are_compatible(
133  std::declval<Utilities::MPI::Partitioner>()))
134  detect(const U &);
135 
136  public:
137  static const bool value =
138  std::is_same<bool, decltype(detect(std::declval<T>()))>::value;
139  };
140 
141  // We need to have a separate declaration for static const members
142  template <typename T>
143  const bool has_partitioners_are_compatible<T>::value;
144 
145 
146  // same as above to check
147  // ... T::begin() const
148  template <typename T>
149  struct has_begin
150  {
151  private:
152  static void
153  detect(...);
154 
155  template <typename U>
156  static decltype(std::declval<U const>().begin())
157  detect(const U &);
158 
159  public:
160  static const bool value =
161  !std::is_same<void, decltype(detect(std::declval<T>()))>::value;
162  };
163 
164  // We need to have a separate declaration for static const members
165  template <typename T>
166  const bool has_begin<T>::value;
167 
168 
169  // type trait for vector T and Number to see if
170  // we can do vectorized load/save.
171  // for VectorReader and VectorDistributorLocalToGlobal we assume that
172  // if both begin() and local_element()
173  // exist, then begin() + offset == local_element(offset)
174  template <typename T, typename Number>
175  struct is_vectorizable
176  {
177  static const bool value =
181  };
182 
183  // We need to have a separate declaration for static const members
184  template <typename T, typename Number>
186 
187 
188  //
189  // type-traits for Matrix-Free
190  //
191  // similar to type traits in FEEvaluation, below we add type-traits
192  // to distinguish between vectors that provide different interface for
193  // operations like update_ghost_values(), compress(), etc.
194  // see internal::has_local_element in fe_evaluation.h that documents
195  // how those type traits work.
196 
197  // a helper type-trait that leverage SFINAE to figure out if type T has
198  // void T::update_ghost_values_start(const uint) const
199  template <typename T>
200  struct has_update_ghost_values_start
201  {
202  private:
203  static bool
204  detect(...);
205 
206  template <typename U>
207  static decltype(std::declval<U const>().update_ghost_values_start(0))
208  detect(const U &);
209 
210  public:
211  static const bool value =
212  !std::is_same<bool, decltype(detect(std::declval<T>()))>::value;
213  };
214 
215  // We need to have a separate declaration for static const members
216  template <typename T>
217  const bool has_update_ghost_values_start<T>::value;
218 
219 
220 
221  // a helper type-trait that leverage SFINAE to figure out if type T has
222  // void T:: compress_start(const uint, VectorOperation::values)
223  template <typename T>
224  struct has_compress_start
225  {
226  private:
227  static bool
228  detect(...);
229 
230  template <typename U>
231  static decltype(std::declval<U>().compress_start(0, VectorOperation::add))
232  detect(const U &);
233 
234  public:
235  static const bool value =
236  !std::is_same<bool, decltype(detect(std::declval<T>()))>::value;
237  };
238 
239  // We need to have a separate declaration for static const members
240  template <typename T>
241  const bool has_compress_start<T>::value;
242 
243 
244 
245  // type trait for vector T to see if
246  // we do a custom data exchange route.
247  // We assume that if both begin() and local_element()
248  // exist, then begin() + offset == local_element(offset)
249  template <typename T>
250  struct has_exchange_on_subset
251  {
252  static const bool value =
254  };
255 
256  // We need to have a separate declaration for static const members
257  template <typename T>
259 
260 
261 
262  // a helper type-trait that leverage SFINAE to figure out if type T has
263  // T::communication_block_size
264  template <typename T>
265  struct has_communication_block_size
266  {
267  private:
268  static void
269  detect(...);
270 
271  template <typename U>
272  static decltype(U::communication_block_size)
273  detect(const U &);
274 
275  public:
276  static const bool value =
277  !std::is_same<void, decltype(detect(std::declval<T>()))>::value;
278  };
279 
280  // We need to have a separate declaration for static const members
281  template <typename T>
283 
284 
285 
286  // type trait for vector T to see if
287  // we need to do any data exchange for this vector type at all.
288  // is_serial_vector<> would have been enough, but in some circumstances
289  // (like calculation of diagonals for matrix-free operators)
290  // a dummy InVector == unsigned int is provided.
291  // Thus we have to treat this case as well.
292  template <typename T>
293  struct is_serial_or_dummy
294  {
295  private:
296  // catches all cases including unsigned int
297  static void
298  detect(...);
299 
300  // catches serial vectors
301  template <
302  typename U,
303  typename std::enable_if<is_serial_vector<U>::value, U>::type * = nullptr>
304  static void
305  detect(const U &);
306 
307  // catches parallel vectors
308  template <
309  typename U,
310  typename std::enable_if<!is_serial_vector<U>::value, U>::type * = nullptr>
311  static bool
312  detect(const U &);
313 
314  public:
315  static const bool value =
316  std::is_same<void, decltype(detect(std::declval<T>()))>::value;
317  };
318 
319  // We need to have a separate declaration for static const members
320  template <typename T>
321  const bool is_serial_or_dummy<T>::value;
322 
323 
324 } // namespace internal
325 #endif
326 
328 
329 #endif
LAPACKSupport::U
static const char U
Definition: lapack_support.h:167
partitioner.h
VectorOperation::add
@ add
Definition: vector_operation.h:53
LAPACKSupport::T
static const char T
Definition: lapack_support.h:163
is_serial_vector
Definition: vector_type_traits.h:49
TrilinosWrappers::internal::begin
VectorType::value_type * begin(VectorType &V)
Definition: trilinos_sparse_matrix.cc:51
Number
vector_type_traits.h
DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:358
value
static const bool value
Definition: dof_tools_constraints.cc:433
config.h
internal
Definition: aligned_vector.h:370
DEAL_II_NAMESPACE_CLOSE
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:359