Reference documentation for deal.II version GIT relicensing-1062-gc06da148b8 2024-07-15 19:20:02+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::communication_block_size
151 template <typename T>
152 using communication_block_size_t = decltype(T::communication_block_size);
153
154 template <typename T>
155 constexpr bool has_communication_block_size =
156 is_supported_operation<communication_block_size_t, T>;
157
163 template <typename VectorType>
164 using is_vector_type = decltype(is_serial_vector<VectorType>::value);
165
170 template <typename VectorType>
171 using is_serial_vector_type =
172 decltype(std::enable_if_t<is_serial_vector<VectorType>::value, int>());
173
179 template <typename VectorType>
180 constexpr bool is_not_parallel_vector =
181 (is_supported_operation<is_vector_type, VectorType> == false) ||
182 (is_supported_operation<is_serial_vector_type, VectorType> == true);
183
184
185
190 template <typename VectorType>
191 struct is_serial_vector_or_array
192 {
193 static const bool value =
194 is_supported_operation<is_serial_vector_type, VectorType>;
195 };
196
201 template <typename Number>
202 struct is_serial_vector_or_array<::ArrayView<Number>>
203 {
204 static const bool value = true;
205 };
206
207 // We need to have a separate declaration for static const members
208 template <typename VectorType>
209 const bool is_serial_vector_or_array<VectorType>::value;
210
211
212
213 // type trait for vector T and Number to see if
214 // we can do vectorized load/save.
215 // for VectorReader and VectorDistributorLocalToGlobal we assume that
216 // if both begin() and local_element()
217 // exist, then begin() + offset == local_element(offset)
218 template <typename T, typename Number>
219 struct is_vectorizable
220 {
221 static const bool value =
222 has_begin<T> &&
223 (has_local_element<T> || is_serial_vector_or_array<T>::value) &&
224 std::is_same_v<typename T::value_type, Number>;
225 };
226
227 // We need to have a separate declaration for static const members
228 template <typename T, typename Number>
229 const bool is_vectorizable<T, Number>::value;
230
231} // namespace internal
232#endif
233
235
236#endif
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:502
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:503