]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Use std::abs() when computing the norm of a tensor of size 1. 16458/head
authorWolfgang Bangerth <bangerth@colostate.edu>
Wed, 10 Jan 2024 23:07:41 +0000 (16:07 -0700)
committerWolfgang Bangerth <bangerth@colostate.edu>
Thu, 11 Jan 2024 23:05:51 +0000 (16:05 -0700)
include/deal.II/base/tensor.h

index 56eaa02ef572c367d22dab0a22cef7c6499f2ad5..49bbcc5a25838aeaf6a758a4bbe10b2525eb856f 100644 (file)
@@ -1720,9 +1720,27 @@ template <int rank_, int dim, typename Number>
 inline DEAL_II_HOST_DEVICE typename numbers::NumberTraits<Number>::real_type
 Tensor<rank_, dim, Number>::norm() const
 {
-  // Make things work with AD types
-  using std::sqrt;
-  return sqrt(norm_square());
+  // Handle cases of a tensor consisting of just one number more
+  // efficiently:
+  if constexpr ((rank_ == 1) && (dim == 1) && std::is_arithmetic_v<Number>)
+    {
+      return std::abs(values[0]);
+    }
+  else if constexpr ((rank_ == 2) && (dim == 1) && std::is_arithmetic_v<Number>)
+    {
+      return std::abs(values[0][0]);
+    }
+  else
+    {
+      // Otherwise fall back to the naive algorithm of taking the square root of
+      // the sum of squares.
+
+      // Make things work with AD types by letting the compiler look up
+      // the symbol sqrt in namespace std and in the type-associated
+      // namespaces
+      using std::sqrt;
+      return sqrt(norm_square());
+    }
 }
 
 

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.