From: Wolfgang Bangerth Date: Sat, 13 Jan 2024 04:46:31 +0000 (-0700) Subject: Use if-constexpr more in Tensor. X-Git-Tag: relicensing~163^2~1 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1b55d98d5cd7d6025bcb7c5d68dcb46a706654e0;p=dealii.git Use if-constexpr more in Tensor. --- diff --git a/include/deal.II/base/tensor.h b/include/deal.II/base/tensor.h index 54a3cbce01..c375d0c5a8 100644 --- a/include/deal.II/base/tensor.h +++ b/include/deal.II/base/tensor.h @@ -1406,34 +1406,6 @@ Tensor::Tensor(Tensor &&other) noexcept } # endif -namespace internal -{ - namespace TensorSubscriptor - { - template - constexpr DEAL_II_HOST_DEVICE_ALWAYS_INLINE ArrayElementType & - subscript(ArrayElementType *values, - const unsigned int i, - std::integral_constant) - { - AssertIndexRange(i, dim); - return values[i]; - } - - template - constexpr DEAL_II_HOST_DEVICE_ALWAYS_INLINE ArrayElementType & - subscript(ArrayElementType *dummy, - const unsigned int, - std::integral_constant) - { - Assert( - false, - ExcMessage( - "Cannot access elements of an object of type Tensor.")); - return *dummy; - } - } // namespace TensorSubscriptor -} // namespace internal template @@ -1441,8 +1413,11 @@ constexpr DEAL_II_HOST_DEVICE_ALWAYS_INLINE typename Tensor::value_type & Tensor::operator[](const unsigned int i) { - return dealii::internal::TensorSubscriptor::subscript( - values, i, std::integral_constant()); + Assert(dim != 0, + ExcMessage("Cannot access an object of type Tensor")); + AssertIndexRange(i, dim); + + return values[i]; } @@ -1451,6 +1426,8 @@ constexpr DEAL_II_ALWAYS_INLINE DEAL_II_HOST_DEVICE const typename Tensor::value_type & Tensor::operator[](const unsigned int i) const { + Assert(dim != 0, + ExcMessage("Cannot access an object of type Tensor")); AssertIndexRange(i, dim); return values[i]; @@ -1646,58 +1623,30 @@ constexpr inline DEAL_II_ALWAYS_INLINE } -namespace internal + +template +template +constexpr inline DEAL_II_ALWAYS_INLINE + DEAL_II_HOST_DEVICE Tensor & + Tensor::operator/=(const OtherNumber &s) { - namespace TensorImplementation - { - template ::type>::value && - !std::is_same_v, - int> = 0> - constexpr DEAL_II_HOST_DEVICE inline DEAL_II_ALWAYS_INLINE void - division_operator(Tensor (&t)[dim], - const OtherNumber &factor) + if constexpr (std::is_integral< + typename ProductType::type>::value || + std::is_same_v) { - const Number inverse_factor = Number(1.) / factor; // recurse over the base objects for (unsigned int d = 0; d < dim; ++d) - t[d] *= inverse_factor; + values[d] /= s; } - - - template ::type>::value || - std::is_same_v, - int> = 0> - constexpr DEAL_II_HOST_DEVICE inline DEAL_II_ALWAYS_INLINE void - division_operator(Tensor (&t)[dim], - const OtherNumber &factor) + else { - // recurse over the base objects + // If we can, avoid division by multiplying by the inverse of the given + // factor: + const Number inverse_factor = Number(1.) / s; for (unsigned int d = 0; d < dim; ++d) - t[d] /= factor; + values[d] *= inverse_factor; } - } // namespace TensorImplementation -} // namespace internal - -template -template -constexpr inline DEAL_II_ALWAYS_INLINE - DEAL_II_HOST_DEVICE Tensor & - Tensor::operator/=(const OtherNumber &s) -{ - internal::TensorImplementation::division_operator(values, s); return *this; } @@ -1749,12 +1698,30 @@ constexpr DEAL_II_HOST_DEVICE_ALWAYS_INLINE typename numbers::NumberTraits::real_type Tensor::norm_square() const { - typename numbers::NumberTraits::real_type s = internal::NumberType< - typename numbers::NumberTraits::real_type>::value(0.0); - for (unsigned int i = 0; i < dim; ++i) - s += values[i].norm_square(); + if constexpr (rank_ == 1) + { + // For rank-1 tensors, the square of the norm is simply the sum of + // squares of the elements: + typename numbers::NumberTraits::real_type s = + internal::NumberType< + typename numbers::NumberTraits::real_type>::value(0.0); + for (unsigned int i = 0; i < dim; ++i) + s += numbers::NumberTraits::abs_square(values[i]); - return s; + return s; + } + else + { + // For higher-rank tensors, the square of the norm is the sum + // of squares of sub-tensors + typename numbers::NumberTraits::real_type s = + internal::NumberType< + typename numbers::NumberTraits::real_type>::value(0.0); + for (unsigned int i = 0; i < dim; ++i) + s += values[i].norm_square(); + + return s; + } }