]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Fix type confusion in Tensor initialization.
authorWolfgang Bangerth <bangerth@colostate.edu>
Tue, 23 Jan 2024 15:47:14 +0000 (08:47 -0700)
committerWolfgang Bangerth <bangerth@colostate.edu>
Wed, 24 Jan 2024 01:42:58 +0000 (18:42 -0700)
include/deal.II/base/tensor.h

index bc75a71ab0e4b5f626cc1d68e122e8f3033d217d..85a07e8e18f2860d83307e2d62634b3c49e124ed 100644 (file)
@@ -1313,7 +1313,27 @@ template <typename ArrayLike, std::size_t... indices>
 constexpr DEAL_II_HOST_DEVICE_ALWAYS_INLINE
 Tensor<rank_, dim, Number>::Tensor(const ArrayLike &initializer,
                                    std::index_sequence<indices...>)
-  : values{{value_type(initializer[indices])...}}
+  // Extract from the 'initializer' a sequence of elements via template
+  // pack evaluation. This could be as easy as
+  //     values{{ (initializer[indices])... }}
+  // but of course in practice it is not. The challenge is that if rank>1,
+  // we want to pass the elements initializer[indices] down to the next
+  // lower rank tensor for evaluation unchanged. But at the rank==1 level,
+  // we need to convert to the scalar type 'Number'. This would all be
+  // relatively straightforward if we could rely on automatic type
+  // conversion, but for some autodifferentiation types, the conversion
+  // from the AD to double (i.e., the extraction of a scalar value) is
+  // not implicit, and we need to call internal::NumberType<Number>::value() --
+  // but as mentioned, we can only do that for rank==1.
+  //
+  // We can achieve all of this by dispatching to a lambda function within
+  // which we can use a 'if constexpr'.
+  : values{{([&initializer]() -> value_type {
+    if constexpr (rank_ == 1)
+      return internal::NumberType<Number>::value(initializer[indices]);
+    else
+      return value_type(initializer[indices]);
+  }())...}}
 {
   static_assert(sizeof...(indices) == dim,
                 "dim should match the number of indices");

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.