Reference documentation for deal.II version 9.4.1
\(\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\}}\)
Loading...
Searching...
No Matches
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
32namespace 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