deal.II version GIT relicensing-2848-g5241f990fb 2025-03-16 19:30:00+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\}}\)
Loading...
Searching...
No Matches
type_traits.h
Go to the documentation of this file.
1// ------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: LGPL-2.1-or-later
4// Copyright (C) 2019 - 2024 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Part of the source code is dual licensed under Apache-2.0 WITH
9// LLVM-exception OR LGPL-2.1-or-later. Detailed license information
10// governing the source code and code contributions can be found in
11// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II.
12//
13// ------------------------------------------------------------------------
14
15
16#ifndef dealii_matrix_free_type_traits_h
17#define dealii_matrix_free_type_traits_h
18
19// various type-traits used exclusively within the matrix-free framework
20
21#include <deal.II/base/config.h>
22
24
26
27
29
30#ifndef DOXYGEN
31
32namespace internal
33{
34 //
35 // type traits for FEEvaluation
36 //
37
38 // a helper type-trait leveraging 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<const T>().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 leveraging 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 leveraging 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 // same as above to check
72 // bool T::partitioners_are_compatible(const Utilities::MPI::Partitioner &)
73 // const
74 template <typename T>
75 using partitioners_are_compatible_t =
76 decltype(std::declval<const T>().partitioners_are_compatible(
77 std::declval<Utilities::MPI::Partitioner>()));
78
79 template <typename T>
80 constexpr bool has_partitioners_are_compatible =
81 is_supported_operation<partitioners_are_compatible_t, T>;
82
83
84
85 // same as above to check
86 // ... T::begin() const
87 template <typename T>
88 using begin_t = decltype(std::declval<const T>().begin());
89
90 template <typename T>
91 constexpr bool has_begin = is_supported_operation<begin_t, T>;
92
93
94
95 // same as above to check
96 // ... T::shared_vector_data() const
97 template <typename T>
98 using shared_vector_data_t =
99 decltype(std::declval<const T>().shared_vector_data());
100
101 template <typename T>
102 constexpr bool has_shared_vector_data =
103 is_supported_operation<shared_vector_data_t, T>;
104
105
106 //
107 // type-traits for Matrix-Free
108 //
109 // similar to type traits in FEEvaluation, below we add type-traits
110 // to distinguish between vectors that provide different interface for
111 // operations like update_ghost_values(), compress(), etc.
112 // see internal::has_local_element in fe_evaluation.h that documents
113 // how those type traits work.
114
115 // a helper type-trait that leverage SFINAE to figure out if type T has
116 // void T::update_ghost_values_start(const uint) const
117 template <typename T>
118 using update_ghost_values_start_t =
119 decltype(std::declval<const T>().update_ghost_values_start(0));
120
121 template <typename T>
122 constexpr bool has_update_ghost_values_start =
123 is_supported_operation<update_ghost_values_start_t, T>;
124
125
126
127 // a helper type-trait that leverage SFINAE to figure out if type T has
128 // void T:: compress_start(const uint, VectorOperation::values)
129 template <typename T>
130 using compress_start_t =
131 decltype(std::declval<T>().compress_start(0, VectorOperation::add));
132
133 template <typename T>
134 constexpr bool has_compress_start =
135 is_supported_operation<compress_start_t, T>;
136
137
138
139 // type trait for vector T to see if
140 // we do a custom data exchange route.
141 // We assume that if both begin() and local_element()
142 // exist, then begin() + offset == local_element(offset)
143 template <typename T>
144 constexpr bool has_exchange_on_subset =
145 has_begin<T> && has_local_element<T> && has_partitioners_are_compatible<T>;
146
147
148
149 // a helper type-trait that leverage SFINAE to figure out if type T has
150 // T & T::operator=(const T::value_type) const
151 template <typename T>
152 using assignment_operator_t =
153 decltype(std::declval<T>().operator=(typename T::value_type()));
154
155 template <typename T>
156 constexpr bool has_assignment_operator =
157 is_supported_operation<assignment_operator_t, T>;
158
159
160
161 // a helper type-trait that leverage SFINAE to figure out if type T has
162 // T::communication_block_size
163 template <typename T>
164 using communication_block_size_t = decltype(T::communication_block_size);
165
166 template <typename T>
167 constexpr bool has_communication_block_size =
168 is_supported_operation<communication_block_size_t, T>;
169
175 template <typename VectorType>
176 using is_vector_type = decltype(is_serial_vector<VectorType>::value);
177
182 template <typename VectorType>
183 using is_serial_vector_type =
184 decltype(std::enable_if_t<is_serial_vector<VectorType>::value, int>());
185
191 template <typename VectorType>
192 constexpr bool is_not_parallel_vector =
193 (is_supported_operation<is_vector_type, VectorType> == false) ||
194 (is_supported_operation<is_serial_vector_type, VectorType> == true);
195
196
197
202 template <typename VectorType>
203 struct is_serial_vector_or_array
204 {
205 static const bool value =
206 is_supported_operation<is_serial_vector_type, VectorType>;
207 };
208
213 template <typename Number>
214 struct is_serial_vector_or_array<::ArrayView<Number>>
215 {
216 static const bool value = true;
217 };
218
219 // We need to have a separate declaration for static const members
220 template <typename VectorType>
221 const bool is_serial_vector_or_array<VectorType>::value;
222
223
224
225 // type trait for vector T and Number to see if
226 // we can do vectorized load/save.
227 // for VectorReader and VectorDistributorLocalToGlobal we assume that
228 // if both begin() and local_element()
229 // exist, then begin() + offset == local_element(offset)
230 template <typename T, typename Number>
231 struct is_vectorizable
232 {
233 static const bool value =
234 has_begin<T> &&
235 (has_local_element<T> || is_serial_vector_or_array<T>::value) &&
236 std::is_same_v<typename T::value_type, Number>;
237 };
238
239 // We need to have a separate declaration for static const members
240 template <typename T, typename Number>
241 const bool is_vectorizable<T, Number>::value;
242
243} // namespace internal
244#endif
245
247
248#endif
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:40
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:41