DEAL_II_NAMESPACE_OPEN
#ifndef DOXYGEN
+
namespace internal
{
//
// type traits for FEEvaluation
//
- // a helper type-trait that leverage SFINAE to figure out if type T has
+ // a helper type-trait leveraging SFINAE to figure out if type T has
// ... T::local_element() const
template <typename T>
using local_element_t = decltype(std::declval<const T>().local_element(0));
- // a helper type-trait that leverage SFINAE to figure out if type T has
+ // a helper type-trait leveraging SFINAE to figure out if type T has
// void T::add_local_element(const uint, const typename T::value_type)
template <typename T>
using add_local_element_t =
- // a helper type-trait that leverage SFINAE to figure out if type T has
+ // a helper type-trait leveraging SFINAE to figure out if type T has
// void T::set_local_element(const uint, const typename T::value_type)
template <typename T>
using set_local_element_t =
is_supported_operation<set_local_element_t, T>;
-
// same as above to check
// bool T::partitioners_are_compatible(const Utilities::MPI::Partitioner &)
// const
is_supported_operation<shared_vector_data_t, T>;
-
- // type trait for vector T and Number to see if
- // we can do vectorized load/save.
- // for VectorReader and VectorDistributorLocalToGlobal we assume that
- // if both begin() and local_element()
- // exist, then begin() + offset == local_element(offset)
- template <typename T, typename Number>
- struct is_vectorizable
- {
- static const bool value =
- has_begin<T> &&
- (has_local_element<T> ||
- is_serial_vector<std::remove_const_t<T>>::value) &&
- std::is_same_v<typename T::value_type, Number>;
- };
-
- // We need to have a separate declaration for static const members
- template <typename T, typename Number>
- const bool is_vectorizable<T, Number>::value;
-
-
//
// type-traits for Matrix-Free
//
constexpr bool has_communication_block_size =
is_supported_operation<communication_block_size_t, T>;
-
-
- // type trait for vector T to see if
- // we need to do any data exchange for this vector type at all.
- // is_serial_vector<> would have been enough, but in some circumstances
- // (like calculation of diagonals for matrix-free operators)
- // a dummy InVector == unsigned int is provided.
- // Thus we have to treat this case as well.
- template <class T, class IsSerialVectorNotSpecialized = void>
- using not_parallel_vector_t = std::bool_constant<is_serial_vector<T>::value>;
-
/**
* A predicate stating whether something is a vector type. We test this
* by seeing whether the `is_serial_vector` type is declared for the
constexpr bool is_not_parallel_vector =
(is_supported_operation<is_vector_type, VectorType> == false) ||
(is_supported_operation<is_serial_vector_type, VectorType> == true);
+
+
+
+ /**
+ * A type trait for vector T indicating serial vectors with access through
+ * operator[], which are the deal.II serial vectors and ArrayView<Number>
+ */
+ template <typename VectorType>
+ struct is_serial_vector_or_array
+ {
+ static const bool value =
+ is_supported_operation<is_serial_vector_type, VectorType>;
+ };
+
+ /**
+ * A type trait for vector T indicating serial vectors with access through
+ * operator[], which are the deal.II serial vectors and ArrayView<Number>
+ */
+ template <typename Number>
+ struct is_serial_vector_or_array<dealii::ArrayView<Number>>
+ {
+ static const bool value = true;
+ };
+
+ // We need to have a separate declaration for static const members
+ template <typename VectorType>
+ const bool is_serial_vector_or_array<VectorType>::value;
+
+
+
+ // type trait for vector T and Number to see if
+ // we can do vectorized load/save.
+ // for VectorReader and VectorDistributorLocalToGlobal we assume that
+ // if both begin() and local_element()
+ // exist, then begin() + offset == local_element(offset)
+ template <typename T, typename Number>
+ struct is_vectorizable
+ {
+ static const bool value =
+ has_begin<T> &&
+ (has_local_element<T> || is_serial_vector_or_array<T>::value) &&
+ std::is_same_v<typename T::value_type, Number>;
+ };
+
+ // We need to have a separate declaration for static const members
+ template <typename T, typename Number>
+ const bool is_vectorizable<T, Number>::value;
+
} // namespace internal
#endif
{
// below we use type-traits from matrix-free/type_traits.h
- // access to generic const vectors that have operator ().
- // FIXME: this is wrong for Trilinos/PETSc MPI vectors
- // where we should first do Partitioner::local_to_global()
- template <
- typename VectorType,
- std::enable_if_t<!has_local_element<VectorType>, VectorType> * = nullptr>
+
+
+ // access to serial const vectors that have operator[].
+ template <typename VectorType,
+ std::enable_if_t<is_serial_vector_or_array<VectorType>::value,
+ VectorType> * = nullptr>
inline typename VectorType::value_type
vector_access(const VectorType &vec, const unsigned int entry)
{
- return vec(entry);
+ return vec[entry];
}
- // access to generic non-const vectors that have operator ().
- // FIXME: this is wrong for Trilinos/PETSc MPI vectors
- // where we should first do Partitioner::local_to_global()
- template <
- typename VectorType,
- std::enable_if_t<!has_local_element<VectorType>, VectorType> * = nullptr>
+ // access to serial non-const vectors that have operator[].
+ template <typename VectorType,
+ std::enable_if_t<is_serial_vector_or_array<VectorType>::value,
+ VectorType> * = nullptr>
inline typename VectorType::value_type &
vector_access(VectorType &vec, const unsigned int entry)
{
- return vec(entry);
+ return vec[entry];
}
const types::global_dof_index entry,
const typename VectorType::value_type &val)
{
- vec(entry) += val;
+ vec[entry] += val;
}
const VectorType &vec,
Number &res) const
{
- res = vec(index);
+ res = vec[index];
}
VectorType &vec,
Number &res) const
{
- vec(index) = res;
+ vec[index] = res;
}