Reference documentation for deal.II version GIT relicensing-384-g4769914377 2024-04-13 09:00: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 - 2023 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
31namespace internal
32{
33 //
34 // type traits for FEEvaluation
35 //
36
37 // a helper type-trait that leverage SFINAE to figure out if type T has
38 // ... T::local_element() const
39 template <typename T>
40 using local_element_t = decltype(std::declval<const T>().local_element(0));
41
42 template <typename T>
43 constexpr bool has_local_element = is_supported_operation<local_element_t, T>;
44
45
46
47 // a helper type-trait that leverage SFINAE to figure out if type T has
48 // void T::add_local_element(const uint, const typename T::value_type)
49 template <typename T>
50 using add_local_element_t =
51 decltype(std::declval<T>().add_local_element(0, typename T::value_type()));
52
53 template <typename T>
54 constexpr bool has_add_local_element =
55 is_supported_operation<add_local_element_t, T>;
56
57
58
59 // a helper type-trait that leverage SFINAE to figure out if type T has
60 // void T::set_local_element(const uint, const typename T::value_type)
61 template <typename T>
62 using set_local_element_t =
63 decltype(std::declval<T>().set_local_element(0, typename T::value_type()));
64
65 template <typename T>
66 constexpr bool has_set_local_element =
67 is_supported_operation<set_local_element_t, T>;
68
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 trait for vector T and Number to see if
108 // we can do vectorized load/save.
109 // for VectorReader and VectorDistributorLocalToGlobal we assume that
110 // if both begin() and local_element()
111 // exist, then begin() + offset == local_element(offset)
112 template <typename T, typename Number>
113 struct is_vectorizable
114 {
115 static const bool value =
116 has_begin<T> &&
117 (has_local_element<T> ||
119 std::is_same_v<typename T::value_type, Number>;
120 };
121
122 // We need to have a separate declaration for static const members
123 template <typename T, typename Number>
124 const bool is_vectorizable<T, Number>::value;
125
126
127 //
128 // type-traits for Matrix-Free
129 //
130 // similar to type traits in FEEvaluation, below we add type-traits
131 // to distinguish between vectors that provide different interface for
132 // operations like update_ghost_values(), compress(), etc.
133 // see internal::has_local_element in fe_evaluation.h that documents
134 // how those type traits work.
135
136 // a helper type-trait that leverage SFINAE to figure out if type T has
137 // void T::update_ghost_values_start(const uint) const
138 template <typename T>
139 using update_ghost_values_start_t =
140 decltype(std::declval<const T>().update_ghost_values_start(0));
141
142 template <typename T>
143 constexpr bool has_update_ghost_values_start =
144 is_supported_operation<update_ghost_values_start_t, T>;
145
146
147
148 // a helper type-trait that leverage SFINAE to figure out if type T has
149 // void T:: compress_start(const uint, VectorOperation::values)
150 template <typename T>
151 using compress_start_t =
152 decltype(std::declval<T>().compress_start(0, VectorOperation::add));
153
154 template <typename T>
155 constexpr bool has_compress_start =
156 is_supported_operation<compress_start_t, T>;
157
158
159
160 // type trait for vector T to see if
161 // we do a custom data exchange route.
162 // We assume that if both begin() and local_element()
163 // exist, then begin() + offset == local_element(offset)
164 template <typename T>
165 constexpr bool has_exchange_on_subset =
166 has_begin<T> && has_local_element<T> && has_partitioners_are_compatible<T>;
167
168
169
170 // a helper type-trait that leverage SFINAE to figure out if type T has
171 // T::communication_block_size
172 template <typename T>
173 using communication_block_size_t = decltype(T::communication_block_size);
174
175 template <typename T>
176 constexpr bool has_communication_block_size =
177 is_supported_operation<communication_block_size_t, T>;
178
179
180
181 // type trait for vector T to see if
182 // we need to do any data exchange for this vector type at all.
183 // is_serial_vector<> would have been enough, but in some circumstances
184 // (like calculation of diagonals for matrix-free operators)
185 // a dummy InVector == unsigned int is provided.
186 // Thus we have to treat this case as well.
187 template <class T, class IsSerialVectorNotSpecialized = void>
188 using not_parallel_vector_t = std::bool_constant<is_serial_vector<T>::value>;
189
195 template <typename VectorType>
196 using is_vector_type = decltype(is_serial_vector<VectorType>::value);
197
202 template <typename VectorType>
203 using is_serial_vector_type =
204 decltype(std::enable_if_t<is_serial_vector<VectorType>::value, int>());
205
211 template <typename VectorType>
212 constexpr bool is_not_parallel_vector =
213 (is_supported_operation<is_vector_type, VectorType> == false) ||
214 (is_supported_operation<is_serial_vector_type, VectorType> == true);
215} // namespace internal
216#endif
217
219
220#endif
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:502
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:503